自動掃雷 分析

2021-09-07 22:06:27 字數 3352 閱讀 1338

一.「影響區域」劃定

如上圖,假如這個局面擺在我們的面前了。只有紅線圈定的內部區域裡面的未被挖開的方塊才可能被當前局面直接影響。只有在紅線圈定區域內的方塊確定後,其他區域的未被挖開的方塊含有的雷數才能由雷的總數做減法求得。所以我們應該先盡可能的確定紅色區域內部雷的分布情況。

二.算式推理技術

對影響區域每一位置都賦予乙個符號名,或叫變數名,進行「算式推理」。對於下圖的局面(called by 局面1):

根據每個數字可以列出乙個算式,總共得到3個算式:

a+b=1;

e+d=1;

a+b+c+d+e=2; 約束條件是a,b,c,d,e,f取0-1值。

對於下面的這個圖(局面2):

根據每個數字可以列出乙個算式,總共得到4個算式:

a+b=2;

a+b+c=2;

d+e=2;

b+c+d+e+f=3;約束條件是a,b,c,d,e,f取0-1值。

「算式推理」指得是由原始的算式集合s0(這裡是4個算式)盡可能多的推出算式中符號的確定取值。具體的演算法如下:

1.             若算式集合s0中含有類似局面2中a+b=2 這樣的算式,即符號數目和等號右邊的數字相等,那麼可以確定每個符號的值為1,然後把確定的符號的值給s0中的其他算式中的該符號賦值,如此還可能出現類似c=0這樣的算式(對局面2帶入a=1,b=1),即左邊一些符號相加後得0,那麼也可以確定此類算式中每個符號取值0。不斷尋找集合s0中的所有類似上面兩種情況的算式,確定一些符號的取值,直到集合s0中沒有類似的算式。此時得到的算式集合稱作s0』。局面1,s0最後化簡得到的s0』集合為:

a+b=1;

e+d=1;

a+b+c+d+e=2;約束條件是a,b,c,d,e,f取0-1值。

局面化簡後得到的是a=1,b=1,c=0,d=1,e=1,f=0。這兩個例子舉得不好,第乙個沒有得到化簡,第二個全化簡完了。

2.             對s0』中的每兩個式子之間做檢測,若其中某個式子左邊的符號是另乙個式子左邊符號的子集,那麼這連個式子相減得到乙個新的式子,並加入s0』。

如,局面1通過這個過程可以得到:

a+b=1;

d+e=1;

a+b+c+d+e=2;

c+d+e=1;

a+b+c=1;

把s0』看做s0,轉到第一步繼續計算。直到集合不再能推出符號的確定值,也不能產生新的算式為止。

這個演算法最終得到的是一些符號的確定取值,還有一些不能「消融」的式子集合,把它叫做集合st。

下面給出局面2完整的演算過程:

1.a+b=1;e+d=1;a+b+c+d+e=2;(步驟一結果)

2.a+b=1;d+e=1;a+b+c+d+e=2;c+d+e=1;a+b+c=1;(步驟二結果)

3. a+b=1;d+e=1;a+b+c+d+e=2;c+d+e=1;a+b+c=1;(

步驟一結果)

4.a+b=1;d+e=1;a+b+c+d+e=2;c+d+e=1;a+b+c=1;c=0;( 步驟一結果,每次只要兩兩檢測上一輪新產生的算式和原來的算式就可以,而且有重複的話只留乙個就可以)

5.a+b=1;d+e=1;a+b+d+e=2;c=0(步驟一結果,同樣也要去重)

6.a+b=1;d+e=1;c=0(終止)

算式推理應該是線性代數裡面的線性方程的求解或者數論裡面的不定方程求解,肯定還有理論和實現上的優化,由於數學基礎較差,只能做到這裡了。

三,列舉手段

經過「算式推理的過程」,現在我們手頭有一些符號確定了,還有一些符號不確定但是他們之間的約束集合st是有的。接下來對於不確定的符號我們只能算出他們有雷的概率了。

