一.制作思路
本次制作,准备模拟未来软件工程的流程进行设计。所以我准备用两个源文件和一个自建头文件来实现,主体函数为text.c,用game.h(在game.h中写函数的声明)来实现核心功能。如图
我的设计思路如下:
①用二维的字符数组来储存每次下子的状态。
②每次下完棋子后判断游戏状态,是玩家胜利,电脑胜利,平局,还是继续游戏。
③因为暂时没有接触人工智能方面的知识,所以电脑下棋的操作,我用了随机数来解决。
二.具体实现
为了游戏能有一定的美感以及做一些游戏说明,我做了一个初始菜单和游戏说明。
这里我选择直接用 printf 函数进行打印。这里用do-while结构是为了游戏可以重复进行。
ps:因为这个电脑没有智力哈,所以将电脑胜利作为终极目标,哈哈。
打印的效果如下:
接下来就是编写代码的主体。
①先写主函数
这里我把功能封装到text()中进行实现。(当然可以不用这么做)
②代码的主要功能。
既然我的思路是用二维数组进行记录,那我就先要创建一个二维数组并初始化它。
代码如下。
这里自定义函数,传入数组的首地址,行数以及列数,进行遍历初始化。
这里用i来控制行,用j来控制列,通过双循环来进行初始化,数组中的每个变量都放入空格。
( 既然这里截图了<stdlib.h>和<time.h>就稍微讲一下,这个是实现rand伪随机函数的头文件。)
为了增强代码的复用性,这里用了define来设置行和列。
③玩家下棋
这里用 * 代表玩家下的棋,所以要将*输入进相应的坐标中。因为要贴近人们的习惯,所以左上角的坐标我标成1 1而不是0 0。
下棋的代码有两个需要实现的点,第一个就是下棋的坐标是不是在棋盘内,第二个就是判断玩家下棋的位置是不是已经被下过了。
这里先用if语句来判断玩家输入的坐标是不是在棋盘中。
这里就是如果输入的行和列,均小于等于你棋盘的大小,那么输入有效。
然后就是判断玩家输入的位置是否已经有棋子,因为我初始化是放入空格,所以只需要判断玩家输入的格子是不是空格就可以了。这里用x-1.y-1是因为规则定义左上角为1 1,而数组存储的第一个元素下标是0 0,所以行和列都需减去1。
④电脑下棋
这里用#来代表电脑下的棋。
用以下函数,随机电脑下棋的位置,用unsigned int来强行转换time函数的返回值。
这里rand()%3来保证x,y的生成范围在0-2之间(其实应该写ROW和COL的,写的时候没注意)
那个if函数与上面的玩家判断同理,判断电脑随机的位置有没有棋子,如果没有棋子就输入,有棋子就重新随机,直到随机到随机到的地方是空的。
⑤判断语句
游戏要分输赢,所以要用判断输赢的语句,来终止对局
这里采用穷举法,前面的两个for语句就是将每行每列都判断一下,有没有相同的三个子。
这里返回值用来判断胜负,如果一条线有三个相同的子,那就返回其中的任意的子。
(返回*为玩家赢,返回#则为电脑赢)
下面的两个if分别判断对角线是否有三个相同的子,下面的is_full函数稍后讲,就是用来判断棋盘是否满的(如果满了就返回Q)。如果经过上面的所有判断后都没有满足条件就返回C(也就是继续游戏)
⑥is_full
采用遍历法,将每个格子都遍历一遍,如果没有空格,那说明棋盘满了。
⑦函数拼接
这里的想法是先写一个不中断循环,玩家下棋或者电脑下棋后,判断一下游戏状态(用f来储存状态),然后打印棋盘。如果游戏结束,也就是f!=c的时候就跳出循环。
游戏完成。
⑧代码总览