满满的童年——C语言之井字棋(三子棋)
- 一.游戏介绍及规则
- 二.游戏步骤
- 三.游戏功能
- 1. 初始化数组
- 2. 打印井字图
- 3. 玩家下棋
- 4. 电脑下棋
- 5. 判断棋盘是否已满
- 6. 判断输赢
- 7.实现人机模式
- 8.人人对抗模式
一.游戏介绍及规则
相信很多小伙伴在学生时代都玩过井字棋(三子棋),在课余时间在自己的草稿纸上画着井字图,然后找同学一起玩,今天,博主就用C语言带大家回忆童年的乐趣。
游戏规则:
如图,在井字图中,横行、竖行或者对角线三子相同则游戏胜利,若棋盘下满时仍未分出胜负则平局。
注:先介绍程序实现的主要功能,后文会有完整代码
二.游戏步骤
- 程序开始执行时玩家需要选择是否开始游戏,输入1则游戏开始,输入0则退出游戏。
- 当玩家选择开始游戏时,将会进入模式选择,输入1则为人机模式——玩家与电脑对战,输入2则为人人模式,玩家可以于自己的朋友开始游戏。
- 玩家选择完游戏模式之后,将会打印出井字图,玩家通过输入坐标位置选择下棋的位置,电脑则自动下棋。
- 当出现三子相连时,游戏结束,此时三子相连方胜利,若无三子相连且棋盘已满则为平局。
三.游戏功能
1. 初始化数组
创建二维数组board[ROW][COL],初始化为空,以便打印井字图时为空白。
//初始化数组
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. 打印井字图
井字图中用符号‘|’作为列的分隔符,符号‘—’作为行的分隔符,每一个小格子中左右分别一个空格,中间为二维数组board的元素。
//打印棋盘
void DisplayBoard(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)
{
for (j = 0; j < COL; j++)
{
printf("---");
if (j < COL - 1)
printf("|");
}
}
printf("\n");
}
}
3. 玩家下棋
玩家通过输入具体位置的坐标进行下棋,若输入坐标小于等于零或者大于数组board的行号或列号,则坐标不合法;若此时想下棋位置原先已有棋则需要重新选择下棋的位置。
void Player1(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
while (1)
{
printf("玩家1请输入下棋的位置:>\n");
scanf("%d%d", &i, &j);
//判断坐标是否合法
if (i > 0 && i <= row && j > 0 && j <= col)
{
//判断所选位置是否已有棋子
if (board[i - 1][j - 1] == ' ')
{
board[i - 1][j - 1] = '*';
break;
}
else
printf("该位置被占用,请重新选择\n");
}
else
printf("输入的坐标不合法重新输入\n");
}
}
4. 电脑下棋
通过生成随机数来确定下棋的位置
void Computer(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
printf("电脑下棋:>\n");
while (1)
{
//生成随机数
i = rand() % row;
j = rand() % col;
if (board[i][j] == ' ')
{
board[i][j] = '#';
break;
}
}
}
5. 判断棋盘是否已满
棋盘未满则返回0,已满则返回1
int is_full(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;//棋盘满了
}
6. 判断输赢
当出现某个字符三个相连时就返回该字符,棋盘满了返回字符‘Q’,若以上情况都未出现,则返回字符‘C’。
//判断输赢
char is_win(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
//判断行赢
for (i = 0; i < row; i++)
{
if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ')
{
return board[i][0];
break;
}
}
//判断列赢
for (j = 0; j < row;j++)
{
if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[0][j] != ' ')
{
return board[0][j];
break;
}
}
//判断对角线赢
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != ' ')
return board[0][0];
if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[2][0] != ' ')
return board[0][2];
if (is_full(board, ROW, COL) == 1)
return 'Q';
return 'C';
}
7.实现人机模式
//人机对抗
void Play_Computer(char board[ROW][COL], int row, int col)
{
char ret = 0;
while (1)
{
Player1(board, ROW, COL);
//每下一步棋则打印棋盘
DisplayBoard(board, ROW, COL);
ret = is_win(board, ROW, COL);
//若棋盘已满则跳出循环
if (ret != 'C')
{
break;
}
Computer(board, ROW, COL);
DisplayBoard(board, ROW, COL);
ret = is_win(board, ROW, COL);
if (ret != 'C')
{
break;
}
}
if (ret == '#')
printf("电脑赢\n");
else if (ret == '*')
printf("玩家赢\n");
else
printf("平局\n");
}
8.人人对抗模式
void Play_Play(char board[ROW][COL], int row, int col)
{
char ret = 0;
while (1)
{
Player1(board, ROW, COL);
DisplayBoard(board, ROW, COL);
ret = is_win(board, ROW, COL);
if (ret != 'C')
{
break;
}
Player2(board, ROW, COL);
DisplayBoard(board, ROW, COL);
ret = is_win(board, ROW, COL);
if (ret != 'C')
{
break;
}
}
if (ret == '+')
printf("玩家2赢\n");
else if (ret == '*')
printf("玩家1赢\n");
else
printf("平局\n");
}