⭕️ 井字棋,又被称为三子棋。相信大家小时候都玩过这个游戏。童年的游戏,让我这个菜鸟动手用代码来实现一下,一起来寻找快乐吧! ❌
在文章的末尾有全部的代码!
- 1. ⭕️井字棋演示
- 2. ⭕️游戏代码实现
- 2.1 ❌ 游戏选择菜单
- 2.2 ❌ 游戏本体
- 2.2.1 游戏本体思路
- 2.2.2 各函数的实现
- InitiBoard(); 棋盘初始化函数
- DisplayBoard(); 棋盘打印函数
- PlayerMove(); 玩家落子函数
- ComputerMove(); 电脑落子函数
- IsWin(); 判断结束函数
- IsFull(); 判断平局函数 (棋盘是否已满)
- game(); 游戏本体函数
- 2.2.3 游戏的实现(所有代码)
1. ⭕️井字棋演示
先看一下代码实现井字棋后的界面演示吧 ⤵️
2. ⭕️游戏代码实现 2.1 ❌ 游戏选择菜单
我们的游戏菜单简洁明了⤵️
选 1, 开始游戏
选 0, 退出游戏
从我们的演示来看,选择游戏,一局游戏结束后,还可以继续选择。
我们可以选择循环来实现重复游玩。
int main() { int input = 0; do { //选择菜单 printf("*********************************n"); printf("******** 1. play ********n"); printf("******** 0. exit ********n"); printf("*********************************n"); printf("请选择序号:>"); scanf("%d", &input); } while(input); return 0; }
关于为什么do while循环的条件是我们输入的 input。
是因为我们想实现
输入 1 进行游戏,游戏完后还可以继续选择,可以进入下次循环继续选择;
输入 0 退出游戏,结束循环;
输入其他数字,就直接进入下一次循环,重新选择
所以循环的条件需要在我们输入 0 的时候为 假,在输入其他数字的时候为 真,直接用 input 的值可以直接判断
这样我们的菜单就会出现了,还可以进行选择⤵️
但是很明显仅仅一个菜单我们并不能进行游戏,所以我们还要实现一个游戏本体的代码。并且在选择 1 的时候,可以执行这些代码。
我们可以写一个 game() 函数来实现游戏的功能,并且使用 switch 语句来实现,选择 1 开始游戏
那么上面的代码就可以更新了⤵️
int main() { int input = 0; do { //选择菜单 printf("*********************************n"); printf("******** 1. play ********n"); printf("******** 0. exit ********n"); printf("*********************************n"); printf("请选择序号:>"); scanf("%d", &input); switch (input) { case 1: //游戏本体函数 game(); break; case 0: printf("退出成功!"); break; default: printf("选择错误,请重新选择!n"); break; } } while(input); return 0; }
现在我们就实现了游戏菜单和选择:
✅ 输入 1 , input == 1 开始游戏 , 游戏结束后再次进入循环 , 可重复游玩
✅ 输入 0 , input == 0 退出游戏 , 循环条件判断为 假 , 退出循环 , 程序结束
✅ 输入其他 , input != 0 && input != 1 选择错误 , 循环条件判断为 真 , 进入下次循环 , 重新选择
2.2 ❌ 游戏本体
上面的代码,我们实现了游戏菜单和选择,接下来我们需要用代码实现一下游戏的游玩内容!
那么 game() 函数到底需要有什么内容呢?
2.2.1 游戏本体思路 让我们先来捋一遍思路⤵️
首先,我们下棋需要一个棋盘,可用 char board[3][3]; 申请一个二维字符数组实现。
还需要将棋盘内容,初始化为 ' ' 。可以自定义一个函数 来初始化棋盘。可以命名为InitiBoard(); //棋盘初始化函数
之后我们需要将棋盘的内容,打印出来显示在屏幕上,具体长这样➡️ 同样可以自定义一个函数来实现。 可以命名为DisplayBoard(); //棋盘打印函数。
然后玩家就可以输入落子的坐标来和 ️笨笨的电脑️ 下棋了!所以这里我们需要自定义 3 个函数,来实现 玩家落子、电脑落子、判断输赢 这三个功能。
PlayerMove(); //玩家落子函数
ComputerMove(); //电脑落子函数
IsWin(); //判断结束函数
那么具体的逻辑就是 ⤵️
选择 1
打印空棋盘
输入坐标
判断游戏输赢(玩家赢、电脑赢、平局、未分输赢)
打印玩家和电脑落子后的棋盘
未分输赢则继续
已分输赢则重新菜单选择
逻辑捋清楚了,我们来逐个实现函数
2.2.2 各函数的实现 InitiBoard(); 棋盘初始化函数void InitiBoard(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] = ' '; } }//两重 for 循环实现二维数组初始化 }
DisplayBoard(); 棋盘打印函数
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) {//打印一行数组后 需要再打印一行 横分割线 int j = 0; for (j = 0; j < col; j++) { printf("---"); if (j < col - 1) printf("|"); } printf("n"); } } }
这个函数可以实现棋盘的打印,如果打印空棋盘结果就是 ➡️
PlayerMove(); 玩家落子函数
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); if (x >= 1 && x <= row && y >= 1 && y <= col) {//输入的坐标需要在棋盘内,即 1 <= x,y <= col(行 或 列) if (board[x-1][y-1] == ' ') //判断落子位置是否为空 { board[x-1][y-1] = '*'; break; } else printf("坐标占用,请重新输入!n"); } else //输入坐标不在棋盘内 printf("非法坐标,请重新输入!n"); } }
这个函数可以实现玩家输入坐标落子 ➡️
ComputerMove(); 电脑落子函数
void ComputerMove(char board[ROW][COL], int row, int col) {//电脑落子函数,传参:数组地址,棋盘行,棋盘列 printf("电脑走:>n"); while (1) { int x = rand() % row; //生成随机行坐标 int y = rand() % col; //生成随机列坐标 //rand() 函数可以生成一个随机数 对行或者列 求余就可以,生成一个合法(1 <= x,y <= row)的坐标 //rand() 函数使用前,需要用 srand() 函数通过 参数改变系统提供的种子值,从而可以使得每次调用rand函数生成的值随机 if (board[x][y] == ' ') //判断落子坐标是否为 空 { board[x][y] = '#'; break; } } }
IsWin(); 判断结束函数
//返回值为 '*' 玩家赢 //返回值为 '#' 电脑赢 //返回值为 'Q' 平局 //返回值为 'C' 游戏继续 char IsWin(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][1] != ' ') return board[i][1]; //返回数组内容,数组内容即为获胜者 } //判断 列有无连子 for (j = 0; j < col; j++) { if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[1][j] != ' ') return board[1][j]; //返回数组内容,数组内容即为获胜者 } //判断 对角线有无连子 if(board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ') return board[1][1]; if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ') return board[1][1]; int ret = IsFull(board, row, col); //判断 平局 // IsFull 返回值 为 1 棋盘满 平局 // 返回值 为 0 期盼未满 游戏继续 if (ret == 1) return 'Q'; //平局返回 Q return 'C'; //无胜方、无平局,返回C 游戏继续 }IsFull(); 判断平局函数 (棋盘是否已满)
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] == ' ') {//二重循环遍历判断数组是否有空,有则返回 0 return 0; break; } } } return 1; //无空,即棋盘以下满,则返回 1 }
game(); 游戏本体函数
void game() {//棋盘的行和列,可以设置全局符号常量 ROW 和 COL 以便后期更改 int j = 0; int i = 0; char ret; char board[ROW][COL]; //设置棋盘 //初始化 数组 InitiBoard(board, ROW, COL); //打印 棋盘 DisplayBoard(board, ROW, COL); while (1) {//循环落子、打印,直到分出胜负后 break; 结束循环 //玩家下棋 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"); DisplayBoard(board, ROW, COL); //打印分出输赢时候的 棋盘 printf("n"); }
至此,我们所需要自定义的所有函数就已经全部实现了;然后需要做的就是按照我们的逻辑合理运用函数来实现完整的游戏。
2.2.3 游戏的实现(所有代码) 按照我们已经分析过的逻辑
具体的逻辑 ⤵️
选择 1
打印空棋盘 或 退出 或 重新选择
输入坐标
判断游戏输赢(玩家赢、电脑赢、平局、未分输赢)
打印玩家和电脑落子后的棋盘
未分输赢则继续
已分输赢则重新菜单选择
按照逻辑将所有代码组合起来 ⤵️
#include#include #include #define ROW 3 //符号常量 行 == 3 #define COL 3 //符号常量 列 == 3 void InitiBoard(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] = ' '; } } } 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) { int j = 0; for (j = 0; j < col; j++) { printf("---"); if (j < col - 1) printf("|"); } printf("n"); } } } 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); 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"); } } void ComputerMove(char board[ROW][COL], int row, int col) { printf("电脑走:>n"); while (1) { int x = rand() % row; int y = rand() % col; if (board[x][y] == ' ') { board[x][y] = '#'; break; } } } 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; break; } } } return 1; } //返回值为 '*' 玩家赢 //返回值为 '#' 电脑赢 //返回值为 'Q' 平局 //返回值为 'C' 游戏继续 char IsWin(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][1] != ' ') return board[i][1]; } //判断 列 for (j = 0; j < col; j++) { if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[1][j] != ' ') return board[1][j]; } //判断 对角线 if(board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ') return board[1][1]; if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ') return board[1][1]; //判断 平局 // IsFull 返回值 为 1 棋盘满 平局 // 返回值 为 0 期盼未满 游戏继续 int ret = IsFull(board, row, col); if (ret == 1) return 'Q'; return 'C'; } void game() { int j = 0; int i = 0; char ret; char board[ROW][COL]; //初始化 数组 InitiBoard(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"); DisplayBoard(board, ROW, COL); printf("n"); } int main() { int input = 0; //随机值前的调用 srand((unsigned int)time(NULL)); do { mune(); printf("请选择序号:>"); scanf("%d", &input); switch (input) { case 1: //游戏本体函数 game(); break; case 0: printf("退出成功!"); break; default: printf("选择错误,请重新选择!n"); break; } } while(input); return 0; }
这就是 井字棋游戏 的所有代码了!
本篇博客到这里就结束了!
求点赞 关注 评论 收藏 ⭐️ 啊!!
求点赞 关注 评论 收藏 ⭐️ 啊!!
求点赞 关注 评论 收藏 ⭐️ 啊!!
这里是井字棋所有代码的网址(封装后的:头文件、函数文件、主函数文件)⤵️
https://github.com/DxytJuly3/problem-of-learning/tree/Learn-C/Study_Dayly/chess
https://gitee.com/xyt-g/problem-of-learning/tree/master/chess
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)