简单人机三子棋(C语言)

您所在的位置:网站首页 简单c语言程序编写 简单人机三子棋(C语言)

简单人机三子棋(C语言)

2023-03-13 04:23| 来源: 网络整理| 查看: 265

三子棋玩法

三子棋是一种民间传统游戏,游戏分为双方对战,双方依次在9宫格棋盘上摆放棋子,率先将自己的三个棋子走成一条连线就视为胜利

三子棋实现思路

本三子棋游戏主要构成部分分为游戏菜单界面,游戏执行。

为实现简单人机效果最基本首要的实现目标是让人机落子交替进行,为了简化游戏实现,本次代码采用人先行落子的单一情况,并且把人机交替落子一次设计成单次循环,简化程序,省去判断标志。

三子棋设计框架及其具体实现代码 主函数设计

我们利用选择对值进行赋予,对应值执行对应情况,这里由于情况单一,我们利用do-while进行执行

int main() { int input = 0; srand((unsigned int)time(NULL)); do { menu(); scanf("%d", &input); if (input == 1) { game(); } else break; } while (input); return 0; } 菜单界面

由于本游戏强制人类先行落子,因而菜单界面仅有开始游戏和结束游戏两项选择。

void menu()//菜单界面 { printf("三子棋\n"); printf("**********按一开始**********\n"); printf("**********按零结束**********\n"); printf("请输入\n"); } 棋盘初始化

由于在判断输赢和是否落子时需要对棋盘状况进行判断,因而设计一个数组进行记录情况,在这里我们把棋盘数值的初始值设为字符‘0’,并使用menset函数进行初始化。

void initboard(char board[ROW][COL], int row, int col) //棋盘初始化 { memset(&board[0][0], ' ', row * col * sizeof(board[0][0]));//memset函数((初始化)的首地址,初始化内容,初始化内容对应的大小) } 棋盘打印

在棋盘打印上,我们仅需要用一个简单的双重循环进行打印数组的对应情况即可,并为了美化棋盘,在循环中插入|和___进行美化,具体实现如下:

void drawboard(char board[ROW][COL], int row, int col)//打印棋盘 { for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { printf(" %c ", board[i][j]); if (j < col - 1) { printf("|");//进行美化 } } printf("\n"); if (i < row - 1) { printf("---|---|---");//美化效果 } printf("\n"); } } 玩家落子

当玩家落子时,我们设计时应考虑到玩家在输入坐标时是否合法以及落子位置是否已存在棋子,我们设计一个循环对此情况进行处理,当玩家未输入到正确位置时,我们让输入过程持续进行,直至玩家输入正确,输入正确,给该位置对应数组的值附上‘#’,并跳出循环

void Player(char board[ROW][COL], int row, int col)//考虑输入合法性,棋盘位置和棋盘上,合法直接落子 { int x; int y; while (1) { printf("请输入坐标以落子\n"); scanf("%d %d", &x, &y); if (x < 1 || x>3 || y < 1 || y>3 || board[x - 1][y - 1] != ' ') { printf("输入非法,请重新输入\n"); } else { board[x - 1][y - 1] = '#'; break; } } } 电脑落子

当电脑落子时,为了简化程序,我们利用时间戳函数,让电脑随机生成坐标值,并进行落子,这里我们将电脑落子的数组对应值赋值为‘*’,值得注意的是,由于电脑是随机落子,因而也需要考虑到落子位置的合法性。

void CSplayer(char board[ROW][COL], int row, int col) { while (1) { int x = rand() % row; int y = rand() % col; if (board[x - 1][y - 1] == ' ') { board[x - 1][y - 1] = '*'; break; } } } 判断输、赢、和三种情况

设计三种情况时,由于输赢的情况类似,我们仅需判断本次落子的米字型方向是否三子连线,人类落子时就判断符号‘#’,电脑落子时判断符号‘*’,并对满足输赢的情况进行数值返回,宣判结果。

而若是和棋则是棋盘被填满,我们将棋盘的二位数组进行遍历,如果数组的每一个数值都不为‘ ’且不满足输赢情况时,我们可以判断此时和棋。

char IsWin(char board[ROW][COL], int row, int col)//米字型检索,若满足任意一种情况则返回对应的数值,进行输赢宣判 { for (int i = 0; i < 3; i++) { if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][2] == board[i][0] && board[i][0] != ' ') { return board[i][0]; } } for (int i = 0; i < 3; i++) { if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[2][i] == board[0][i] && board[0][i] != ' ') { return board[0][i]; } } if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[2][2] == board[0][0] && board[0][0] != ' ') { return board[0][0]; } if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[2][0] == board[0][2] && board[0][2] != ' ') { return board[0][2]; } if (IsFull(board, ROW, COL))//若棋盘饱和,则宣布和棋 { return'P'; } return 'C'; } int IsFull(char board[ROW][COL], int row, int col) //运用遍历进行判断棋盘是否饱和,饱和则返回真值1,不饱和则返回0 { for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (board[i][j] == ' ') { return 0; } } } return 1; } 游戏集合函数

