最后更新:2022-01-26 09:43
? 前言
Wassup guys?
今天是我们的C语言小项目「井字棋升级版」
Let’s get it!
井字棋,又名三子棋,英文名叫Tic-Tac-Toe;
是一种在3x3格子上进行的连珠游戏,和五子棋类似,格线排成井字故得名。
游戏需要的工具仅为纸和笔,然后由分别代表O和X的两个游戏者轮流在格子里留下标记(一般来说先手者为X),任意三个标记形成一条直线,则为获胜。
其游戏过程就像下面这样?
游戏运行结果如下?
我在 函数 这一篇总结中,讲过函数的声明和定义,所有这里我用三个文件来实现这个三子棋游戏
友友们可以将以下代码复制到自己的编译器当中运行:
◾
game.h
游戏函数的声明
◾
game.c
游戏函数的实现
◾
test.c
测试游戏
打印一个游戏菜单,有两种选择
1、玩游戏
0、退出游戏
代码实现?
当运行这个游戏的时候,会首先生成一个菜单,让我们选择;
但是当我玩完一局过后,还想再玩,所以会用到循环
代码实现?
在
game()函数,去实现三子棋的过程
三子棋,顾名思义,我们要定义一个3x3的二维数组棋盘
当棋盘数组定义好以后,我们就要初始化棋盘
可以看到,这个棋盘里面最开始都是空的,所以我们把棋盘定义成空的字符
首先我们要在
game.h头文件里面去声明这个初始化函数
然后再去
game.c游戏函数里面实现
注意:后面的函数也是一样,要先去头文件里面声明,再到游戏函数里面去实现
我们初始化好棋盘以后,要在屏幕上打印一下
![]()
聪明的朋友能猜到这个棋盘是怎么想出来的吗?
代码实现?
接下来就是玩家开始下棋;
由于是个二维数组,并且数组下标是从0开始的,但是玩家可能不是程序员,所以不知道数组的下标;
所以这里把下标定义从1开始;
并且当玩家在棋盘落子以后,我们把棋盘打印出来。
代码实现?
电脑下棋的方法我们选择用时间戳来生成一个随机数,并把随机数的范围控制在0~3以内;
关于随机数的生成,这里简单说一下
代码实现?
注意,我们这里调用rand函数,必须在主函数里面设置一下srand函数
如果你运行了这个程序以后,会发现电脑的走法貌似不太聪明的样子;
因为我们用随机数生成,会造成玩家赢的很轻松;
那如果电脑有了AI的思想呢?它就知道如何进攻、防守。
那么来思考一下,你是怎么下三子棋的?
1、如果我们在三行、三列、对角线上,下了两个棋子后,我们会继续下第三个;
2、如果对方在三行、三列、对角线上有了相同两个棋子后,我们会堵截,不让它下第三个;
此时我们就有了思路?
电脑需要的就是在:出现两个相同的棋子的地方下自己的棋子就好了
?代码一
对
ComputerMove函数进行修改;
电脑下棋需要加一步,获取返回值,如果返回值为0,那么电脑只有乖乖的按照伪随机数来走啦
?代码二
定义一个函数:
CheckComputer,作用是电脑检查自己是否会赢;
1、电脑在坐标(1,1)和坐标(1,2)的格子进行判断,如果(1,1)或者(1,2)的格子都为自己的棋子,那么直接在(1,3)的格子落子?
2、电脑在坐标(1,1)和坐标(1,3)的格子进行判断,如果(1,1)或者(1,3)的格子都为自己的棋子,那么直接在坐标(1,2)的格子落子?
3、电脑在坐标(1,2)和坐标(1,3)的格子进行判断,如果(1,2)或者(1,3)的格子都为自己的棋子,那么直接在坐标(1,1)的格子落子?
此时我们只需要定义一个循环,三行都进行判断即可,同理,三列和对角线也是一样
三行
三列
左对角线
右对角线
完整代码
?代码二
定义一个函数:
CheckPlayer,作用是电脑检查玩家是否会赢;
如果玩家在三行、三列、对角线上有了相同两个棋子后,电脑会堵截,不让玩家下第三个
1、电脑在坐标(1,1)和坐标(1,2)的格子进行判断,如果(1,1)或者(1,2)的格子都为玩家的棋子,那么直接在(1,3)的格子落子堵截?
2、电脑在坐标(1,1)和坐标(1,3)的格子进行判断,如果(1,1)或者(1,3)的格子都为玩家的棋子,那么直接在(1,2)的格子落子堵截?
3、电脑在坐标(1,2)和坐标(1,3)的格子进行判断,如果(1,2)或者(1,3)的格子都为玩家的棋子,那么直接在(1,1)的格子落子堵截?
此时我们只需要定义一个循环,三行都进行判断即可,同理,三列和对角线也是一样
三行
三列
左对角线
右对角线
完整代码
当玩家或者电脑每下一步棋的时候,我们就定义一个函数,判断一下谁赢了;
当棋盘已经落满棋子的时候,并且谁也没有赢,我们就认定为平局;
当棋盘还没有落满棋子的时候,并且谁也没有赢,游戏就继续;
1、玩家赢 —> 返回x
2、电脑赢 —> 返回o
3、平局 —> 返回P;
4、继续 —> 返回C;
那么怎么来判断输赢呢?
其实很简单,你看这个棋盘?
当三行或者三列,以及两条对角线都落满相同的棋子时,那就就赢了;
举个例子?
如图,当第一行全部落满相同的棋子
那么我们就返回中间红色这个位置的棋盘,并拿去判断;
如果是x号,那么就是玩家胜利;
如果是o号,那么就是电脑胜利
代码示例?
三行判断
三列判断
对角线判断
判断平局
游戏继续
玩家和电脑下棋的思路可以这样理解?
当玩家每下一步棋时,就进行输赢判断;
当电脑每下一步棋时,也进行输赢判断;
但是玩家走一步,电脑走一步,必须要拿循环来实现;
那么跳出循环的条件是什么呢?
上面已经分析了判断输赢的四种情况;
如果当棋盘已经全部落子了,就表示游戏不能再继续了,所以就可以跳出循环;
跳出来以后,就把上面判断输赢函数返回的结果来进行比较;
如果是x,表示玩家赢了;
如果是o,表示电脑赢了;
如果是P,表示平局了。
循环走棋
判断
其实上面的AI算法虽然说可以让电脑进行攻击和截堵,但还是有点缺陷,所以再给大家介绍一种。
这个算法很精妙,可以让玩家永远赢不了电脑,最多也就只能打成平局
首先第一步始终让电脑先落子,并且电脑落子的地方永远在坐标为(1,1)的格子里面?
(注:#表示电脑,*表示玩家)
此时玩家落子就有剩余的8个格子可以选择
那么我们就遍历每一个格子,并推演出让电脑赢的方法(这里给大家演示一种)
第一步:首先电脑在坐标(1,1)落子;
第二步:玩家在坐标(1,2)落子;
第三步:电脑在坐标(3,1)落子;
第四步:玩家在坐标(2,1)落子;
第五步:电脑在坐标(3,3)落子;
第六步:此时玩家不管在棋盘剩余空格的任意位置落子,都已经输了?
是不是很妙?其实五子棋的AI算法也类似,到时候会出一篇结合EasyX的图形化五子棋?
?结语
编程这件事情,你如果不练习,你只是学了语法而已,那是绝对不会写代码的?
?我是Edison,你知道的越多,你不知道越多,我们下期见!
本文由 在线网速测试 整理编辑,转载请注明出处。