目录
首先,欢迎各位点进我的文章。话不多说,正如标题一样,接下来,我来给大家讲解三子棋小游戏的设计思路以及代码实现。
一,设计思路
一. 大家应该都玩过王者荣耀,原神之类的游戏吧,虽然这个三子棋小游戏无法与之相提并论,但它仍然需要一个游戏该有的基本功能 ——选择是否进入游戏,游戏内容,游戏完毕后选择是否退出游戏。(此程序会有很多代码,所以要尽量使用言简意赅,一看就懂的函数来构造)
以上代码便实现了游戏的最外层的框架。
二.在确定了上述框架后,我们要填充游戏的具体内容,而三子棋小游戏需要的内容便是:
1.初始化棋盘
2.打印棋盘
3.玩家下棋
4.打印棋盘
5.判断游戏结果:(输赢,平局或者继续)以下不再赘述。
6.电脑下棋
7.打印棋盘
8.判断游戏结果。
9.打印游戏对局结果。
接下来对以上内容进行分析
其中,1.初始化棋盘 2.打印初始化的棋盘 9.打印游戏对局结果 是在玩家与电脑对峙的内容以外的部分。
而3.4.5.6.7.8是电脑与玩家对峙的部分,而对峙会持续几个回合,所以需要循环结构。
因此,1.2.9要放在循环之外,345678要放在循环内部。
如下,便是代码结构。(我们先假设*代表玩家,#代表电脑,C代表继续游戏,Q代表平局)。
如上图,代码的最终框架终于得到完善,设计思路也跟上面所讨论的相同。即为——1.2.9要放在循环之外,345678要放在循环内部。
接下来,便是整个程序中最难的地方——函数的代码实现。
二, 代码实现
由上图可知,我们创建了以下函数
可见数量之多,然而主函数所在文件(test.c)已经足够复杂,我们最好不要再去增加它的负担,不要破坏它的可读性。
于是,这时候,我们就要创建另外两个文件,分别是:game.c和game.h
game.h用来存放宏定义,头文件和函数声明。
game.c用来存放函数的具体内容(实现)。
接下来,只需要完成game.c和game.h中的内容,并将game.h引入test.c和game.c即可
我们需要依照上图中的函数按顺序一个一个的实现。
第一个函数
它的功能是初始化棋盘,将其全变为空白。因此,不需要返回值,参数需要有:棋盘第一个元素的地址(这里棋盘用二维数组来表示) 棋盘的行数 棋盘的列数
棋盘的行数和列数在头文件中 定义
要将棋盘全初始化为空白,需要遍历行和列,于是想到了用嵌套循环。以下是代码实现。
第二个函数
它的功能是打印棋盘,因此不需要返回值,参数同上。
理想中的三子棋棋盘应该是这个样子:
又因为我们不想把棋盘写死——仅能用于三子棋,所以我们要把棋盘拆分成模块来进行打印。
即:我们要打印n列这个东西,其实就是“ %c ”和“|” (注意%c的前后有空格 )。
但注意最后一列不需要“|”,所以需要判断结构。
然后还要打印分割线,也就是“---”和“|”,当然最后一列同样不需要“|”,需要判断。
并且棋盘最后一行也不需要分割线,也需要判断。
思考了这些之后,得到了如下代码。
第三个函数
它的返回值和参数同上
它的功能是在玩家输入两个坐标之后,在相应的位置打印“*” 。
但是玩家输入的坐标不可以超过棋盘范围,也不可以在已经有棋子的地方落子,因此需要判断结构,并且在输入错误之后,要提醒玩家重新输入,因此需要循环结构。(另外需要注意,玩家输入坐标等于二维数组坐标加一)
代码如下
第四个函数
它的返回值和参数同上
此函数的功能是命令电脑下棋,在随机位置打印“#”
同样的,电脑也不可以在超出棋盘范围下棋,不可以在有棋子的地方下棋。
但随机位置下棋该如何实现呢?
这就要用到<stdlib.h>中的rand()函数生成随机数了
而要用rand()函数还需要用srand()函数设置随机数起点,
要用srand()函数设置起点,还需要一个随机数(笑哭),读者是不是以为要没完了
幸好我们还有时间戳函数,它会根据时间来生成随机数,而使用它还需要包含<time.h>。
这下终于解决了随机数的问题,但是rand()生成的随机数范围过大,需要根据棋盘来限制范围。
也就是说需要这样——x=rand()%col y=rand()%row .
构思完毕,代码如下
这是在game.h中需要包含的。
以下是game.c中需要包含的
第五个函数,也是最后一个,好耶,但是还有点难,坏耶。
这个函数要判断对局的结果,我们需要让他在不同的情况下返回不同的值
1.玩家赢,返回“*”
2.电脑赢,返回“#”
3.平局,返回“Q”
4.对局继续,返回“C”
因此,它的返回值应该设置为char类型。参数同上。
如果有一行或者一列或对角线都是一个字符,则返回这个字符。如果都不是空格就返回“Q”。在此处写了一个函数判断棋盘是否被占满,专门服务于is_win函数。
博主技术力不足,暂时写死了(哭)
OK,以上便是全部内容了,欢迎大家讨论指正批评doge。