前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >扫雷与算法:如何随机化的布雷(一)

扫雷与算法:如何随机化的布雷(一)

作者头像
五分钟学算法
发布2019-06-05 18:11:24
1.2K0
发布2019-06-05 18:11:24
举报
文章被收录于专栏:五分钟学算法五分钟学算法

程序员小吴

读完需要

5

分钟

速读仅需2分钟

这是通过「扫雷与算法」小程序来讲解算法的第一章:如何随机化的进行布雷,主要介绍了三种不那么好的方法,希望通过这些不好的方法能让大家明白第二章要讲解的「洗牌算法」有多牛逼。 补充:「扫雷与算法」小程序会在写完后进行开源,发布在我的 GitHub 上面。

方法一

最想当然的方法就是随机的在二维区间寻找一个点布雷即可,代码如下:

代码语言:javascript
复制
for (var i = 0; i < mineNumber; i++) {
       var row = this.rangeRandom(0, this.rowCount - 1);
       var col = this.rangeRandom(0, this.colCount - 1);
       //使用数字 9 表示该区域有雷
       tmpMineMap[row][col] = 9;
 }

这种实现逻辑的一个弊端就是会在已经布雷的位置再度布雷,进而导致整个区域的布雷数量与要求不符合。

如上图所示,需要布雷的个数为 5 ,但在最后一次的随机布雷过程中只埋了 4 颗雷。

方法二

方法二是对方法一的改善:既然会重复埋雷,那么只需要再埋雷的过程中判断一下该位置是否已经埋雷即可。

  • 如果该位置是空的,那么则布雷,然后进行寻找新的位置布下下一颗雷
  • 如果该位置已经被安置了雷,那么就需要重新生成一个位置来安置

代码如下:

代码语言:javascript
复制
   for (var i = 0; i < mineNumber; i++) {
      //通过死循环来实现不停的寻找,直到安置好雷
      while (true) {
        var row = this.rangeRandom(0, this.rowCount - 1);
        var col = this.rangeRandom(0, this.colCount - 1);
        //用数字 9 表示该区域有雷,如果该位置没有布雷,那么则放置
        if (tmpMineMap[row][col] != 9) {
           tmpMineMap[row][col] = 9;
           //跳出循环
           break;
        }
      }
    }

使用效果如下:

效果貌似挺好的,但小伙伴们可能已经注意到了,上面的代码中有一段 死循环 代码,这就意味着如果棋盘很大,雷区很多,并且你的运气还不够好的话,那么就有可能一直在执行这段 死循环 代码,进而导致程序的卡死崩溃。

虽然没有卡死,但执行时间很久,再多的话就会出问题

方法三

第三种方法是先将雷布置在最前面,然后再不停的打乱。

实现代码如下:

代码语言:javascript
复制
//先按顺序排列
for (var i = 0; i < mineNumber; i++) {
    var row = parseInt(i / this.colCount);
    var col = i % this.colCount;
    //使用数字 9 表示该区域有雷
    tmpMineMap[row][col] = 9;
}

//定义交换的次数,次数越多越混乱随机
var swapTime = 100;
for (var i = 0; i < swapTime; i++) {
    //随机位置1
    var row1 = this.rangeRandom(0, this.rowCount - 1);
    var col1 = this.rangeRandom(0, this.colCount - 1);
    //随机位置2
    var row2 = this.rangeRandom(0, this.rowCount - 1);
    var col2 = this.rangeRandom(0, this.colCount - 1);
    //交换两个位置
    var temp = tmpMineMap[row1][col1];
    tmpMineMap[row1][col1] = tmpMineMap[row2][col2];
    tmpMineMap[row2][col2] = temp;
}

这种方法的一个弊端就是对于 swapTime 的依赖程度很高,如果设置的交互次数少了,大部分雷都还是按照一开始的顺序安置,都在最前面的位置,全部的雷并不是随机排放。

最重要的一点是:每个位置安置雷的概率并不是等可能的,也就意味着它不能做到随机化。

我尝试过在小程序上进行概率模拟,搞了半天也没弄好,每次都会卡死,后续发现能优化继续模拟出概率来的话再补上。

总结

在大部分情况下,方法二方法三 是可以满足我们随机化处理的过程的,但方法二有可能运行卡死崩溃,方法三中每个位置安置雷的概率并不是等可能的。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-06-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 五分钟学算法 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 方法一
  • 方法二
  • 方法三
  • 总结
相关产品与服务
云开发 CloudBase
云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档