如何編寫一個掃雷速度最快的自動掃雷程序?

這個問題可能花費答題者很長時間去研究掃雷內在原理,如果沒有興趣和時間的人請跳過。

需要優化操作,即減少操作數,即通過一定的標雷雙擊使操作最簡,達到IOE(掃雷指標,即效率 3BV / 總點擊)。

--------------------------------------------------------------------------

提供一些參考資料(建議按順序看,看不太明白下載下面那個軟體玩幾局就知道了):

掃雷的規則:掃雷新手上路

掃雷各種指標:掃雷術語介紹

掃雷技術指標解析詞典

3bvs:3BV/s的公式及其應用

優化操作:談局部最優化操作

怎樣節省標雷

3bv和zini演算法:3BV與ZiNi淺析

定式:掃雷定式及變化

掃雷軟體(直接下載):http://saolei.net/Download/Arbiter_0.52.2.zip

前來答題的可不可以先看一看以上的資料熟悉一下這些指標以及掃雷的規則技巧。

只是為了研究這個技術,並不是作弊。


題主提供的那些資料是給人玩掃雷時用的,寫程序根本沒這麼多講究,所謂標雷對程序來說就是內存里設置一個flag。

所以正常的掃雷程序的就是掃描雷區,取得雷區中的信息(已翻開,未翻開,顯示的數字),這部分的效率是掃雷程序速度的關鍵。慢方法有取屏幕顏色,快方法是讀取遊戲內存。

然後,根據獲得的信息判斷出下一個安全的方塊,翻開。翻方塊的慢方法有模擬滑鼠操作,快方法是直接call遊戲里翻方塊的函數。

正如V大所說,有時候是無法準確算出安全方塊的,這時候就隨便挑一個中雷概率小的吧。

讀遊戲內存/call操作個人認為算是外掛的行為了,一般網路遊戲對此都有防範。

如果單機的話。。。隨便搞吧,甚至讀內存直接就能取得雷區的分布,什麼掃描雷區,算安全方塊都可以省了,這應該是最塊的掃雷程序了。


我自己寫過一個通過圖像識別來艸win7的掃雷的程序。演算法很簡單,就是針對所有覆蓋了數字的7*7方塊裡面,窮舉所有的不跟數字矛盾的情況,你就會發現有一些方塊在所有情況下面都是雷,有一些方塊都不是雷,這樣你就可以標記他們了。

如果你玩的是高級,你會發現你有大概90%的概率會發生猜不出來的情況。這種情況是常見的,也就是現在我們要蒙了,於是就隨機數一下蒙它。

看起來好像很粗暴,但是實際上效率是很高的。就算我的掃雷還要包含自己去截圖、分析圖片、移動滑鼠、等win7的掃雷放完他的動畫等耗時操作,也只需要30秒就可以破一個不需要蒙的高級了。


不考慮N(o)F(lag),操作有這麼2種:

1. 左鍵單擊一個格子。

  • 操作數:1
  • 收益(翻開的格子數): 如果點的格子數字為空,則&>=9 ,上不封頂;如果點的格子數字是1-8,則為1

2. 右鍵標n個旗,在一個已翻開的格子g上"左右並擊"。

  • 操作數:n + 2
  • 收益(翻開的格子數): &>= g周圍非雷的格子

新手的特點是能用操作2就不用操作1。其實操作2有時點擊很冗餘,比如插兩個旗,並擊一下,然後只開一個格子,凈收益為1 - (2 + 2) = -3;使用操作1則凈收益為1 - 1 = 0。這時就不如操作1。

達到較高IOE的關鍵就是合理地選擇操作1和操作2,以及選擇在哪裡操作,這確實是非常複雜的問題(參考題主的鏈接 3BV與ZiNi淺析)。

--------------------------以上算是掃盲(題主自然是都懂。。)-------------------------

我曾實現過一個 Human ZiNi(DEMO見:掃雷AI (Minesweeper Assist) Demo 1:48開始,代碼:minesweeper-assist -

Play minesweeper automatically on most platforms)。雖然還有很多問題,不過單看錄像,操作和人類比算是乾淨不少,IOE基本可以穩定sup1。即使是程序,如果不讀內存也沒法得知未點開的區域,Human ZiNi大概是程序能做到最好結果了吧。(PS:我的程序開率很低,主要是沒有在猜雷上下功夫,不過這個和題主說的減少操作數是兩回事了,互不影響)


上大學的時候編過一個,很簡單,直接讀掃雷的內存,1S以內全部搞定。

不過代碼早就不見了。

當時寫了個這個東西是為了逗女孩子從而達到不可告人的目的的。


以win7的為例。

行數:【MineSweeper.exe+868B4】+10】+8

列數:【MineSweeper.exe+868B4】+10】+C

雷表:【【【【【【MineSweeper.exe+0x868B4】+0x10】+0x44】+0xC】+x*4】+0xC】+y

結果為0(正常)1(有雷)。x是列號(0~列數-1),y是行號(0~行數-1)

在這個基礎上模擬滑鼠動作可以實現100%準確。

ps:

實現自動點擊還需要找到雷區那個控制項的句柄。我忘了存哪了。

找到之後就用winAPI讀內存和模擬點格子吧


剛畢業的時候閑的無聊做著玩的,自動排雷的抓圖

讀內存太作弊了,用的是去抓取界面根據顏色判斷數字的方法

程序模擬滑鼠隨機點開一個位置,然後自動根據範式判斷,有雷標雷,沒雷一直往下點


計算每一個點上雷的概率p。

點開p最小的。


我寫了一個,Java版本,比人快比人准。不過掃雷從理論上來說就總有解的。


推薦閱讀:

遊戲『這是我的戰爭』里大家喜歡哪個人物,不喜歡哪個?
《異星迷航》評測 我們的征途是星辰大海
CSGO有啥好看的皮膚?
我們為什麼玩遊戲?致所有用心良苦的父母

TAG:遊戲 | 演算法 | 編程 | 編程思想 | 演算法設計 |