三子棋又称黑白棋,是一种经典的棋类小游戏,玩法简单。在日常生活中,我们可以在纸上随手画出一个井字格,然后就可以开始这类小游戏。那么在学习了C语言的二维数组之后,我们也可以通过代码来实现这样一个简单经典的小游戏。
对于采用C语言实现一个简单的小程序,通常包含三个文件(两个源文件和一个头文件)来执行,即test.c、game.h、game.c。三个不同的文件分别用于实现自己的作用,以保证整个程序井井有条。其中,
test.c——用于测试和实现整个游戏的基本流程;
game.h——用于包含整个程序中用到的头文件以及声明所需要使用的变量、宏和函数等;
game.c——用于实现游戏的各像功能的函数的具体内容。
游戏思路
二维数组存储信息 → 初始化信息 → 打印棋盘 → 下棋 → 判断输赢 → 循环直至结束。
具体的内容与操作将在后面一一展开。
0 游戏的基本流程
对于一个游戏的实现,首先要有一个初始的互动选择界面,来执行游戏的启动与否。这个初始界面的实现可以通过printf()函数打印出相应的信息,通过switch……case实现玩家的选择,大致如下:
在玩家选择了PLAY之后,就会调用game()函数,即游戏启动。game()函数中的主体内容,也就是我们上面讲的一个游戏的基本思路,如下:
接下来将依照这个思路,逐步具体的描述其中的内容。
1 二维数组存储信息
因为三子棋是在井字格中执行的,那么对应的每个格子中的信息就可以采用二维数组的形式来存储。对于三子棋游戏中信息的存储只需要一个3*3的二维数组即可,如下:
在实际创建时,采用的事先在game.h头文件中定义的两个宏ROW 和 COL,而不是直接采用具体的数字,这样是位了方便后续的更改时,只需要对头文件中的定义宏进行相应的修改即可。
这里创建的是一个5*5的二维数组,主要是位后续输赢的判断预留空间,具体在后面会讲解。
2 数组信息的初始化
对于创建好的二维数组,需要先对其进行初始化,也就是对应游戏开始时的空白状态。因此,采用两个简单的循环来实现将二维数组的每个位置信息初始化位空格符号——‘ ’,如下:
3 打印棋盘
数组只是用来存储信息,在实际的游戏中,需要将获得的信息打印出来给玩家一个直观的感受。此外,为了让输出的信息有一个更明显的区分度,也就是实现一个井字格的棋盘形式,可以通过printf()函数来打印一些有用的符号格式。总的来说,就是结合数据的信息和符号格式的棋盘一并输出,如下:
4 玩家下棋
玩家下棋实际上就是让玩家输入所选择的位置坐标,以对应二维数组中的位置,并用相应的符号来替代原有的空格。其中,需要注意的是,玩家的输入是有限制的,不能重复输入以及越界输入,如下:
同时,在每次输入之后都需要重新打印棋盘以更新信息。
5 判断游戏状态
在每一步棋走完之后,我们需要判断游戏是否已经结束,从而进行下一步的操作。游戏的状态无非就是以下几种:游戏继续、玩家获胜、电脑获胜、平局。在第一小节的基本流程中,已经给出了判断游戏状态的循环过程,其中用三个字符分别代表三种状态,即:
‘c’——游戏继续;
‘*’——玩家获胜;
‘#’——电脑获胜;
通过采用一个判断函数来返回不同的字符值,依次来判断游戏的状态。
首先判断输赢——对数组中的3*3有效信息区域依次进行读取,如果不为‘ ’,则进行输赢判断。判断的方法是与所在位置的上下、左右、以及对角所组成的直线的三个信息是否相等,如果存在相等的情况,则返回该位置的符号信息,以便后续的判断。
为了方便边界位置的判断能够合法的读取到信息,所以设置初始的存储信息的数组大小位5*5,而非3*3。
其次判断平局与继续——如果没有分出胜负,那么游戏仍然存在两种状态,平局和继续。同样,对数组中的3*3有效信息区域依次进行读取,如果还存在‘ ’字符,则游戏继续,返回‘C’;否则,游戏平局,返回除此之外的任意字符,如‘Q’。
到这里,整个游戏的基本内容都已阐述完毕,简单的试玩过程如下:
6 总结
总的来说,整个代码基本实现了三子棋游戏的过程,对于玩家 VS 玩家,基本上没有太大的问题;但对于玩家 VS 电脑,此代码采用的是生成随机数的方式,其下棋步骤完全是随机的,缺乏只能性,有待改进。除此之外,在这个游戏的基础上,可以扩大棋盘并更改判断规则,进一步衍生出玩家 VS 玩家的五子棋小程序。