兴趣使然(呜呜呜,这篇博客又臭又长,一点都不契合我写博客的初衷)这篇博客很长,本来准备分几篇来写,但感觉会浪费看博客的人的时间,也不方便,所以还是用一篇大长文写完这个游戏。
test.c ------ 游戏的整个逻辑运行
以下两项是游戏模块。
game.h ------ 游戏相关的函数的声明
game.c ------ 游戏相关的函数的实现
先创建三个文件:两份源文件和一份头文件。三份文件创建顺序先后顺序可变,具体流程如下:
创建两件源文件,名称改正及流程如图
如上图所示,创建game.c与源.c文件,注意源.c后缀必须是.c而非其他,后缀绝对不可以是.cpp。否则,相信我,运行时绝对会后悔的(别问,问就是......你懂的)。
同样的,用同样的方式创建头文件,可以用game.h用作文件名。
先在主函数里用do while结构,创建游戏中常见的“菜单”,以及选择,如图
但我们需要知道选择后会呈现什么,比如“退出游戏”或者“选择错误”之类的,接下来的代码需要使用Switch函数(不确定是否可以使用其他函数,我只是C语言小白,暂时也不清楚),具体如图
因为扫雷游戏是需要使用函数的,所以“printf("开始扫雷\n");”需要换成一个函数,可以称为game,这个game函数才是完成扫雷游戏的整个过程。扫雷游戏分很多种,我说的这种是最简单的一种也就是9*9,共81格,我倾向于埋十个雷,也可以埋别的数量的雷,看个人想法。根据扫雷游戏的游戏规则,埋雷地点与相应提示都需要设置,并为了随机性,会使用时刻变化的时间(time)函数(我不确定可不可以这么叫,我上一篇博客曾为了做数字游戏用到这个东西)。
如果要记录布置好的雷的信息,需要使用二维数组(这里暂时先试用9*9类型)
如果想知道某一坐标的信息,便需要获知周边雷的分布,以进行整合。但是,根据扫雷游戏的规则,随便放置会造成困惑与悖论。如果某一坐标周围只有一个雷,则此坐标显示1(之前是用1来表示雷,但又只能用1或2来提供信息),但很明显,与规则冲突,造成歧义,所以需要找到另一种更精确有效的方法来设置(比如用*号来表示雷啥的)。
*---------表示雷 #----------不是雷 数字-------------周围雷的个数
另外,因为如果用的数多于两位数字,会造成信息量过大的问题,不好处理,所以默认只用1和2,但仍然可以用0来表示不是雷(也就是周围以及自身没有雷)
我们可以使用两个不同的数组,一个用于存放雷的信息,另一个则存放排查出的雷的信息,两个数组互不干扰,打印出来会自由得多。
统计坐标时会有越界情况,如果统计9*9的边缘坐标的周围,则可能会有3或5个越界,不被囊括进9*9共81格子中。为了解决这一问题,我们可以让这个数组大一圈,让它成为“11*11”。但是这个最外圈什么都不存,就是为了防止越界。
放数组char mine[][],括号里面写什么呢?9?还是11?好像都不是很方便。事实上,我们可以使用头文件game.h解决这一问题(记得在源文件中包含自己的头文件,不用<>,用"",英文形式的,懂的都懂)
其中一个数组中没有雷的地方用“0” ,布置雷的则放的“1”
另一个数组中没有被排查过的全部放“*”
我们需要初始化棋盘,图中注释会解释那些步骤是初始化。
col与row是形参
两个数组需要用代码实现,可以用i与y,用两个for循环。
效果如下图
但如果用的是‘0’而非set,自由度将会降低,会把show数组写死,所以如图,替换set并在源.c中加入‘0’,‘*’元素。
初始化棋盘已经完成,紧接着是布置雷,但首先我们要先验证之前的代码对不对,如果代码正确无误可以正常运行,则可以继续之后的操作了。使用DisplayBoard打印棋盘(有符号的是9*9,外围是无符号的,应该后续会给数字当坐标轴用),并对其在game.h进行声明,而且,外围与内侧要分开打印,如图:
然后打印外围
从图中看,似乎和我们想要的效果差了不少。首先,<号应该改为<=号,其次,某些数应该从1开始,所以,更正如图:
还有,非常非常重要的一点,既然已经出现打印页面,一定一定在看完后及时关掉,否则你会收获下面这段话:
严重性 代码 说明 项目 文件 行 禁止显示状态 详细信息
错误 LNK1168 无法打开 D:\代码练习2024-2-2\CSDN-picture-扫雷游戏\x64\Debug\CSDN-picture-扫雷游戏.exe 进行写入 CSDN-picture-扫雷游戏 D:\代码练习2024-2-2\CSDN-picture-扫雷游戏\CSDN-picture-扫雷游戏\LINK 1
先解释一下上面这句话的触发条件,在你已经打印过后,但没有关闭打印界面,然后你对你的代码进行修改(不管改的对不对),之后你再次打印(刚刚已经说过了,打印界面没有关闭的情况下),那么,恭喜你,喜提上述错误。(别问我怎么知道的,问就是......你懂的,人都会犯错)
好了,回归正题,为了美观,可以设置扫雷提示(就一行字加几个横,想要几个横就加几个横,自己高兴就行,看着高级而已)
DisplayBoard(char board[ROWS][COLS], int row, int col)
{
int i = 0;
printf("------- 扫雷 -------\n");
//打印列号
for (i = 0; i <=row; i++)
{
printf("%d ", i);
}
printf("\n");
这句话的位置如上述所示(应该很清楚了吧)。
而我们有两个数组要打印,所以首先打印出另一个代码(仅列一步,其他的发完这张图再说)
但我们实际上不会打印mine数组,甚至
//DisplayBoard(show, ROW, COL);
//DisplayBoard(mine, ROW, COL);
这两行代码我们都要屏蔽掉,但为什么还要写这串代码?前文说了,我们需要检验,没错,这两行代码只是为了让我们知道自己的代码是否写错,可以尽量直观地展现我们代码所打印出来的东西
最后,布置雷,就快要结束啦。
为了自由(感觉美里美气的咋回事?突然想起了某个自由国度阿美莉卡)布置雷的数量用别的方式代替(比如用count),比如我要布置10个雷
使用while循环,定下坐标范围
在源.c中调用srand(game.c中含rand),使用time函数。具体代码及打印结果如图。
然后排查雷,我们常用FindMine,在mine数组中观察。并且,排查雷其实需要多次排查,所以又需要用到while循环(如果友友有别的想法也可以用别的方法)。所以,输入坐标,但又得保证坐标属于数组内,而不是直接飞到外星球,可以使用if语句来界定范围(不要乱跑,if语句在while循环内),if语句内还有if语句(感觉有套娃的嫌疑,是我的错觉吗)。一个坐标,周围有八个坐标,我们需要统计这八个坐标的数据。
字符‘0’ ------ 48 字符‘1’ ------ 49 字符‘2’ ------ 50
以上是相对应的ASCII码值
让选中的坐标周围的8个坐标的相对应的字符值减去中间的值,再相加。代码如下
OK,以上就是所有的内容了(可以稍作改变规则,代码只用做少量修改)
以下,是完整代码截图
嘿嘿,新的一年,祝大家健康快乐!(诶,好像祝福的晚了点)