我们将每一个板块进行整合就得到我们的游戏集合函数

void game() { char board[ROW][COL] = { 0 }; initboard(board, ROW, COL);//传的是地址进去 drawboard(board, ROW, COL); char ret = 0; while (1) { Player(board, ROW, COL); drawboard(board, ROW, COL); ret =IsWin(board, ROW, COL); if (ret != 'C')//游戏结束条件 { break; } CSplayer(board, ROW, COL); drawboard(board, ROW, COL); IsWin(board, ROW, COL); if (ret != 'C')//游戏结束条件 { break; } } if (ret == '#')//输赢和判断 { printf("你赢了\n"); } else if (ret == '*') { printf("你输了\n"); } else printf("平局\n"); printf("\n\n\n"); } 完整代码 gamethree.c #include"game.h" void menu()//菜单界面 { printf("三子棋\n"); printf("**********按一开始**********\n"); printf("**********按零结束**********\n"); printf("请输入\n"); } void game() { char board[ROW][COL] = { 0 }; initboard(board, ROW, COL);//传的是地址进去 drawboard(board, ROW, COL); char ret = 0; while (1) { Player(board, ROW, COL); drawboard(board, ROW, COL); ret =IsWin(board, ROW, COL); if (ret != 'C')//游戏结束条件 { break; } CSplayer(board, ROW, COL); drawboard(board, ROW, COL); IsWin(board, ROW, COL); if (ret != 'C')//游戏结束条件 { break; } } if (ret == '#')//输赢和判断 { printf("你赢了\n"); } else if (ret == '*') { printf("你输了\n"); } else printf("平局\n"); printf("\n\n\n"); } int main() { int input = 0; srand((unsigned int)time(NULL)); do { menu(); scanf("%d", &input); if (input == 1) { game(); } else break; } while (input); return 0; } game.c #include"game.h" void initboard(char board[ROW][COL], int row, int col) //棋盘初始化 { memset(&board[0][0], ' ', row * col * sizeof(board[0][0]));//memset函数((初始化)的首地址,初始化内容,初始化内容对应的大小) } void drawboard(char board[ROW][COL], int row, int col)//打印棋盘 { for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { printf(" %c ", board[i][j]); if (j < col - 1) { printf("|");//进行美化 } } printf("\n"); if (i < row - 1) { printf("---|---|---");//美化效果 } printf("\n"); } } void Player(char board[ROW][COL], int row, int col)//考虑输入合法性,棋盘位置和棋盘上,合法直接落子 { int x; int y; while (1) { printf("请输入坐标以落子\n"); scanf("%d %d", &x, &y); if (x < 1 || x>3 || y < 1 || y>3 || board[x - 1][y - 1] != ' ') { printf("输入非法,请重新输入\n"); } else { board[x - 1][y - 1] = '#'; break; } } } void CSplayer(char board[ROW][COL], int row, int col) { while (1) { int x = rand() % row; int y = rand() % col; if (board[x - 1][y - 1] == ' ') { board[x - 1][y - 1] = '*'; break; } } } char IsWin(char board[ROW][COL], int row, int col)//米字型检索,若满足任意一种情况则返回对应的数值,进行输赢宣判 { for (int i = 0; i < 3; i++) { if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][2] == board[i][0] && board[i][0] != ' ') { return board[i][0]; } } for (int i = 0; i < 3; i++) { if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[2][i] == board[0][i] && board[0][i] != ' ') { return board[0][i]; } } if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[2][2] == board[0][0] && board[0][0] != ' ') { return board[0][0]; } if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[2][0] == board[0][2] && board[0][2] != ' ') { return board[0][2]; } if (IsFull(board, ROW, COL))//若棋盘饱和,则宣布和棋 { return'P'; } return 'C'; } int IsFull(char board[ROW][COL], int row, int col) //运用遍历进行判断棋盘是否饱和,饱和则返回真值1,不饱和则返回0 { for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (board[i][j] == ' ') { return 0; } } } return 1; } game.h #include #include #include #include #define COL 3 #define ROW 3 void initboard(char board[ROW][COL], int row, int col ); void drawboard(char board[ROW][COL], int row, int col); void Player(char board[ROW][COL], int row, int col);//考虑输入合法性,棋盘位置和棋盘上,合法直接落子 void CSplayer(char board[ROW][COL], int row, int col); char IsWin(char board[ROW][COL], int row, int col); int IsFull(char board[ROW][COL], int row, int col); 程序总结

三子棋游戏整体的代码实现较为简单,但我们在设计时,运用到的封装思想和模块设计思想是所有程序的关键思想,通过对三子棋的设计,能够强化我们的设计思路



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3