设计扫雷游戏

最近学习了如何编程最基础的扫雷,算是我接触的第一个项目,虽然没有页面美化,功能上的拓展,但我已经在做成的那一刻已经感觉到很爽了。这是理科才能带来的成就感。

一、整体思路

作为一个项目,即使十分基础,但扫雷依然有它的傲气,就是比任何oj都要更多的代码量和思考量。所以我们必须将整个项目拆解成可执行的步骤,才能在我们脑中成功编译。

即将展开一场以结果为导向的倒推所需条件。

核心部分

扫雷,扫雷,顾名思义有雷,有不是雷的地方,我们才会去“扫”。 

所以我们需要做的事其中最重要的就是,布置雷,然后检测雷的位置。

如何布置雷?

我们形容扫雷的时候,都是形容为9*9的格子里布置着十个雷,而不是81个格子里放十个雷,所以自然而然地,我们想到了二维数组,因为二者是极度接近的。

而扫雷每次开始,所布置的雷都有所不同,这就意味着我们需要用到随机数函数——rand。

注意事项

rand函数实际上是伪随机函数,在我们曾经写猜数字游戏的时候,我们就知道,rand函数实质上是以一个“种子”进行运算得到的随机数,不变种子,就不变随机值。

而rand函数的“种子”,默认为1。

这个时候,我们就需要掏出大杀器——srand函数

程序在调用rand函数的时候,会先调用srand函数,我们通过srand改变rand函数的种子,即达到了每次真随机的目的。

但是seed如果是给定值,只是改变一次种子,这个时候我们就可以用到时间这一恒定改变量,作为我们的seed。

time函数的本质是返回1970年1月1日0分0秒到现在的时间差,但是这个实时变化的值可以让我们得到随机的效果。

于是这样,我们就能得到一个随机种子了。

于是我们可以得到布置雷的思路:(其中srand函数已经在前面使用,避免反复随机,浪费不必要内存资源)

如何检查雷?

前面提到了如何布置雷,那扫雷游戏的获胜逻辑在于,当我们点出一个不是雷的方块时,方块出现的数字告诉我们周围一圈方块存在的雷的个数,让我们得以通过逻辑判断,某几个格子可能存在雷。

之前我们将雷布在了二维数组中,而二维数组最方便的地方在于,我们可以定位!

我先前将雷的值设为了1,那么全加起来就得到了这个方块上该填的数字。

如果这个没想到,也可以用两层循环来代替,这实质上是一样的。

我们应该设置11*11的二维数组,而不是9*9的数组

如何检查雷的思路实质上没有问题,但是我们没有考虑到数组越界。

当我们取到arr[0][0]的时候,程序无法检查arr[-1][0],arr[-1][-1],arr[0][-1],会直接报错。

所以我们可以考虑在外面加一圈(因为arr[8][8]同样会面临越界的问题)

这个时候思路甚至更顺,我们设置雷的地方就是1~9,不用想着数组下标从0开始的问题。

我们应该设置两个二维数组,而不是一个数组从头用到尾

在写着写着,我们觉得不对劲了,扫雷之前都有一些“掩盖”数字的形式,否则还需要我们扫吗?

这个时候,将一个数组变来变去,已经满足不了我们的需求了,甚至还会搞乱我们的思路。

所以我们设置两个二维数组,一个埋雷、检查雷,一个展示出来,到时候用值代替就可以了。

非核心部分

我们将扫雷的核心思路已经理顺了,接下来就是一些界面、功能的设置了。

比如,一个开始界面。

比如难度选择。难度在扫雷游戏里就是多设置一些雷,盘改大一点,只是改几个数字的事情,十分容易。

比如失败界面

当然你完全可以更华丽一些。

二、扫雷游戏的一些拓展

回想一下微软游戏里的扫雷,我们可以留心到一些功能。

1、第一下必不是雷。

这个我们可以通过先输入一遍,然后再随机数埋雷,即在rand函数前先写scanf,然后在后续的循环里再补scanf。

2、排查到周围雷为0个的格子,会将同为数字0的数字,以及一圈有数字的格子同时点亮。

