C++实现和电脑对战三子棋实例
作者:banbanbanni
前言
前两天在牛客网写了一道题,关于KiKi和BoBo玩 “井”字棋,请根据棋盘状态,判断当前输赢。也就是说系统给你一个已经下好的棋,让你来判断谁输谁赢还是平局。写完这道题也不禁让我有点想法,能不能写一个代码来实现我和电脑对峙三子棋,边下棋系统边判断是否输赢或者平局,否则继续下棋。经过一天查阅资料,观看视频,自己实践,终于实现了我当初的想法,现在来分享给大家我自己的思路。
一.准备需要的函数
1.棋盘
①构建
三子棋的棋盘肯定是必不可少,我们可以利用void函数来实现一个空的棋盘,让他为九宫格然后每一个格子都是空
void intiboard(char arr[ROW][COL], int row, int col)//初始化棋盘 { for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { arr[i][j] = ' '; } } }
②美化棋盘
棋盘肯定得有棋盘的样子,我们得美化一下键盘,我的思路是在横列上先打印'|'然后打印字符,在竖列上直接打印|---,然后循环。
void displayboard(char arr[ROW][COL], int row, int col)//打印棋盘 { for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { printf("|"); printf(" %c ", arr[i][j]); } printf("\n"); { for (int k = 0; k < col; k++) { printf("|---"); } printf("\n"); } } }
最后实现是这样的。
2.各自下棋
①玩家下棋
玩家这部分我们需要自己输入横竖坐标,但是实际上数组的是从0开始的,因此我们输入的时候应该给玩家输入的实际坐标减一,假如玩家输出超出范围或者输入的值被电脑抢先输入程序会反馈重新输入,这边使用while循环也成功实现了这一点,直到找到break才可以跳出这个循环。
void playermove(char arr[][COL], int row, int col)//玩家回合 { int x = 0; int y = 0; printf("玩家回合\n"); while (1)//一直循环直到break { printf("请输入你想要下的坐标\n"); scanf_s("%d %d", &x, &y); if (x >= 1 && x <= row && y >= 1 && y <= col)//输入合法 { if (arr[x-1][y-1] == ' ') { arr[x-1][y-1] = 'X'; break; } else printf("棋盘重复,重新输入\n"); } else printf("超出范围,请重新输入!\n"); } }
②电脑下棋
电脑这边有一个难点就在于如何让电脑随机输入数值,我是利用rand()来实现关于随机的范围我选择了除余来解决,让电脑输入有了随机性,同时也利用了while函数,只有输入了正确的位置才会跳出循环
void AImove(char arr[][COL], int row, int col)//电脑回合 { printf("AI回合\n"); while (1) { int x = rand() % row; int y = rand() % col; if (arr[x][y] == ' ') { arr[x][y] = 'O'; break; } } }
3.输赢判断
关于输赢我选择利用带有返回值的函数,方便日后判断。关于井字棋我们只要行、列,或者任意对角线上面出现三个连续相同的棋子,就能获胜。因此我们可以用if语句来判断是否满足以上任一条件如果满足则返回对于数值的字符,关于平局时在没有决出胜负的情况下棋盘下满,因此我们需要构建函数来判断棋盘是否满,不是则继续,是则暂停返回值。
int Full(char arr[][COL], int row, int col) { for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { if (arr[i][j] == ' ') return 0;//返回0说明棋盘没有满 } } return 1;//棋盘满了,平局 } char Winner(char arr[][COL], int row, int col)//判断输赢 { for (int i = 0; i < row; i++) { if (arr[i][0] == arr[i][1] && arr[i][1] == arr[i][2] && arr[i][0] != ' ') { return arr[i][0]; } else if (arr[0][i] == arr[1][i] && arr[1][i] == arr[2][i] && arr[0][i] != ' ') { return arr[0][i]; } if (arr[0][0] == arr[1][1] && arr[1][1] == arr[2][2] && arr[0][0] != ' ') { return arr[0][0]; } if (arr[0][2] == arr[1][1] && arr[1][1] == arr[2][0] && arr[1][1] != ' ') { return arr[1][1]; } } int x = Full; if (x == 0) { return 'Q'; } else return 'C'; }
因此我们准备的函数就准备完毕了。
二.游戏实现
1.菜单的实现
对于菜单没有什么说的直接就简单粗暴的打印就好
void menu() { printf("---------------------------------------\n"); printf("============1.开始 2.结束=============\n"); printf("+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=\n"); printf("----------------------------------------\n"); }//游戏的主页面;
然后菜单选项的实现我利用了do while函数来实现,用while来判断输入值的真假,假如是真的判断是否是一,要是一就开始游戏,否则提示输入超纲,重新循环,如果输入是零的话,while语句为假跳出循环,也就是结束游戏。
void test()//前端游戏页面和选择 { int input = 0; srand((unsigned int)time(NULL));//后面rand的使用 do { menu();//调用菜单的打印 printf("请输入你的选择(1/0):\n"); scanf_s("%d", &input); if (input == 1) { printf("三子棋游戏开始!\n"); play(); } else if (input == 0) { printf("结束游戏,感谢游玩\n"); } else printf("请你重新选择qaq\n"); } while (input);//假如input=0也就是input为假的时候结束循环: }
2.游戏本体的构建
关于游戏的逻辑,首先我们得构建一个数组来实现因此构建一个数组是必不可少的,然后利用函数对数组重置并且美化,然后实现玩家互相下棋然后显示棋盘,判断是否输赢或者平局,这里我们继续用了while循环来实现只有有了结果我们才会跳出循环
void play() { char board[ROW][COL]; char ret = 0; intiboard(board, ROW, COL); displayboard(board, ROW, COL); while (1) { playermove(board, ROW, COL); displayboard(board, ROW, COL); ret=Winner(board, ROW, COL); if (ret != 'C')//棋盘满了,或者决出胜负了! { break; } AImove(board, ROW, COL); displayboard(board, ROW, COL); ret = Winner(board, ROW, COL); if (ret != 'C')//棋盘满了,或者决出胜负了! { break; } } if (ret == 'X') { printf("玩家获胜!\n"); } else if (ret == 'O') { printf("电脑获胜!\n"); } else if(ret=='Q') printf("平局.\n"); }
就这样一个游戏就成功完成!
总结
这个游戏其实过于简单,因为三子棋判断输赢比较简单,也不麻烦,重点在于需要判断每一步是否输赢或者平局和对于while的理解,何时跳出循环,何时继续循环,而且要细心,就比如我在写的时候好多次把自己定义函数名字打错导致编译器错误找了好久才发现,还是得细心才行。
关于这个代码源码头文件什么的我都上传到gitee上去了如果感兴趣可以去看看
CSDN writings/三子棋 · banbanni/banni - 码云 - 开源中国 (gitee.com)
到此这篇关于C++实现和电脑对战三子棋实例的文章就介绍到这了,更多相关C++三子棋内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!