效果展示
写代码之前首先我们要明白什么是三子棋?三子棋的图形是什么?三子棋的本质是什么?这些问题。
三子棋图像
#define ROW 3//定义行数
#define COL 3//定义列数
void intiborad(char board[ROW][COL], int row, int col);//初始化棋盘的二维数组
void Display_Board(char board[ROW][COL], int row, int col);//打印棋盘
void PlayerMove(char board[ROW][COL], int row, int col);//玩家移动
void ComputerMove(char board[ROW][COL], int row, int col);//电脑移动
char Iswin(char board[ROW][COL], int row, int col);//判断输赢
三子棋本质就是二维数组,
- 我们应该首先建立一个二维数组,开辟一个二维数组的空间,然后对这个二维数组进行初始化,方便之后我们之后赋值,这样就建立了一个三子棋的框架。
void intiborad(char board[ROW][COL], int row, int col) { int i = 0; for (i = 0; i < row; i++) { int j = 0; for (j = 0; j < col; j++) { board[i][j] = ' ';//赋空值,为之后下棋,落子做准备。 } } }
- 然后我们便就可以打印棋盘,我们就要晓得棋盘的构造
用---|---|--- //来做出棋盘的下划线
用 | | //来做棋盘的分割线
void Display_Board(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
//打印数据
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
printf(" %c ", board[i][j]);//打印下划线
if (j < col - 1)//最后一个|不用打印,只需打印两个就行了
printf("|");//效果就是: | |
}
printf("\n");
//打印分割线
if (i < row - 1)//只需打印两个下划线
{
j = 0;
for (j = 0; j < col; j++)
{
printf("---");
if (j < col - 1)//最后一个|不用打印,只需打印两个就行了
{
printf("|");//效果就是---|---|---
}
}
printf("\n");
}
}
}
3.玩家输入
因为玩家不都是程序员,不知道是二维数组从0开始排列的,所以我们可以让玩家,直接从1开始。
我们输入一个坐标,先判断那个位置有没有被占,或者那个位置是不是存在的。判断完成后我们才可以下子。然后直接插入进去,进行赋值。
用*来表示玩家输入,用#来表示电脑输入
void PlayerMove(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
printf("玩家下棋\n");
printf("输入你的坐标>,用空格隔开");
while (1)
{
scanf("%d %d", &x, &y);
if (x > 0 && x <= row && y > 0 && y <= col)//先判断位置是否是合法的
{
if (board[x-1][y-1] == ' ')//后判断位置是否为空的
{
board[x-1][y-1] = '*';//最后在插入
printf("成功\n");
break;
}
else
{
printf("此位置被占用,请重新选择 。\n");
}
}
else
{
printf("这位置不对,请重新选择\n");
}
}
}
4.电脑下棋
电脑下棋也是同样的道理,我们应该也要判断位置的合法性,电脑下棋的本质就是随机下棋。随机下棋就要用到随机种子,也就是时间戳,进行随机去插入一个值。
void ComputerMove(char board[ROW][COL], int row, int col)
{
printf("电脑输入\n");
int x;
int y;
while (1)
{
x = rand() % row;//取模让每次取得行列是合法的
y = rand() % col;
if (board[x][y] == ' ')
{
board[x][y] = '#';
printf("成功\n");
break;
}
}
}
5.判断输赢
判断输赢第一步就是先判断棋盘内是否有连成三个的,
该结果就有三个:玩家赢,电脑赢,平局
int Isfull(char board[ROW][COL], int row, int col)//判断是否满了
{
int i = 0, j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if (board[i][j] == ' ')
{
return 0;//遍历完还有空的,则表示还没满
}
}
}
return 1;//满了,返回1
}
char Iswin(char board[ROW][COL], int row, int col)
{
int i = 0;
for (i = 0; i < row; i++)//遍历判断是否连成三个
{
if (board[i][0] == board[i][1] && board[i][1] == board[i][2]&& board[i][2]!=' ')
{
return board[i][2];//返回连成的元素
}
if (board[0][i] == board[1][i] && board[1][i] == board[2][i]&& board[1][i] != ' ')
{
return board[1][i];
}
if (board[0][0] == board[1][1] && board[1][1] == board[2][2]&& board[2][1] != ' ')
return board[1][1];
if (board[1][3] == board[2][2] && board[2][2] == board[3][1]&& board[2][2] != ' ')
return board[2][2];
}
if (Isfull(board, ROW, COL) == 1)//如果棋盘满了,还没有判断出输赢。
return 'Q';//返回一个值来表示平局
return 'C';//没有输赢
}
END
游戏界面设计
void menu()
{
printf("*************************\n");
printf("******1. play ***********\n");
printf("******0. exit ***********\n");
printf("*************************\n");
}
void game()
{
char board[ROW][COL];//创建一个二维数组
intiborad(board, ROW, COL);//初始化二维数组
Display_Board(board, ROW, COL);
char ret;
while (1)
{
PlayerMove(board, ROW, COL);//玩家输入
Display_Board(board, ROW, COL);
ret=Iswin(board, ROW, COL);//每运行一次判断是否赢了,用返回值判断
if (ret != 'C')//C表示继续
break;
ComputerMove(board, ROW, COL);
Display_Board(board, ROW, COL);
if (ret != 'C')
break;
}
//ret接受返回值
if (ret == '*')//返回一个*
{
printf("恭喜你赢了!!!!\n");
}
if (ret == '#')//返回一个#
{
printf("对不起你输了\n");
}
if (ret == 'Q')//返回一个Q
{
printf("平局\n");
}
}
int main()
{
srand((unsigned int)time(NULL));
int input = 0;
do
{
menu();
printf("输入你的选择\n");
scanf("%d", &input);
switch (input)
{
case 1:
printf("进入游戏\n");
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("输入有错,重新输入\n");
}
} while (input);
return 0;
}
源码:三字棋 · 胡小威/C语言项目 - 码云 - 开源中国 (gitee.com)
不足地方望大佬指教。