為了程式設計實現的方便,我們可以採取回溯+列舉這種手段。假設還有a1,a2,…,an 這些符號還沒確定,b1,b2,…,bm這些符號確定了。我們採用遞迴實現列舉a1,…,an取0-1的每種可能,中間結合不確定符號的約束關係做剪枝。最終列舉出來的可能情況假設如下:

1110101011010….101   91

1010100101010….100   98

1111100010100….111   91

1000011101010….101   89

前面那個01陣是列舉結果,第i行j列表示第i個列舉中第j個未知符號是否有雷,最後一列是用雷的總數減去紅線區域內部的類的數目得到的紅線外部的雷的數目。假設總共k個列舉結果,根據列舉結果我們可以統計出每個符號有雷的概率---用該符號位置是1的列舉結果數目除以總的列舉結果數目。

至於紅線外部的方塊,他們的有雷的概率都是一樣的。我們只能知道該區域含有雷的數目,至於他們怎麼分布那就隨便了。這個概率的計算可以考慮全概率公式。設列舉結果有100個91,110個90,106個89,105個93,紅線外部有m個方塊,我認為可以如下計算紅線外部每個方塊有雷的概率:

100+106+110+105=421

p=(100/421)*(91/m)+(110/421)*(90/m)+(106/421)*(89/m)+(105/421)*(93/m)

經過」影響區域」劃定,「算式推理」,列舉手段,我們能夠精確確定沒挖掘方塊中的一些是否有雷,以及不能確定的方塊的有雷概率。我們把確定沒雷的都挖開,再使用上面的手段,再挖雷,直到有乙個局面我們不能精確確定任何乙個方塊,只有概率可以參考,那就只能選個概率小的碰運氣了。

至於程式實現,目前沒時間。唯一擔心的就是那個列舉太耗時間了,然後有些資料上採用了排列組合的方法計算乙個局面的每個方塊的有雷情況,如《程式設計之美——4.11 掃雷遊戲的概率 - fivedoumi的專欄 - 部落格頻道 – csdn》。但是這種手段只是針對乙個很簡單的局面在稿紙上做個分析而已。至於情況變複雜,這麼多數字之間肯定是有影響的,還不知道怎麼算呢,要是再程式設計實現就更困難了。若是這種採用排列組合來算概率的手段得到很好的推到優化,計算速度肯定大幅提公升,但是沒時間考慮這些呢!

最後我發現掃雷遊戲的初始局面要不是你中雷,要麼是點中乙個8鄰域無雷的方塊得到如下局面:

要麼是你點中乙個8鄰域內有雷的方塊,得到如下局面:

對於第二種情況,我們用寬度優先搜尋呈現給玩家出事局面!

演算法實現自動掃雷遊戲

1.遊戲的構思 2.演算法偽 的實現 3.演算法的實現 1.首先需要建立起遊戲的整個框架 棋盤的繪製,地雷的生成,基本函式的實現等 2.構思ai演算法的大概樣貌 先嘗試寫偽碼 voidai ai演算法 if first selectrandompos 遊戲開始隨機選擇一處位置翻開 selectpos...

WinXP下 掃雷程式逆向分析 掃雷輔助 一

逐步走向逆向的坑 慢慢的鍛鍊 也算是一種興趣愛好吧 突然起興 及時行樂 就想著嘗試分析一下掃雷 這次就用 winxp自帶的掃雷試試 使用peid 直接拖進去 可以看到 是使用vc 編寫 而且 是 debug 版本 m 還是比較厚道 直接拖進 od api 程式設計的逆向優勢在於 呼叫的 api 函式...

掃雷的分析與實現 C語言

主要功能有 1.第一次下子不被炸死 2.下子後顯示周圍布雷數 首先可以將掃雷的遊戲介面看做乙個二維陣列 然後有限的雷隨機排布在這個二維陣列中,玩家通過輸入座標來確定該座標對應的二維陣列座標是否是雷,若不是則顯示周圍布雷數,這時考慮座標如果在陣列的中間則少顯示周圍8個座標布雷情況,而在陣列邊緣則小於8...