目录
前言
三子棋是我们生活中进行的两人游戏。棋盘有九个位置,采用回合制,只要一方先下够三个连续的棋子就算赢。是一种比较简单的小游戏。接下来,我们就尝试一下用c语言简单滴实现这个游戏的逻辑。
一、游戏的基本流程
用代码写三子棋首先要将这个游戏拆分成许多具体的模块,再分别用代码实现。
我们可以将三子棋小游戏拆分成以下几个模块:
1. 打印菜单,玩家选择
在玩家进入游戏之前需要有菜单提供玩家一些选项,用来确定玩家是否要进行游戏。因此,在每次游戏开始之前和结束之后都要出现这个菜单。
2.游戏开始
进入游戏后的整个过程,可以进一步拆分为以下几个模块:
(搁着套娃呢 )
(1)初始化棋盘
在正式开始下棋之前,我们需要一个棋盘,上面没放任何东西。棋盘上的行和列对应的位置,恰好可以用二维数组很好地表示出来。
(2)打印棋盘
想要让初始化后的棋盘让玩家看到,就需要将棋盘打印出来。但是不能只打印初始化的数组,还需要用线条修饰让它看着是棋盘。另外,这个过程在后面下棋过程中需要反复使用,需要具备一定的兼容性,以方便地展示不一样的棋盘。
(3)玩家下棋
玩家下棋时是有自己的意识的,这时就需要让玩家输入,电脑接收以实现下棋的效果。此外,已经下过棋或没有在棋盘上的坐标不能下棋,但玩家可能不知道,因此需要提醒。而且,一般情况下人想的坐标是比数组下标多 1 的,别忘了减去哦。
(4)电脑下棋
我们现在只是学习三子棋的基本逻辑,可以让电脑下棋位置随机(当然,如果大佬能让电脑更牛,可以写出来让俺见识一下嘿嘿)。这个随机数可以用rand与srand来实现,注意只需取随机数除以三的余数即可得到数组的下标。
(5)判断输赢
每次电脑下完棋或者玩家下完棋都需要判断一次输赢。如果玩家的棋子先连起来,就是玩家赢。反之,则电脑赢。但是不要忘记了,这种游戏还有可能出现平局。如果棋盘满了且没有任何一方胜利,就判为平局。如果以上情况都没发生,就继续游戏。
好了,基本流程已经梳理完毕,接下来开始用代码实现吧!
二、代码实操
1.创建文件,引用头文件
这里我们为了更好地展示,将头文件一次全部展示,但其实在实操过程中可以边写边引用。
首先我们要创建两个 .c 文件,一个 .h 文件,前者用来写函数,后者用来写声明。如下:
2. 编写主函数和主要函数
我们将主函数和主要函数写入文件test.c文件中,主要流程如下:
(1)主函数
如下:
int main()
{
test();
return 0;
}
(2)主函数中的test函数和菜单函数
对应前面的“打印菜单,玩家选择”部分
void menu()
{
printf("***************************\n");
printf("**** 1. play 0. exit*****\n");
printf("***************************\n");
}
void test()
{
int input = 0;
srand((unsigned int)time(NULL));
do
{
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("选择错误,请重新选择!\n");
break;
}
} while (input);
}
(3)游戏主要框架
对应前面的“游戏开始”部分
//游戏的整个算法实现
void game()
{
char ret = 0;
//数组-存放走出的棋盘信息
char board[ROW][COL] = {0};//全部空格
//初始化棋盘
InitBoard(board, ROW, COL);
//打印棋盘
DisplayBoard(board, ROW, COL);
//下棋
while (1)
{
//玩家下棋
PlayerMove(board, ROW, COL);
DisplayBoard(board, ROW, COL);
//判断玩家是否赢
ret = IsWin(board, ROW, COL);
if (ret != 'C')
{
break;
}
//电脑下棋
ComputerMove(board, ROW, COL);
DisplayBoard(board, ROW, COL);
//判断电脑是否赢
ret = IsWin(board, ROW, COL);
if (ret != 'C')
{
break;
}
}
if (ret == '*')
{
printf("玩家赢\n");
}
else if (ret == '#')
{
printf("电脑赢\n");
}
else
{
printf("平局\n");
}
}
这里将判断输赢的函数返回值设置为“*”、“#”、“C”、“Q”可以使我们在后面写该函数更加方便。
3.各分支代码的实现
我们将各分支代码写入文件game.c文件中,主要流程如下:
(1)初始化棋盘
对应前面的“初始化棋盘”部分
void InitBoard(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++)
{
board[i][j] = ' ';
}
}
}
(2)打印棋盘
对应前面的“打印棋盘”部分
void DisplayBoard(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++)
{
//1. 打印一行棋盘位置的字符
printf(" %c ", board[i][j]);
if (j < col - 1)
printf("|");
}
printf("\n");
//2. 打印分割线
if (i < row - 1)
{
for (j = 0; j < col; j++)
{
printf("---");
if (j<col-1)
printf("|");
}
printf("\n");
}
}
}
(3)玩家下棋
对应前面的“玩家下棋”部分
void PlayerMove(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
printf("玩家走:>\n");
while (1)
{
printf("请输入要下的坐标:>");
scanf("%d%d", &x, &y);
//要判断x,y坐标的合法性
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (board[x - 1][y - 1] == ' ')
{
board[x - 1][y - 1] = '*';
break;
}
else
{
printf("这里下过啦\n");
}
}
else
{
printf("没下到棋盘上!\n");
}
}
}
(4)电脑下棋
对应前面的“电脑下棋”部分
void ComputerMove(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
printf("电脑走:>\n");
while (1)
{
x = rand() % row;
y = rand() % col;
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
(5)判断输赢
对应前面的“判断输赢”部分
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][1] != ' ')
{
return board[i][1];
}
}
//判断竖着的
for (i = 0; i < col; i++)
{
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[1][1] != ' ')
return board[1][1];
if (board[2][0] == board[1][1] && board[1][1] == board[0][2] && board[1][1] != ' ')
return board[1][1];
//判断是否平局
if (1 == IsFull(board, ROW, COL))
{
return 'Q';
}
//继续
return 'C';
}
这里要判断棋盘是否满了,所以要额外写一个判断棋盘是否下满的函数。也可以直接写,但是使用if语句时不太方便。这里专门用一个新函数来写。
int IsFull(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++)
{
if (board[i][j] == ' ')
{
return 0;//没满
}
}
}
return 1;//满了
}
注意在函数的过程中或者写完之后,记得在 .h 文件中声明哦!
到此为止,我们的三子棋代码就全部写完了,让我们来看看效果吧!
三、运行效果
是不是很好玩呀!不知道你能不能连续三次和电脑平局呢?快去试试吧!