目录
三子棋介绍
如何用C语言实现三子棋
游戏菜单的创建
游戏代码的实现
一、棋盘初始化
二、棋盘的打印
三、玩家下棋
四、电脑下棋
五、判断胜负
游戏部分代码实现
game.h文件中代码声明部分:
三子棋是一种民间传统游戏,又叫九宫棋、圈圈叉叉棋、一条龙、井字棋等。游戏分为双方对战,双方依次在9宫格棋盘上摆放棋子,率先将自己的三个棋子走成一条线就视为胜利,而对方就算输了,但是三子棋在很多时候会出现和棋的局面。
用C语言实现三子棋的步骤主要分成以下几步;
1、棋盘初始化
2、打印棋盘
3、下棋
4、判断输赢
在设计游戏前,我们首先需要创建3个文件来将代码模块化:
test.c----测试游戏
game.h----游戏代码中函数的声明
game.c----游戏的实现
在正式开始游戏前,我们需要先设置一个菜单函数引导玩家正确的开始游戏
此时我们设置函数menu( )来完成对玩家的引导。
在整个菜单的创建过程中,为了保证玩家可以连续进行多次游戏,我们可以运用do while循环的特性来编写代码的测试部分
menu 函数如下
void menu()
{
printf("***************************\n");
printf("欢迎你点开由xhhh113亲自写出来的游戏代码《三子棋》\n");
printf("三个子连在一起即为胜利\n");
printf("下棋时请输入你想将棋子放置的坐标(坐标格式为:行 列)\n");
printf("例如:如果想将棋子放置于左上角,则输入1 1并按回车键\n");
printf("******* 1.play ************\n");
printf("******* 0.exit ************\n");
printf("***************************\n");
}
test函数及主函数如下:
void test()
{
int input = 0;
srand((unsigned int)time(NULL));
printf("请选择\n");
do {
scanf_s("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("输入错误 请重新输入\n");
break;
}
} while (input);
}
int main()
{
menu();
test();
return 0;
}
注意!!!代码块中的srand((unsigned int)time(NULL));是利用时间戳来创造随机值,为后面编写电脑下棋的函数做铺垫
在游戏正式开始前,我们要对棋盘进行棋盘的初始化来确保游戏的正常进行,在这里,我们选择创建一个函数InitBoard来实现这一功能
棋盘初始化的代码如下:
void Initboard(char board[ROW][COL], int row, int col)//棋盘初始化
{
int i, j;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
board[i][j] = ' ';
}
}
}
在棋盘完成初始化后,我们需要将棋盘打印出来(注意:此时打印的棋盘中的每一格分别对应了二维数组的一个元素的值)
棋盘长这样:
我们可以将棋盘分成多个部分进行打印,将空格和横虚线看为一组,分为三组进行打印
(代码中使用ROW和COL是为了使代码更加灵活,当行、列发生改变时,棋盘也能相应的随之发生改变)
棋盘打印代码如下:
void Printboard(char board[ROW][COL], int row, int col)//打印棋盘
{
int i, j;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
printf(" %c ", board[i][j]);
if (j < col - 1)
printf("|");
}
printf("\n", board[i][j]);
if (i < row - 1)
{
for (j = 0; j < col; j++)
{
printf("---");
if (j < col - 1)
printf("|");
}
printf("\n");
}
}
}
在棋盘布置好后,玩家将输入坐标进行下棋,在玩家输入坐标后,我们首先要进行下列判断:
1、玩家输入的坐标均小于行、列
2、玩家输入的坐标对应棋盘中的位置应当未有棋子落下
注意!!!在C语言的编写过程中,数组下标以0开始,但是玩家在输入坐标时,对应的行、列均从1开始,因此我们在编写代码的过程中要注意数组元素下标和玩家输入坐标之间的差值
玩家下棋步骤的代码如下:
void PlayerMove(char board[ROW][COL],int row, int col)//玩家下棋
{
int input;
int i, j;
printf("玩家下棋\n");
while (1)
{
scanf_s("%d%d", &i, &j);
if (i <= row && i >= 1 && j <= col && j >= 1)//判断坐标是否合法
{
if (board[i - 1][j - 1] == ' ')//判断该坐标是否已有棋子落下
{
board[i - 1][j - 1] = '*';
break;
}
else
printf("改坐标已被占用 请重新输入\n");
}
else
{
printf("输入错误 请重新输入坐标\n");
}
}
}
在玩家下棋后,电脑应当进行下棋步骤
电脑下棋时,我们先利用随机值函数生成随机坐标,再先后判断坐标是否合法以及坐标是否已有棋子落下
那么如何进行坐标生成部分呢?
首先,我们可以先利用上文中提及过的函数 srand((unsigned int)time(NULL)); 来利用时间戳生成随机值(这里要注意一点,如果不使用时间戳,那么使用rand生产随机值时每次产生的随机值是固定一样的)
代码实现如下:
void ComputerMove(char board[ROW][COL], int row, int col)//电脑下棋
{
printf("电脑下棋\n");
int x = 0;//行
int y = 0;//列
while (1)
{
x = rand() % row;
y = rand() % col;
if (board[x][y] == ' ')//判断是否已有棋子落下
{
board[x][y] = '#';
break;
}
}
}
对于代码中x、y赋值的解释如下:
当x随机值过大时,我们计算x%row可以得到0-row-1之间的数字,此时可以当作二维数组下标来进行使用,该语句可以大大减少计算量
游戏在进行的过程中,可能随时有任意一方获得胜利,此时我们要创建一个函数来判断游戏是否结束
当游戏进行过程中,有下列四种情况:
1、玩家赢-----返回p
2、电脑赢-----返回m
3、平局(棋盘已满)-----返回o
4、游戏继续(尚未结束)-----返回c
对于平局的判断,我们需要另外再创建一个函数来判断棋盘是否已经满了,如果此时棋盘已满,且无任何一方胜出,那么结果为平局。
判断棋盘是否已满代码如下:
int IsFull(char board[ROW][COL], int row, int col)//判断棋盘是否满了
{
int i, j;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if (board[i][j] == ' ')
return 0;
}
}
return 1;
}
判断胜负的代码如下:
int Iswin(char board[ROW][COL], int row, int col)//判断输赢
{
int i, j;
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 (j = 0; j < row; j++)
{
if (board[j][0] == board[j][1] && board[j][1] == board[j][2] && board[j][1] != ' ')
return board[j][1];
}
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
return board[1][1];
else if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
return board[1][1];
else if (1 == IsFull(board, ROW, COL))
{
return 'o';
}
return 'c';
}
void game()
{
char board[ROW][COL] = { 0 };
int ret;
Initboard(board,ROW,COL);//初始化棋盘
Printboard(board,ROW,COL);//打印棋盘
while (1)
{
//玩家下棋
PlayerMove(board, ROW, COL);
Printboard(board, ROW, COL);
ret = Iswin(board, ROW, COL);
if (ret != 'c')
break;
// //电脑下棋
ComputerMove(board, ROW, COL);
Printboard(board, ROW, COL);
ret = Iswin(board, ROW, COL);
if (ret != 'c')
break;
}
//判断输赢
if (ret == '#')
printf("你输了\n");
else if (ret == '*')
printf("你赢了\n");
else if (ret == 'o')
printf("平局\n");
}
#include
#include
#include
#define ROW 3
#define COL 3
void Initboard(char board[ROW][COL], int row, int col);
void Printboard(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);
int Iswin(char board[ROW][COL], int row, int col);
int IsFull(char board[ROW][COL], int row, int col);