智能三子棋——保姆级教学。
目录
序言:
一.整体思路
二.加载逻辑
三.棋盘布置
四.下棋
五.智能化
最后:
序言:
想必三子棋大家都玩过吧,回想起小时候在地上用石头画上线,有的用石子儿,有的用树枝,下三子棋,都能玩一天。现在回想起来都是满满的回忆呀。今天带着大家来用C语言,来实现模拟实现一下三子棋游戏,来帮大家找一找童年的记忆。下面进入正题:
一.整体思路
我们三子棋主要实现的原理是,利用字符打印出一个棋盘,用二维数组存储我们下的棋子。先给大家看看什么样的。
大致就是这个样子。
然后一步一步下棋,每下一步,我们就把棋盘打印一边。
二.加载逻辑
首先每次游戏开始我们都需要一个菜单:
菜单代码:
void menu()
{printf("*****************************************\n");printf("************1.play 0.exit*************\n");printf("*****************************************\n");
}
游戏的加载逻辑,我们希望可以选择游戏开始或者退出,也不是玩完一局就没有了,而是玩完一局以后还可以继续选择玩或者不玩,只有我们选组退出时,程序才会结束。
代码:
void game()
{printf("三子棋\n");
}
int main()
{int input = 0;do{menu();printf("请输入选项:>\n");scanf("%d", &input);printf("\n");switch (input){case 1:game();break;case 0:printf("退出游戏\n");break;default:printf("输入错误,请重新输入:>\n");break;}} while (input);return 0;
}
运行效果:
设置好游戏的加载逻辑以后,后面的游戏内容就全部在game()函数里面完成。并且我们为了是程序模块化,我们将主函数放到main.c文件里面,函数声明,头文件,宏等,我们就放在game.h文件里面,函数的具体实现我们统统放在,game.c文件里面。这样我们的整体程序就会非常有序,可读性提高。
三.棋盘布置
我们使用宏常量来,规定棋盘的大小 :
#define _CRT_SECURE_NO_WARNINGS 1
#define ROW 3
#define LIN 3
#include<stdio.h>void menu();void game();
void game()
{//创建二维数组char chess[ROW][LIN] = { 0 };//初始化用来装棋子的二维数组init_board(chess,ROW,LIN);//打印棋盘print_board(chess,ROW,LIN);
}
void init_board(char chess[ROW][LIN], int row, int lin)
{for (int i = 0; i < row; i++){for (int j = 0; j < lin; j++){//二维数组全部初始化位空格chess[i][j] = ' ';}}
}
void print_board(char chess[ROW][LIN],int row,int lin)
{for (int i = 0; i < row; i++){for (int j = 0; j < lin; j++){//空格 + 棋子 + 空格 + | ,为一组,一共//需要 lin 组,但是最后一组不需要 |printf(" %c ",chess[i][j]);//控制最后一个 | 不打印if (j < row - 1){printf("|");}}//换行printf("\n");// | | //---|---|---//为一组,一共需要 row 组,但是最后一组,不需要 ---|---|---if (i < lin - 1){for (int j = 0; j < row; j++){// ---| 为一组,一共 row 组,最后一组不需要打印 |printf("---");if (j < row - 1){printf("|");}}}printf("\n");}
}
运行效果:
四.下棋
下棋的主要逻辑实现就是,封装两个函数player_chess()用来表示玩家下棋和电脑下棋computer_board(),玩家输入坐标,并将玩家代表的棋子存入棋盘的二维数组里面,电脑下棋先给他设置成随机下棋,然后每次下完一颗棋子我们就打印一下整个棋盘。我们需要一直下棋,每下一颗棋子都有可能出现胜利的一方,封装一个函数is_win()用来判断是否又人赢了,所以需要每下一颗棋子就需要判断一下是否又赢得玩家,如果又赢得玩家就直接is_win直接返回胜利者的棋子,如果没有人赢就返回‘C’代表继续,如果棋盘已经满了,就返回‘Q’代表平局。
void game()
{char set;//随机数生成器srand((unsigned int)time(NULL));//创建二维数组char chess[ROW][LIN] = { 0 };//初始化用来装棋子的二维数组init_board(chess,ROW,LIN);//打印棋盘print_board(chess,ROW,LIN);while (1)//一直循环,直到结果出现输赢,或者平局{//玩家下棋player_chess(chess, ROW, LIN );//打印棋盘print_board(chess, ROW, LIN);//判断结果set=is_win(chess,ROW,LIN);if ('C' != set){break;}//电脑下棋computer_board(chess, ROW, LIN);//打印棋盘print_board(chess, ROW, LIN);//判断结果set = is_win(chess, ROW, LIN);if ('C' != set){break;}}//如果返回的是玩家代表的棋子,if (set == '*'){printf("恭喜你,你赢了!!\n");}//如果返回的是电脑代表的棋子else if ('#' == set){printf("电脑赢了!!\n");}//如果是平局else if ('Q' == set){printf("平局\n");}
}
void player_chess(char chess[ROW][LIN], int row, int lin)
{//计数玩家棋子数量count_board++;//坐标int x = 0;int y = 0;while (1){printf("请输入棋子坐标:>");scanf("%d %d", &x, &y);//判断坐标合理性,是否在棋盘内if (x >= 1 && x <= row && y >= 1 && y <= lin){//坐标位置是否为空if (chess[x-1][y-1] == ' '){chess[x-1][y-1] = '*';break;}else{printf("该位置已有棋子\n");}}else{printf("棋子坐标错误,请重新输入\n");}}
}
void computer_board(char chess[ROW][LIN], int row, int lin)
{while (1)//直到找好位置循环结束。{//随机数生成,0~2int x = rand()%row;int y = rand()%lin;//判断是否该位置为空,if (chess[x][y] == ' '){chess[x][y] = '#';break;}}
}
判断是否有玩家赢is_win()
//判断棋盘是否满了
int is_full(char chess[ROW][LIN], int row, int lin)
{for (int i = 0; i < row; i++){for (int j = 0; j < lin; j++){if (chess[i][j] == ' '){return 0;}}}return 1;
}char is_win(char chess[ROW][LIN], int row, int lin)
{//横着判断是否有三个一样的for (int i = 0; i < row; i++){if (chess[i][0] == chess[i][1] && chess[i][1] == chess[i][2] &&chess[i][0]!=' '){return chess[i][0];}}//竖着判断是否有三个一样的for (int i = 0; i < lin; i++){if (chess[0][i] == chess[1][i] && chess[1][i] == chess[2][i] && chess[0][i] != ' '){return chess[0][i];}}//斜着判断是否有三个一样的if (chess[0][0] == chess[1][1] && chess[1][1] == chess[2][2] && chess[0][0] != ' '){return chess[0][0];}//斜着判断是否有三个一样的if (chess[0][2] == chess[1][1] && chess[1][1] == chess[2][0] && chess[0][2] != ' '){return chess[0][2];}//判断棋盘是否满了int tmp = is_full(chess, ROW, LIN);if (tmp == 1){return 'Q';}return 'C';
}
这样我们三子棋的主要逻辑就实现了
五.智能化
但是大家发现这电脑傻了吧唧的,现在我们就给他智能化,但是智能化的程度取决于设计者。分析那些情况优先的,就像当你电脑还差一颗棋子就可以赢了,这就是最先考虑的情况,其次是当对手还差一颗棋子赢了,还有电脑下一颗可以达成两颗棋子的领先情况,等等还有一些情况小编不好分析,就不多介绍了。
void computer_board(char chess[ROW][LIN], int row, int lin)
{//差一棋子,优先下(1)for (int i = 0; i < row; i++){if (chess[i][0] == chess[i][1] && chess[i][0] == '#'&& chess[i][2] == ' '){chess[i][2] = '#';return;}if (chess[i][0] == chess[i][2] && chess[i][0] == '#'&& chess[i][1] == ' '){chess[i][1] = '#';return;}if (chess[i][1] == chess[i][2] && chess[i][1] == '#'&& chess[i][0] == ' '){chess[i][0] = '#';return;}}//差一棋子,优先下(2)for (int i = 0; i < lin; i++){if (chess[0][i] == chess[1][i] && chess[0][i] == '#'&& chess[2][i]==' '){chess[2][i] = '#';return;}if (chess[0][i] == chess[2][i] && chess[0][i] == '#'&&chess[1][i] == ' '){chess[1][i] = '#';return;}if (chess[1][i] == chess[2][i] && chess[1][i] == '#'&& chess[0][i] == ' '){chess[0][i] = '#';return;}}//差一棋子,优先下(3)if (chess[0][0] == chess[1][1] && chess[0][0] == '#' && chess[2][2] == ' '){chess[2][2] = '#';return;}if (chess[0][0] == chess[2][2] && chess[0][0] == '#' && chess[1][1] == ' '){chess[1][1] = '#';return;}if (chess[2][2] == chess[1][1] && chess[1][1] == '#' && chess[0][0] == ' '){chess[0][0] = '#';return;}//差一棋子,优先下(4)if (chess[0][2] == chess[1][1] && chess[0][2] == '#' && chess[2][0] == ' '){chess[2][0] = '#';return;}if (chess[0][2] == chess[2][0] && chess[0][2] == '#' && chess[1][1] == ' '){chess[1][1] = '#';return;}if (chess[2][0] == chess[1][1] && chess[1][1] == '#' && chess[0][2] == ' '){chess[0][2] = '#';return;}//对方差一棋子胜利,优先下(5)for (int i = 0; i < row; i++){if (chess[i][0] == chess[i][1] && chess[i][0] == '*' && chess[i][2] == ' '){chess[i][2] = '#';return;}if (chess[i][0] == chess[i][2] && chess[i][0] == '*' && chess[i][1] == ' '){chess[i][1] = '#';return;}if (chess[i][1] == chess[i][2] && chess[i][1] == '*' && chess[i][0] == ' '){chess[i][0] = '#';return;}}//对方差一棋子胜利,优先下(6)for (int i = 0; i < lin; i++){if (chess[0][i] == chess[1][i] && chess[0][i] == '*' && chess[2][i] == ' '){chess[2][i] = '#';return;}if (chess[0][i] == chess[2][i] && chess[0][i] == '*' && chess[1][i] == ' '){chess[1][i] = '#';return;}if (chess[1][i] == chess[2][i] && chess[1][i] == '*' && chess[0][i] == ' '){chess[0][i] = '#';return;}}//对方差一棋子胜利,优先下(7)if (chess[0][0] == chess[1][1] && chess[0][0] == '*' && chess[2][2] == ' '){chess[2][2] = '#';return;}if (chess[0][0] == chess[2][2] && chess[0][0] == '*' && chess[1][1] == ' '){chess[1][1] = '#';return;}if (chess[2][2] == chess[1][1] && chess[1][1] == '*' && chess[0][0] == ' '){chess[0][0] = '#';return;}//对方差一棋子胜利,优先下(8)if (chess[0][2] == chess[1][1] && chess[0][2] == '*' && chess[2][0] == ' '){chess[2][0] = '#';return;}if (chess[0][2] == chess[2][0] && chess[0][2] == '*' && chess[1][1] == ' '){chess[1][1] = '#';return;}if (chess[2][0] == chess[1][1] && chess[1][1] == '*' && chess[0][2] == ' '){chess[0][2] = '#';return;}//抢占先机,下完这一棋子,差一步胜利;(1)for (int i = 0; i < lin; i++){if (chess[0][i] == '#' && chess[1][i] == ' ' && chess[2][i] == ' '){chess[1][i] = '#';return;}if (chess[1][i] == '#' && chess[0][i] == ' ' && chess[2][i] == ' '){chess[0][i] = '#';return;}if (chess[2][i] == '#' && chess[0][i] == ' ' && chess[1][i] == ' '){chess[0][i] = '#';return;}}//抢占先机,下完这一棋子,差一步胜利;(2)for (int i = 0; i < row; i++){if (chess[i][0] == '#' && chess[i][1] == ' ' && chess[i][2] == ' '){chess[i][1] = '#';return;}if (chess[i][1] == '#' && chess[i][0] == ' ' && chess[i][2] == ' '){chess[i][0] = '#';return;}if (chess[i][2] == '#' && chess[i][0] == ' ' && chess[i][1] == ' '){chess[i][0] = '#';return;}}//抢占先机,下完这一棋子,差一步胜利;(3)if (chess[0][0] == '#' && chess[1][1] == ' ' && chess[2][2] == ' '){chess[1][1] = '#';return;}if (chess[0][0] == ' ' && chess[1][1] == '#' && chess[2][2] == ' '){chess[2][2] = '#';return;}if (chess[0][0] == ' ' && chess[1][1] == ' ' && chess[2][2] == '#'){chess[0][0] = '#';return;}//抢占先机,下完这一棋子,差一步胜利;(4)if (chess[0][2] == '#' && chess[1][1] == ' ' && chess[2][0] == ' '){chess[1][1] = '#';return;}if (chess[0][2] == ' ' && chess[1][1] == '#' && chess[2][0] == ' '){chess[0][2] = '#';return;}if (chess[0][2] == ' ' && chess[1][1] == ' ' && chess[2][0] == '#'){chess[0][2] = '#';return;}//第一步棋子,针对if (count_board == 1 && chess[0][0] == '*'){chess[2][2] = '#';return;}if (count_board == 1 && chess[0][2] == '*'){chess[2][0] = '#';return;}if (count_board == 1 && chess[2][0] == '*'){chess[0][2] = '#';return;}if (count_board == 1 && chess[2][2] == '*'){chess[0][0] = '#';return;}while (1){int x = rand()%row;int y = rand()%lin;if (chess[x][y] == ' '){chess[x][y] = '#';break;}}
}
最后展示成果:
这里我就已经输了,哈哈哈。
最后:
坚守之心就是不为苦难所惧。苦难是成功的磨刀石,是对人的胆识、智慧和毅力的考验。生活的道 路不是一帆风顺的,往往荆棘丛生。不少人就是迈不过这道坎,害怕、退缩、放弃、变向,结果只 能与成功失之交臂。努力成为你最喜欢的那种人,就算不成功,至少你会喜欢这样努力的自己。加油,诸君,山顶见!!!
智能三子棋——保姆级教学。相关推荐
- 【三子棋保姆级教学】
文章目录 前言 1. 游戏整体思路 2. 代码讲解 2.1 游戏大体框架 2.2 游戏的具体实现过程 2.2.1 游戏菜单的打印 2.2.2 游戏的实现过程 2.2.3 游戏实现过程中所需函数的定义 ...
- 【C语言】小游戏系列——三子棋(保姆级教程)
我相信三子棋大家并不陌生,小时候经常玩,深受大家的喜欢.今天我们用c语言来编写一个简单的三子棋小游戏,在C语言的学习中,就应该用一些有趣的代码来激励我们,增加我们对编程的热爱.下面我来讲述如何去实现一 ...
- 【不收藏一定后悔】超智能三子棋——和电脑比一把
目录 分析 test.c game.c game.h 智能三子棋,才更有挑战 重头戏刚开始 对于三子棋,俗称#字棋,从小玩到大,如今自己也能实现了,真是颇有成就的. 分析 接下来,我们一起实现超智能的 ...
- Java EE系列(九)——Java EE连接Mysql数据库(JDBC保姆级教学)
最近几天,peter xiao所在的项目小组也逐渐开始进行做最后的Java web课程大作业了,我们组所做的是运动会报名服务系统,其中涉及到很多数据的增删查改,所以需要依靠Mysql数据库来解决这些问 ...
- 「保姆级教学」入门级java程序——薪资转换器
往期「保姆级教学」目录 「保姆级教学」iOS下JDK环境配置 文章目录 往期「保姆级教学」目录 前言 第二日任务 1.java基础语法 2.掌握java基本输入输出 3.掌握java基本数据类型和变量 ...
- Fortran保姆级教学——考试所有知识点看这一篇就够了
Fortran保姆级教学--考试所有知识点看这一篇就够了 临近期末本人复习的同时将整个fortran课堂知识整理了下来,希望学弟学妹们今后学这门课的时候不至于在csdn找不到系统的教程,也希望能帮到需 ...
- 保姆级教学——集群环境搭建及创建集群
保姆级教学--集群环境搭建及创建集群 新建虚拟机 一些默认,加载镜像开启虚拟机,在安装位置选择自己目录,然后建立分区,首先添加 挂载点,类型标准分区,文件系统ext4 加载分区,期望给2G, 类型标准 ...
- 【量化回测必看!】Backtrader保姆级教学+免费行情源 SMA策略
前言 想开始量化学习不知道如何入手?市面上的学习资料太多不知道该怎么看? 博主将从零基础讲解回测框架,一步步完成量化数据源的搭建,让你10天内成为量化高手 博主同时将视频课程内容在B站更新,可以关注& ...
- 英伟达的Nerf:instant_ngp在Windows10下的配置和使用--保姆级教学
英伟达的Nerf:instant_ngp在Windows10下的配置和使用–保姆级教学 1.前言 Nerf的原理和厉害之处在这里就不做详细介绍了,本文主要是针对小白在Windows10环境下配置ins ...
最新文章
- 28、FileThumbnails
- LambdaMART简介——基于Ranklib源码(一 lambda计算)
- 笔记本电脑怎样连接打印机_佳能无线便携打印机上市
- Java黑皮书课后题第5章:**5.34(游戏:石头、剪刀、布)编程练习题3.17给出玩石头-剪刀-布游戏的程序。修改这个程序,让用户可以连续玩这个游戏,直到用户或者计算机赢对手两次以上为止
- C语言九十三之输入一个字符x,找到输入的那句话(字符串)里面一样字母的位置。
- 服务器网络销售软文,关于云服务器的软文
- Atitit 提升可读性sql subquery udf 子查询 目录 1. 使用udf 和参数@简化join和subquery	1 1.1.1. 子查询分类	1 2. 2.1 按返回结果集分类
- 动态链接库(共享库).so文件的使用
- j2me模拟器qq2007_如何在J2ME中创建MIDlet
- 11款中兴盒子固件合集分享(已列出全部型号,附刷机教程)
- flash打造佛光效果实例教程
- Win10台式电脑怎么不拔网线断网
- 网站百度快速排名软件系统
- MindManager 2018如何新建维恩图
- 联想拯救者y7000p电池怎么卸下来_联想拯救者R7000P怎么样 联想拯救者R7000P全面评测_笔记本_硬件教程...
- (EPROCESS/KPROCESS/ETHREAD/KTHREAD)进程与线程内核层中的结构
- 接口详解(JAVA)
- 如何使用Google云端硬盘备份和还原WhatsApp消息
- 系统调用是什么,你用过哪些系统调用
- 我们的管理:部门管理