首先,一个游戏的制作,必须由大化小,分步完成。
当我们想要制作三子棋小游戏时,必须先搞清楚这个小游戏的逻辑和原理。
三子棋是黑白棋的一种。三子棋是一种民间传统游戏,又叫九宫棋、圈圈叉叉、一条龙、井字棋等。将正方形对角线连起来,相对两边依次摆上三个双方棋子,只要将自己的三个棋子走成一条线,对方就算输了。但是,有很多时候会出现和棋的情况。
因此,怎么来实现这个游戏呢?
显而易见,制作游戏我们需要引用许多库函数,定义许多函数,每个部分的代码实现不同的功能。如果将所有代码写在一个文件中,首先,在我们想知道用了哪些函数,每部分函数对应什么样的头文件时可能就会出现不便的情况。为了减少这些麻烦,我们选择将整个代码规范化,条理化。
因此,我们来进行创建:
- 一个专门存放所有函数声明的文件,将其命名为game.h(头文件)
- 一个来编写游戏的实现逻辑,将其命名为game.c(源文件)
- 一个来编写游戏的测试逻辑,将其命名为test.c(源文件)
好的,现在,就开始来编写程序。
我们的思路为
- 游戏菜单
- 游戏主体函数
- 游戏的实现
游戏的菜单
首先,进入一个游戏,我们首先看到的就是游戏主界面,也就是菜单,一般来说,菜单应该有以下几个选项:
- 开始游戏
- 退出游戏
- 非法输入
因此,我们就需要创建这样一个menu()函数来实现这样的功能,代码如下:
运行结果如下:
当我们选择进入游戏,也就进入了游戏主要代码的编写。
游戏主体函数
- 棋盘初始化
- 棋盘展现
- 玩家下棋
- 电脑自动下棋
- 判断胜负
1.棋盘初始化
首先,我们需要创建一个棋盘,由于棋盘是九宫格,因此我们使用数组来进行创建(由于这里是较为简单的三子棋,因此我们创建数组时可以直接来打印出3*3的数组,但由于我们想让这个游戏的适用面更加广泛,改动时较为容易,我们使用一个函数可以输入自己想要打印的棋盘的大小)
在test.c里创建如下:
char board[ROW][COL] = { 0 };//数组的内容应该是全部空格
InitBoard(board, ROW, COL);//初始化棋牌
在game.c里创建如下:
2.棋盘展现
我们将创建好的棋盘打印出来:
在test.c创建:
DisplayBoard(board, ROW, COL);//打印棋盘
在game.c创建:
3.玩家下棋
为了完成这一功能,我们需要注意以下几点:
- 接收玩家所输入的坐标
- 判断玩家所输入的坐标所在是否已有落子
- 将玩家的棋子落入对应地
代码实现:
在test.c创建:
在game.c创建:
运行结果如下:
4.电脑下棋
这里,由于游戏实现的智能化水平有限,电脑在下棋时,采用随机下棋的方式,因此坐标随机不确定,那么,如何来创建随机坐标呢?我们使用一个称为时间戳的函数。
我们需要调用以下头文件:
<stdlib.h>
<time.h>
同时,我们还需要使用:
srand((unsigned int)time(NULL)); 来进行初始化
x = rand() % row;
y = rand() % col; 来进行创建坐标的随机数
当然,与玩家下棋相一致,我们也需要判断电脑所下的坐标是否被占用,以及将棋子落下。
代码如下,我们在test.c里创建:
同时,在game.c里创建:
运行结果如下:
5.判断胜负
在我们下棋的过程中,由于规则的特殊性,我们需要在玩家和电脑下的每一步后都对比赛的结果进行判断,确保程序的逻辑正确性。
在这里,我们使用Is_win()函数来实现这一功能。
在这一函数中,我们需要实现以下几个逻辑:
要返回四种不同的状态
玩家赢 --> 返回'*'
电脑赢 --> 返回'#'
平局 --> 返回'Q'
游戏继续 --> 返回'C'
首先我们要确立判断函数再整个游戏主体中的位置和作用
我们在test,c中创建的逻辑如下:
同时,我们在实现Is_win()这一函数时,需要注意以下几点:
- 判断行
- 判断列
- 判断对角线
- 判断棋盘是否已经放满 -- > 确认游戏是否继续(需要一个Is_full()函数来实现这一功能
我们在game.c里创建is_full()的实现逻辑如下:
接下来是is_win()函数的实现:
注:这里所有创建的函数,我们都会在game.h 里进行声明
游戏的实现
当我们进行完上述步骤买就可以运行代码了:
到这里,三子棋这个小游戏的代码就实现完成了,快去试试吧!