100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > C语言实现三子棋plus版本(困难人机电脑不会输 支持双人对战)

C语言实现三子棋plus版本(困难人机电脑不会输 支持双人对战)

时间:2022-12-05 09:49:40

相关推荐

C语言实现三子棋plus版本(困难人机电脑不会输 支持双人对战)

目录

一、功能描述二、游戏部分功能介绍三、代码实现1. main()代码2.游戏菜单代码3.playgame()代码3.模式菜单和难度菜单4.初始化棋盘5.打印棋盘6.玩家下棋7.简单人机下棋8.困难人机下棋8.1 电脑检测自己这次落棋后是否能赢8.2 电脑检测是否要堵玩家的棋8.3 困难人机主函数9.判断输赢9.1 判断是否棋盘满9.2 判断输、赢、平局10.双人游戏四、游戏页面以及结果演示1.人机模式1.1 简单人机1.2 困难人机2.双人模式五、全部代码

一、功能描述

该版本可以选择双人游戏和人机对战,并且人机对战分为两个等级(简单人机随机下棋;困难人机是优化后的算法具有堵棋、三连功能)。

二、游戏部分功能介绍

1.打印游戏菜单

2.初始化棋盘

3.打印棋盘

4.打印模式菜单

5.打印难度菜单

6.双人游戏

7.简单人机

8.困难人机

9.判断棋盘是否下满

10.判断输赢

三、代码实现

1. main()代码

用户输入

