目录

序言:

一.整体思路

二.加载逻辑

三.棋盘布置

四.下棋

五.智能化

最后:


序言:

想必三子棋大家都玩过吧,回想起小时候在地上用石头画上线,有的用石子儿,有的用树枝,下三子棋,都能玩一天。现在回想起来都是满满的回忆呀。今天带着大家来用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. 【三子棋保姆级教学】

    文章目录 前言 1. 游戏整体思路 2. 代码讲解 2.1 游戏大体框架 2.2 游戏的具体实现过程 2.2.1 游戏菜单的打印 2.2.2 游戏的实现过程 2.2.3 游戏实现过程中所需函数的定义 ...

  2. 【C语言】小游戏系列——三子棋(保姆级教程)

    我相信三子棋大家并不陌生,小时候经常玩,深受大家的喜欢.今天我们用c语言来编写一个简单的三子棋小游戏,在C语言的学习中,就应该用一些有趣的代码来激励我们,增加我们对编程的热爱.下面我来讲述如何去实现一 ...

  3. 【不收藏一定后悔】超智能三子棋——和电脑比一把

    目录 分析 test.c game.c game.h 智能三子棋,才更有挑战 重头戏刚开始 对于三子棋,俗称#字棋,从小玩到大,如今自己也能实现了,真是颇有成就的. 分析 接下来,我们一起实现超智能的 ...

  4. Java EE系列(九)——Java EE连接Mysql数据库(JDBC保姆级教学)

    最近几天,peter xiao所在的项目小组也逐渐开始进行做最后的Java web课程大作业了,我们组所做的是运动会报名服务系统,其中涉及到很多数据的增删查改,所以需要依靠Mysql数据库来解决这些问 ...

  5. 「保姆级教学」入门级java程序——薪资转换器

    往期「保姆级教学」目录 「保姆级教学」iOS下JDK环境配置 文章目录 往期「保姆级教学」目录 前言 第二日任务 1.java基础语法 2.掌握java基本输入输出 3.掌握java基本数据类型和变量 ...

  6. Fortran保姆级教学——考试所有知识点看这一篇就够了

    Fortran保姆级教学--考试所有知识点看这一篇就够了 临近期末本人复习的同时将整个fortran课堂知识整理了下来,希望学弟学妹们今后学这门课的时候不至于在csdn找不到系统的教程,也希望能帮到需 ...

  7. 保姆级教学——集群环境搭建及创建集群

    保姆级教学--集群环境搭建及创建集群 新建虚拟机 一些默认,加载镜像开启虚拟机,在安装位置选择自己目录,然后建立分区,首先添加 挂载点,类型标准分区,文件系统ext4 加载分区,期望给2G, 类型标准 ...

  8. 【量化回测必看!】Backtrader保姆级教学+免费行情源 SMA策略

    前言 想开始量化学习不知道如何入手?市面上的学习资料太多不知道该怎么看? 博主将从零基础讲解回测框架,一步步完成量化数据源的搭建,让你10天内成为量化高手 博主同时将视频课程内容在B站更新,可以关注& ...

  9. 英伟达的Nerf:instant_ngp在Windows10下的配置和使用--保姆级教学

    英伟达的Nerf:instant_ngp在Windows10下的配置和使用–保姆级教学 1.前言 Nerf的原理和厉害之处在这里就不做详细介绍了,本文主要是针对小白在Windows10环境下配置ins ...

最新文章

  1. 28、FileThumbnails
  2. LambdaMART简介——基于Ranklib源码(一 lambda计算)
  3. 笔记本电脑怎样连接打印机_佳能无线便携打印机上市
  4. Java黑皮书课后题第5章:**5.34(游戏:石头、剪刀、布)编程练习题3.17给出玩石头-剪刀-布游戏的程序。修改这个程序,让用户可以连续玩这个游戏,直到用户或者计算机赢对手两次以上为止
  5. C语言九十三之输入一个字符x,找到输入的那句话(字符串)里面一样字母的位置。
  6. 服务器网络销售软文,关于云服务器的软文
  7. Atitit 提升可读性sql subquery udf 子查询 目录 1. 使用udf 和参数@简化join和subquery 1 1.1.1. 子查询分类 1 2. 2.1 按返回结果集分类
  8. 动态链接库(共享库).so文件的使用
  9. j2me模拟器qq2007_如何在J2ME中创建MIDlet
  10. 11款中兴盒子固件合集分享(已列出全部型号,附刷机教程)
  11. flash打造佛光效果实例教程
  12. Win10台式电脑怎么不拔网线断网
  13. 网站百度快速排名软件系统
  14. MindManager 2018如何新建维恩图
  15. 联想拯救者y7000p电池怎么卸下来_联想拯救者R7000P怎么样 联想拯救者R7000P全面评测_笔记本_硬件教程...
  16. (EPROCESS/KPROCESS/ETHREAD/KTHREAD)进程与线程内核层中的结构
  17. 接口详解(JAVA)
  18. 如何使用Google云端硬盘备份和还原WhatsApp消息
  19. 系统调用是什么,你用过哪些系统调用
  20. 我们的管理:部门管理

热门文章

  1. 织梦网站频道管理员不能添加栏目
  2. Supervisor的使用方法
  3. sql2005如何修改服务器名称,sql2005 服务器名称设置
  4. MATLAB图像的两种模糊模式
  5. 武汉微软认证考点及考试流程 与 微软认证考试流程
  6. kindeditor文本编辑器使用
  7. Hyper-V相关Powershell cmdlets
  8. 【RT-Thread 开源作品秀】小型蚯蚓养殖监控系统
  9. Docker、Docker、Docker
  10. LSGO软件技术团队2015~2016学年第十四周(1130~1206)总结