博主的个人想法是,再创建第三个数组,将所有无雷方格的数字填充到这第三个数组中。

然后通过循环的方式来检索相连的0方格(即找行或列相同另一个差1的0方格)。

或者可以检索到0,就把周围一圈的值填充到打印的数组上来,发现上下左右四格里有0的,再把对应的值填上去,直到没有0为止。(感觉可能是这个思路)

3、旗子

在我们没有办法检测鼠标左键/右键的时候,我们可以检测输入的值是0还是1,从而实现放旗子还是检测值的功能,就是用户使用的方式实在感觉有些麻烦......如果是9*9还好,我们可以选择放10个旗子,就检测一次,如果放准了,直接通关。但是我很难想象99*99的那个专家级扫雷,实在有些折磨。

4、用时

可以使用先前提到time函数。time函数记录的实质上是从1970年1月1日到现在的时间差,单位为秒,所以我们可以在游戏开始的时候设置一个变量记录,再设置另一个变量,记录通关/失败的时刻,两者相减就是用时。

5、尽可能避免需要靠运气的死局出现

试想一下,当你玩专家99*99的难度的时候,你辛辛苦苦排的只剩下18个格子(2个3*3),结果发现还有17个雷没有被旗子标出来,这个时候你悲惨地发现,雷的摆放应该是一个3*3空心,一个3*3实心的时候,相信你的心态崩溃了。

这个时候建议增加:

如果发现某个格子周围均为雷,则将周围的某两个雷布置在另一个不为雷的地方。

或者:

不允许将雷相连布置(但这可能就失去游戏的难度了)

这个是开发者需要自己去权衡的。

三、写扫雷游戏有感

扫雷游戏是一个极为基础的游戏,但我发现我的脑子已经不够用了,即使学习到了可以通过函数将代码分块,但函数之间的传输数据时不时让我崩溃,char和int两者同样也让我难绷。

本来以为在已经学习过一遍思路的情况下,我通过三个小时即可复刻。但最后发现还是用了三天,整合起来大约8个小时的样子。

在这期间我学习了调试的技巧,但是这对于我这个新手来说无异于还是无用,因为我的函数分的太多了,导致我自己都不知道调试的地方在哪里了。

代码还是需要多练习,不论是思路难想,还是代码冗长的,多练总没错。

  • 14
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Java设计扫雷游戏代码需要考虑以下几个主要方面: 1. 游戏界面设计:需要使用Java GUI库(如Swing或JavaFX)创建游戏界面。可以使用面板(Panel)和按钮(Button)来显示扫雷游戏的方格,并添加鼠标监听器(MouseListener)来处理用户点击方格的事件。 2. 游戏逻辑设计:需要定义一个二维数组来表示扫雷游戏的方格,使用数字来表示方格的状态(如0表示未翻开,-1表示雷,1到8表示周围雷的数量)。同时需要定义一些逻辑方法,如点击方格时的逻辑、判断游戏胜利或失败的逻辑等。 3. 雷区生成算法:需要实现一个雷区生成算法,使得每一局游戏的雷分布都是随机的。可以使用随机数生成雷的位置,并在周围的方格中递增数字来表示雷的数量。 4. 计时器和计分系统:需要添加计时器和计分系统来记录游戏的时间和玩家的得分。可以使用Java的定时器(Timer)来实现计时功能,并在游戏胜利或失败时计算得分。 5. 图标和声音效果:可以为游戏添加一些图标和声音效果,使得游戏更加生动有趣。可以使用Java的图片库和声音库来加载图标和声音文件,并在特定事件发生时播放。 最后,需要将上述设计思路转化为具体的代码实现。根据个人能力和经验的不同,可能代码量和实现方式会有所差异。可以利用面向对象的编程思想,将游戏的方格、雷区、计时器等封装为各自的类,提高代码的可读性和可维护性。同时,合理地使用注释和命名规范,可以使代码更易理解和调试。 由于篇幅有限,无法在300字内详细给出代码实现的细节,但以上的设计思路可以作为编写Java扫雷游戏代码的指导。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值