Web版扫雷开发小记(3)

前篇:

web版扫雷开发小记(1)
web版扫雷开发小记(2)
web版扫雷开发小记(3)
web版扫雷开发小记(4)

完整代码:我的Github

在线试玩:点击

上一节完成了数字的显示,这次主要完成一个功能,即当当前方块周围没有雷(roundMines为0)时,自动挖开周边的雷。

思路分析

首先先弄明白扫雷中的这一游戏规则。

当用户点击到一个方块,而它的周围没有雷时,就会挖开它周围的方块,而当它的周边共计8个方块中,有一个方块也是周围没有雷的话,又会继续挖开这个方块周围的方块。如下图:


空的方块

很容易想到,这是一个递归的思想,设计一个cleanArea()函数,遍历某方块周围的八个方块,当其中一个方块的roundMines属性为0时,则递归调用cleanArea()函数,直到该区域方块都被挖开为止。

(这里的实现搜罗了下其他人的想法,还可以用BFS实现,毕竟递归太低效了。不过我算法不咋样,还是先用着递归吧,有时间了来研究研究BFS)

函数实现

cleanArea()函数接收两个参数,当前点击方块的列columns和行rows

通过两层for 循环嵌套,遍历当前方块周边的8个方块,将周边方块的行列数push到定义的一个数组中,然后通过读取该数组的值,对方块进行clearRect()

添加isClicked属性

然而按照这个思路实现起来有诸多问题,最主要的一个问题就是循环会遍历到该方块本身。

例如,当前方块行为12,列为15,它的roundMines为0,那么函数就会遍历周边的方块,当我遍历到比如行11,列15的方块时,发现它的roundMines为0,那么递归函数调用,以行11,列15为当前方块,开始遍历,其他方块暂且不论,当检查到行12,列15的方块时(是的两个方块互为周边块)。发现也是0,好,又是一个递归调用。于是两个递归互相调用,永无止境……

这是我最开始写的:

function cleanArea(columns, rows, mineObject) {
    for (var k = -1; k < 2; k++) {
        for (var l = -1; l < 2; l++) {
            if (columns + l > -1 && rows + k > -1 && columns + l < 30 && rows + k < 16 ) {
                mineObject.cleanArr.push({
                    columns: columns + l,
                    rows: rows + k
                });
                if (mineObject.mines[columns + l][rows + k].roundMines === 0) {
                    mineObject.cleanArea(columns + l, rows + k, mineObject);
                }
            }
        }
    }
}

这个问题解决起来也简单,添加一个条件判断语句就好。例如这里两个范围-1到1的变量l和k,代表行和列的变化,那么当两个变量都为0时,就代表是当前块。

但是当我添加一个(l!==0)&&(k!==0)的条件时,程序每次在其中一个变量为0时就会判断为true。百思不得其解,自认这个判断写得也没有问题,搜索了一下大家也都是这么写得。没办法,只有搁置。

同时也感谢这个bug,让我思考到了更为便捷且语义更加明确的方法:

在之前定义的Mineblock类中,再添加一个isClicked属性,初始值为false。对于每个方块,当被点击到时isClicked更改为true。对于上述方法也同样如此,当我在将它push到定义的数组中时,同时更改isClicked属性。

那么在我判断中,我只需要加入isClicked===false的判断,就可以规避掉所有或被点击或被挖开的方块。

代码如下:

function cleanArea(columns, rows, mineObject) {
    for (var k = -1; k < 2; k++) {
        for (var l = -1; l < 2; l++) {
            if (columns + l > -1 && rows + k > -1 && columns + l < 30 && rows + k < 16 && mineObject.mines[columns + l][rows + k].isClicked === false) {
                mineObject.cleanArr.push({
                    columns: columns + l,
                    rows: rows + k
                });
                mineObject.mines[columns + l][rows + k].isClicked = true;
                if (mineObject.mines[columns + l][rows + k].roundMines === 0) {
                    mineObject.cleanArea(columns + l, rows + k, mineObject);
                }
            }
        }
    }
}

效果可以看上面的截图

添加游戏成功条件

游戏失败的条件很简单,点击到一个雷方块时就结束。游戏成功稍微麻烦一点,概念上很简单,所有不是雷的方块都被点开时游戏就成功了。但是怎么做呢?

最开始的想法很蠢,每次点击或者挖开一个方块时,都调用一个函数。这个函数的作用是什么呢?遍历当前所有isMined===false的对象,查看它的isClicked属性是否等于true。若所有方块都已经被挖开,那么游戏成功。

听起来思路其实很清晰,但这个方法不用说,太不节约了。

最后决定给MineSweeping对象添加一个属性count,作用很简单,每点开或者挖开一个方块时,count数都+1,当count数达到480-99(高级扫雷)时,即游戏成功。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,898评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,401评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,058评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,539评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,382评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,319评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,706评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,370评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,664评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,715评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,476评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,326评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,730评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,003评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,275评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,683评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,877评论 2 335

推荐阅读更多精彩内容

  • 目录:Web扫雷开发小记(1)Web扫雷开发小记(2)Web扫雷开发小记(3) 其实在完成上篇的功能之后,一个扫雷...
    franose阅读 509评论 0 0
  • 扫雷是我第一个取得显著成就的游戏,但一直没有机会写一篇关于它的文章。前不久,一家游戏媒体约我就扫雷做个采访,列举了...
    深加思考阅读 2,731评论 4 5
  • 目录Web扫雷开发小记(2)Web扫雷开发小记(3)Web扫雷开发小记(4) 刚好今天做阿里前端笔试问到扫雷了,那...
    franose阅读 894评论 0 0
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,127评论 25 707
  • 如果有一天,你的岗位被人替代了,请不要奇怪,因为你还在过年,而人家已经在上班了…… 如果有一天,你的客户被人抢走了...
    帝星微寒阅读 377评论 0 0