int main() {srand((unsigned int)time(NULL));//随机数int input = 0;do{menu();printf("请输入 >");scanf("%d", &input);switch (input) {case 1:playgame();break;case 0:printf("游戏退出...\n");break;default:printf("请输入正确的格式\n");}} while (input);return 0;}

2.游戏菜单代码

void menu() {printf("****************************\n");printf("***** 0 退出游戏 ******\n");printf("***** 1 进入游戏 ******\n");printf("****************************\n");}

3.playgame()代码

void playgame() {char model;//接收用户选择的模式char difficulty;//接收难度系数char ch;//接收数据 用于清空缓存区model_menu();printf("请你选择模式 >");while ((ch = getchar()) != '\n' && ch != EOF);//清空缓存区 scanf("%c", &model);if (model == 'a') {difficulty_menu();printf("请选择难度等级:");while ((ch = getchar()) != '\n' && ch != EOF);//清空缓存区 scanf("%c", &difficulty);if (difficulty == 'd') {printf("困难模式开始...\n");playgame_pvc(&difficulty);}else if (difficulty == 'e') {printf("简单模式开始...\n");playgame_pvc(&difficulty);}}else if (model == 'b') {printf("人人对战\n");play_game_pvp();}}

3.模式菜单和难度菜单

//模式菜单void model_menu() {printf("***************************\n");printf("** a 人机模式 b 双人模式 **\n");printf("***************************\n");}//难度菜单void difficulty_menu() {printf("***************************\n");printf("** e 简单模式 d 困难模式 **\n");printf("***************************\n");}

4.初始化棋盘

void init_board(char board[ROW][COL], int row, int col) {int i = 0;for (i = 0; i < row; i++) {int j = 0;for (j = 0; j < col; j++) {board[i][j] = ' ';}}}

5.打印棋盘

void print_board(char board[ROW][COL], int row, int col) {int i = 0;for (i = 0; i < row; i++) {//打印数据for (int j = 0; j < col; j++) {if (j < col - 1)printf(" %c |", board[i][j]);elseprintf(" %c\n", board[i][j]);}//打印分隔符if (i < row - 1) {for (int j = 0; j < row; j++) {if (j < row - 1)printf("---|");elseprintf("---\n");}}}}

6.玩家下棋

void person_move(char board[ROW][COL], int row, int col) {int i = 0, j = 0;while (1) {scanf("%d %d", &i, &j);if (board[i - 1][j - 1] == ' ') {//注意坐标与二维数组对应关系board[i - 1][j - 1] = '*';break;}else {printf("此位置已被下过,请重新落棋:");}}}

7.简单人机下棋

void computer_move_easy(char board[ROW][COL], int row, int col) {int i = 0, j = 0;printf("电脑走:\n");while (1) {i = rand() % row;j = rand() % col;if (board[i][j] == ' ') {board[i][j] = '#';break;}}}

8.困难人机下棋

8.1 电脑检测自己这次落棋后是否能赢

电脑检测棋盘在横向、纵向以及主副对角线是否有两个’#‘,如果有就代表电脑可以直接下上第三个’#‘;如果没有则需要继续判断是否需要堵玩家的棋子。代码:

//检查电脑是否一线两子 如果有直接赢int computer_will_win(char board[ROW][COL], int row, int col) {int i = 0;int j = 0;int p_win = 0;//标志是否直接赢if(0 == p_win){//判断电脑横行上是否会赢for (i = 0; i < row; i++){if (board[i][0] == board[i][1] && board[i][1] == '#' && board[i][2] == ' '){board[i][2] = '#';p_win = 1;break;}if (board[i][0] == board[i][2] && board[i][0] == '#' && board[i][1] == ' '){board[i][1] = '#';p_win = 1;break;}if (board[i][1] == board[i][2] && board[i][1] == '#' && board[i][0] == ' '){board[i][0] = '#';p_win = 1;break;}}if (p_win != 0)return p_win;//判断电脑列上是否有机会赢for (j = 0; j < col; j++){if (board[0][j] == board[1][j] && board[1][j] == '#' && board[2][j] == ' '){board[2][j] = '#';p_win = 1;break;}if (board[0][j] == board[2][j] && board[2][j] == '#' && board[1][j] == ' '){board[1][j] = '#';p_win = 1;break;}if (board[1][j] == board[2][j] && board[2][j] == '#' && board[0][j] == ' '){board[0][j] = '#';p_win = 1;break;}}if (p_win != 0)return p_win;}//判断电脑在对角线上是否会赢if (0 == p_win){if (board[0][0] == board[1][1] && board[1][1] == '#' && board[2][2] == ' '){board[2][2] = '#';p_win = 1;return p_win;}if (board[0][0] == board[2][2] && board[2][2] == '#' && board[1][1] == ' '){board[1][1] = '#';p_win = 1;return p_win;}if (board[1][1] == board[2][2] && board[1][1] == '#' && board[0][0] == ' '){board[0][0] = '#';p_win = 1;return p_win;}if (board[0][2] == board[1][1] && board[0][2] == '#' && board[2][0] == ' '){board[2][0] = '#';p_win = 1;return p_win;}if (board[0][2] == board[2][0] && board[2][0] == '#' && board[1][1] == ' '){board[1][1] = '#';p_win = 1;return p_win;}if (board[1][1] == board[2][0] && board[2][0] == '#' && board[0][2] == ' '){board[0][2] = '#';p_win = 1;return p_win;}}return p_win;//p_win==0 说明没有直接赢 需继续判断是否要堵棋}

8.2 电脑检测是否要堵玩家的棋

如果程序执行到此说明电脑不能直接赢,而是要判断玩家的棋子有没有一条线上出现二连’ * '的情况。如果有就“堵棋”;如果也不需要“堵棋”,那么电脑就随机下棋了(执行简单人机的核心下棋代码)。代码:

//检测玩家是否能一线两子 如果有就堵int people_will_win(char board[ROW][COL], int row, int col) {int i = 0;int j = 0;int k = 0;while (0 == k){//判断玩家在横行上是否会赢for (i = 0; i < row; i++){if (board[i][0] == board[i][1] && board[i][1] == '*' && board[i][2] == ' '){board[i][2] = '#';k = 1;break;}if (board[i][0] == board[i][2] && board[i][0] == '*' && board[i][1] == ' '){board[i][1] = '#';k = 1;break;}if (board[i][1] == board[i][2] && board[i][1] == '*' && board[i][0] == ' '){board[i][0] = '#';k = 1;break;}}if (k != 0)break;//判断玩家在竖列上是否会赢for (j = 0; j < col; j++){if (board[0][j] == board[1][j] && board[1][j] == '*' && board[2][j] == ' '){board[2][j] = '#';k = 1;break;}if (board[0][j] == board[2][j] && board[2][j] == '*' && board[1][j] == ' '){board[1][j] = '#';k = 1;break;}if (board[1][j] == board[2][j] && board[2][j] == '*' && board[0][j] == ' '){board[0][j] = '#';k = 1;break;}}break;}//判断玩家在对角线上是否会赢while (0 == k){if (board[0][0] == board[1][1] && board[1][1] == '*' && board[2][2] == ' '){board[2][2] = '#';k = 1;break;}if (board[0][0] == board[2][2] && board[2][2] == '*' && board[1][1] == ' '){board[1][1] = '#';k = 1;break;}if (board[1][1] == board[2][2] && board[1][1] == '*' && board[0][0] == ' '){board[0][0] = '#';k = 1;break;}if (board[0][2] == board[1][1] && board[0][2] == '*' && board[2][0] == ' '){board[2][0] = '#';k = 1;break;}if (board[0][2] == board[2][0] && board[2][0] == '*' && board[1][1] == ' '){board[1][1] = '#';k = 1;break;}if (board[1][1] == board[2][0] && board[2][0] == '*' && board[0][2] == ' '){board[0][2] = '#';k = 1;break;}break;}return k;//返回值如果是1那么已经对玩家进行了堵棋,如果是0则无需堵。}

8.3 困难人机主函数

//电脑下棋优化版void computer_move_diff(char board[ROW][COL], int row, int col) {int i = 0, j = 0;int p;printf("电脑走:\n");//电脑先检测自己这一次落棋后自己是否能赢p = computer_will_win( board, row, col);if (p == 1) {//电脑已经下过棋return;}//检查玩家是否会赢 会赢直接堵截p = people_will_win(board, row, col);if (p == 1) {//电脑对玩家进行了堵截不需要再下return;}//运行到这说明也没有赢 也没有堵截 随机下棋while (1) {i = rand() % row;j = rand() % col;if (board[i][j] == ' ') {board[i][j] = '#';break;}}}

9.判断输赢

9.1 判断是否棋盘满

代码:

//判断棋盘是否下满int is_full(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;}

9.2 判断输、赢、平局

如果在任一方向出现三连一样的字符(排除三连空格情况),那么久说明有一方赢了,直接返回这个字符(#:代表电脑赢(或者玩家2)、* :代表玩家赢)。如果没有人赢就判断是否出现平局的情况(棋盘满了)。如果以上情况均未发生那就游戏继续。代码:

//检查是否有一方获胜char check_win(char board[ROW][COL], int row, int col){int i;//判断横向是否有一样的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 (i = 0; i < col; i++){if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' ')return board[1][i];}//判断对角线是否有一样的if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')return board[1][1];else if (board[2][0] == board[1][1] && board[1][1] == board[0][2] && board[1][1] != ' ')return board[1][1];//如果没人赢 检查棋盘是否满 也就是平局else if (is_full(board, row, col))return '$';//以上情况都没有则分不出输赢return 0;}

10.双人游戏

有了以上各种函数基础双人游戏代码就很简单了,只需要让一方先下棋,打印出棋盘然后判断是否分出胜负;另一方下棋,打印出棋盘然后判断胜负。如此循环知道分出胜负。代码:

//双人对战游戏void play_game_pvp() {char key;//接收输赢结果//定义棋盘char board[ROW][COL];//初始化棋盘init_board(board, ROW, COL);//打印棋盘print_board(board, ROW, COL);while (1){printf("请p1下棋:(输入坐标)>");person_move(board, ROW, COL);//玩家1下棋print_board(board, ROW, COL);//打印棋盘key = check_win(board, ROW, COL);//判输赢平局//打印输赢结果if (key == '*'){printf("恭喜p1赢啦\n");break;}if (key == '#'){printf("恭喜p2赢了\n");break;}if (key == '$'){printf("平局了!\n");break;}printf("请p2下棋:(输入坐标)>");person2_move(board, ROW, COL);//玩家2下棋print_board(board, ROW, COL);//打印棋盘key = check_win(board, ROW, COL);//判输赢平局//打印输赢结果if (key == '*'){printf("恭喜你获得胜利啦\n");break;}if (key == '#'){printf("p2赢了\n");break;}if (key == '$'){printf("你们打平局了!\n");break;}}}

四、游戏页面以及结果演示

1.人机模式

1.1 简单人机

这时的人机还很呆 不会堵棋,玩家轻易获胜!

1.2 困难人机

困难人机一旦二连就可以直接赢。

困难人机可以在三个方向赌棋

2.双人模式

五、全部代码

全部代码内容较多 以上也展示的差不多了,避免页面太长,想要直接全部拷贝来自己玩一玩的小伙伴可以码云复制。

点击这里获取全部代码

写的思想比较简单 可能存在错误如有发现欢迎指正 咱再继续改进。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。