C语言制作扫雷小游戏(简易版)

前言

扫雷,这个小游戏相信大家应该不会很陌生吧,今天我们就来用C语言制作一个简易版的扫雷游戏,主要运用的是C语言二维数组的知识点和应用。

初步设计思路

在制作扫雷之前,我们要先理一下制作的初步思路。

这里我们制作一个棋盘大小为9*9的扫雷,里面放上10个雷,棋盘就用二维数组来表示。但是,在我们布置好雷之后要将棋盘打印出来,并且不能让雷暴露,这里如果只用一个二维数组表示的话很困难,所以可以使用两个二维数组,一个用来布置雷,另一个将雷隐藏并打印棋盘给玩家看。

在扫雷游戏中,没有踩到雷时会显示周围8个格子中的雷的个数,这里我们设置的棋盘是9*9,踩在边界处时检测周围8个格子会超出数组的范围,所以我们在定义数组时,可以将行与列各+2,也就是创建11*11的数组,但打印棋盘时纸打印中间9*9的部分。

为了让代码看起来更美观,我们可以用三个代码块来实现扫雷小游戏,分别是test.c(测试)、game.c()(游戏主体)、game.h(头文件)。因为在test.c和game.c中会同时使用一些全局变量或函数声明,所以我们把这些都放在game.h中,在test.c和game.c中包含game.h。

主函数

现在就可以开始编写程序了,首先是主函数,在主函数中,我们定义一个名为test的函数来调用游戏

菜单

在函数test中定义一个名为menu的函数用来打印菜单,然后在函数menu中发挥想象力制作一个好康的菜单。之后在函数test中调用switch语句来对玩家的选项做出反馈,在switch语句中定义一个名为game的函数,当玩家要玩游戏时,便通过它来进入游戏。

游戏主体设计思路

在函数game中,要编写出游戏的主体,这里可以将游戏分为4个模块来实现,分别是:初始化棋盘、打印棋盘、布置雷、检测雷。

因为在最开始设计时的思路就是两个棋盘,所以我们要先创建两个二维数组。为了后面编写代码时可以减少代码量,在game.h中用宏定义来控制棋盘

初始化棋盘

首先是初始化棋盘,数组mine是用来布置雷的,为了后面排查雷的代码更方便编写,这里将数组mine中所有元素初始化为字符'0';数组show是用来给玩家看的,将其初始化为字符'*',这里为了减少代码量,在函数声明时就可以将两个数组对应的字符放进去。

打印棋盘

其次是打印棋盘,这里要打印的棋盘是9*9大小的,所以将ROW和COL放进函数中,而不是ROWS和COLS(头文件中宏定义的常量),不过,放进函数中的数组还是要11*11的,因为这样初始化后的数组可以直接在函数中使用,不需要进行下标计算,打印时只需要打印从[1][1]到[9][9]就可以了,这也是将ROW和COL放进函数中的原因。这里为了让棋盘看上去更美观,我加了一些符号,老铁们可以自行发挥。

布置雷

然后是布置雷,这里用随机数来布置雷,范围是1~9,代码中row(col)的值是9,所以对其取余后的值就是0~8,再+1,这样就满足要求了。为了避免精度丢失的问题,不要忘了强制转换为unsigned int类型。

在布置雷的函数体中,while循环的条件设置为剩下雷的数量count,每布置一个雷就-1,这样将所有的雷都布置好后循环就结束了。为了后面排查雷更方便一点,这里将是雷的元素变为字符'1',在布置好之后可以调用打印棋盘的函数来看一下效果。

排查雷

最后就是最难的部分——排查雷。因为是将玩家输入的坐标放入数组mine中进行比较,并通过数组show打印出来,所以在定义函数find_mine时要将两个数组都放进去。通过if-else语句的嵌套来实现玩家输入坐标后的几种反馈,在玩家失败后将布置雷的棋盘打印出来,让玩家死的明白。

其中,当玩家没有踩到雷时,要对输入坐标周围8个格子的排查,将周围的雷的数量替换掉输入的坐标所代表的元素('0')。这里可以定义一个函数get_mine_count用来统计周围的雷的数量,将其返回值赋给变量ret。

通过对照ASCII表可以知道,字符'0'~'9'减去字符'0'所得到的值就是对应的数字。比如,字符'0'在ASCII表中的值是48,字符'1'在ASCII表中的值是49,,那么'1'减去'0'的值就是1,其他的也是同理。那么同理,代码中将输入坐标周围的8个元素加起来,再减去8*'0',所得到的值就是周围的雷的数量,将其赋值给ret,然后让ret加上字符'0',结果就是数字所对应的字符,用它替换掉输入的坐标在数组show中所代表的元素,打印出来的效果就是这个坐标周围有几个雷。

总代码

到此位置,程序的代码主体就完成了,剩下的就是拼接和补充。下面是总代码:

其实这篇文章中的代码还有很多值得优化的地方,比如在真正的扫雷游戏中,如果选中的位置周围没有雷,讲道理来说会扩散开(如下图);还有在统计输入坐标周围的雷的数量时,本文中所使用的代码太过繁琐,理论上应该可以通过递归来实现,还有诸多等等。这些在后期实力提高之后我会逐步优化(毕竟俺也是小白)

最后感谢大家的支持,关于本篇文章有任何疑问或值得优化的地方,欢迎大家在评论区留言或讨论,也可以私信提出,祝愿大家在提高实力的同时保持发量的茂密!!!

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

拒绝脱发从我做起

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值