讓你的拼圖聰明起來——自動還原拼圖


寫在前面

上一篇文章我寫了一個簡單的iOS 拼圖游戲(童年的記憶——拼圖游戲),現在我要讓這個游戲聰明起來,幫助你來完成拼圖。寫這篇文章的時候正好在看《最強大腦》,節目里的第一個PK就是復原這種拼圖(非圖而是數字,數字華容道),節目營造了非常緊張的氣氛,其實這種拼圖復原算是比較簡單的。
不再前戲,直接進入正題:游戲源碼點這里(拼圖游戲),您可以從這份源碼中get到的技術點:

> 設置代理類為控制器瘦身
> A*算法(含借助完全二叉樹實現優先隊列)
> GCD信號量控制數組遍歷流量
> 定時器+GCD信號量實現數組遍歷的暫停、繼續

游戲效果:游戲效果.gif

基本思路

那么怎樣讓原本屌絲氣質的游戲具備人工智能(AI),自動還原拼圖,從此華麗變身高大上呢?

  • 方案一:
    我們很容易想到的方法,按打亂的順序逆序還原。此方案的打亂順序即將原本有序的圖片按照游戲規則移動數次,從而實現打亂效果。但是我想你們已經發現了一個問題,我所設計的游戲打亂后空位設置在右下角,我們還需要想辦法將空位移動到右下角的目標位置。
  • 方案二:
    不關心打亂的過程,依次將編號0、1、2... 回歸到正確位置,逐漸縮小亂序圖區域。不過往往最后兩行的幾塊需要稍微調整下策略。
  • 方案三:
    不關心打亂的過程,從打亂后的狀態開始,根據一定約束條件,對下一步的多種可能性進行搜索判斷,逐步演進,從而找出復原步驟。我選用的是A*搜索算法。

方案解讀

* 方案一

方案一實現起來較為簡單,假定我們現在已經將有序的(處於復原態)拼圖移動了數次,也就是拼圖打亂了(如下圖左)。接下來將空位移動到右下角。
圖1.png

顯然,移動的策略有很多種,我們只需要一種,比如這樣:空位先逐步橫向移動到最右側,再逐步縱向移動到最下側。你看,可以啦。(上圖右邊)

算法分解:

1。求出當前空位所在行、列。
2。當前空位與其右側格子換位。
3。重復1、2,直到空位位於最右側(最大列)。
4。當前空位與其下側格子換位。
5。重復1、4,直到空位位於最下側(最大行)。

如此,我們已經完成了打亂步驟。當然,我們移動的每一步都需要記錄在案,以便按照記錄逆步驟進行還原。注:我提供的游戲源碼中並沒有包含該方案(方案一)的代碼實現,感興趣的讀者可以自行實現。

* 方案二

對於方案二,寫這篇文章的時候才臨時考慮加入這個方案。基本思路上文中其實已經闡明,暫不展開討論。

* 方案三

對於方案三,容易聯想到嘗試每種步驟可能性,最終選出可以復原的步驟鏈。圖2.png

上圖即表示每一個狀態衍生出的可能路徑,排除了重復的狀態。對於這種暴力搜索算法,性能是較低的(關於搜索算法,我此前的文章有介紹過最短路徑的兩個經典算法 點我)。拼圖為4階方陣時,拼圖狀態數(4*4)! = 20922789888000,廣搜算法已基本不能搜出結果,直到爆內存。拼圖為5階方陣時,狀態數(5*5)! = 1.551121004333098e25,10的25次方。先別着急,我們可以選擇性能較高的A*算法為拼圖游戲助力。

  • A*算法簡介:
    A*(A-Star)算法是一種靜態路網中求解最短路徑最有效的直接搜索方法,也是解決許多搜索問題的有效算法。它並不是搜索每一種可能的狀態,而是有選擇地啟發式搜索,每一次在多個狀態中選擇可能最接近目標狀態的一個。依此層層搜索,顯然相比暴力搜索,少走了很多的彎路。
    本文並不打算深入描述該算法技術細節。推薦閱讀A*算法詳解

對於該游戲,對每一個狀態到目標狀態的“距離”進行估算,將每一個方塊偏離它正確位置的距離進行累加,取偏離值最小者擇優錄取。圖示說明:

圖3.png

當前狀態估價(本例中也就是曼哈頓距離)計算方式:
4距離它正確的位置也就是上圖中7的位置:橫向1+縱向1=2;
1距離它正確的位置0;
3距離它正確的位置也就是上圖中2的位置:橫向2+縱向1=3;
2距離它正確的位置也就是上圖中3的位置:橫向2+縱向1=3;
7距離它正確的位置也就是上圖中5的位置:橫向0+縱向1=1;
0距離它正確的位置也就是上圖中4的位置:橫向2+縱向1=3;
6距離它正確的位置0;
我們給予空格位特權,不對它考核。
5距離它正確的位置也就是上圖中0的位置:橫向0+縱向1=1;
然后將上述距離值累加。
當然實際還可以在這個基礎上對估價進行調整,比如乘以一定系數。

性能優化(TODO)

暫時想到了以下優化方向:

  • 當前源碼每次UICollectionView數據源刷新時,為全局刷新方式,實際除了重置游戲,每次都只是2個格子在變化。可以修改為局部刷新。
  • 當前源碼為搜索完成后再進行拼圖復原。需要耗費一定的時間。嘗試邊搜索邊拼圖的方式(邊“生產”邊“消費”)。
  • 根據方格數的多少(難易程度)靈活調整A*算法的估價,意在優化游戲還原步數。

鳴謝

本文配套源碼中直接套用了《拼圖游戲和它的AI算法》該文作者封裝的A*算法,在此對原作者表示感謝。


免責聲明!

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



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