掃雷與算法:如何隨機化的布雷(一)


這是通過「掃雷與算法」小程序來講解算法的第一章:如何隨機化的進行布雷,主要介紹了三種不那么好的方法,希望通過這些不好的方法能讓大家明白第二章要講解的「洗牌算法」有多牛逼。

補充:「掃雷與算法」小程序會在寫完后進行開源,發布在我的 GitHub 上面。

方法一

最想當然的方法就是隨機的在二維區間尋找一個點布雷即可,代碼如下:

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 顆雷。

方法二

方法二是對方法一的改善:既然會重復埋雷,那么只需要再埋雷的過程中判斷一下該位置是否已經埋雷即可。

  • 如果該位置是空的,那么則布雷,然后進行尋找新的位置布下下一顆雷
  • 如果該位置已經被安置了雷,那么就需要重新生成一個位置來安置

代碼如下:

   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;
        }
      }
    }

使用效果如下:

效果貌似挺好的,但小伙伴們可能已經注意到了,上面的代碼中有一段 死循環 代碼,這就意味着如果棋盤很大,雷區很多,並且你的運氣還不夠好的話,那么就有可能一直在執行這段 死循環 代碼,進而導致程序的卡死崩潰。

雖然沒有卡死,但執行時間很久雖然沒有卡死,但執行時間很久

方法三

第三種方法是先將雷布置在最前面,然后再不停的打亂。

實現代碼如下:

//先按順序排列
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 的依賴程度很高,如果設置的交互次數少了,大部分雷都還是按照一開始的順序安置,都在最前面的位置,全部的雷並不是隨機排放。

最重要的一點是:每個位置安置雷的概率並不是等可能的,也就意味着它不能做到隨機化。

我嘗試過在小程序上進行概率模擬,但每次都會卡死了,后續發現能優化繼續模擬出概率來的話再補上。

總結

在大部分情況下,方法二方法三 是可以滿足我們隨機化處理的過程的,但方法二有可能運行卡死崩潰,方法三中每個位置安置雷的概率並不是等可能的。

❤️ 看完三件事:

如果你覺得這篇內容對你挺有啟發,我想邀請你幫我三個忙:

  • 點贊,讓更多的人也能看到這篇內容(收藏不點贊,都是耍流氓 -_-)
  • 關注我和專欄,讓我們成為長期關系
  • 關注公眾號「五分鍾學算法」,第一時間閱讀最新的算法文章,公眾號后台回復 1024 送你 50 本 算法編程書籍。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM