讓你的拼圖聰明起來——自動還原拼圖(iOS 游戲)

寫在前面

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

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

游戲效果:
游戲效果.gif

基本思路

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

  • 方案一:
    我們很容易想到的方法,按打亂的順序逆序還原戏挡。此方案的打亂順序即將原本有序的圖片按照游戲規(guī)則移動數(shù)次芍瑞,從而實現(xiàn)打亂效果。但是我想你們已經(jīng)發(fā)現(xiàn)了一個問題褐墅,我所設(shè)計的游戲打亂后空位設(shè)置在右下角拆檬,我們還需要想辦法將空位移動到右下角的目標(biāo)位置。
  • 方案二:
    不關(guān)心打亂的過程妥凳,依次將編號0竟贯、1、2... 回歸到正確位置逝钥,逐漸縮小亂序圖區(qū)域屑那。不過往往最后兩行的幾塊需要稍微調(diào)整下策略。
  • 方案三:
    不關(guān)心打亂的過程艘款,從打亂后的狀態(tài)開始持际,根據(jù)一定約束條件,對下一步的多種可能性進(jìn)行搜索判斷哗咆,逐步演進(jìn)蜘欲,從而找出復(fù)原步驟。我選用的是A*搜索算法晌柬。

方案解讀

* 方案一

方案一實現(xiàn)起來較為簡單姥份,假定我們現(xiàn)在已經(jīng)將有序的(處于復(fù)原態(tài))拼圖移動了數(shù)次,也就是拼圖打亂了(如下圖左)年碘。接下來將空位移動到右下角澈歉。


圖1.png

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

算法分解:

1。求出當(dāng)前空位所在行悟衩、列剧罩。
2。當(dāng)前空位與其右側(cè)格子換位座泳。
3惠昔。重復(fù)1、2挑势,直到空位位于最右側(cè)(最大列)镇防。
4。當(dāng)前空位與其下側(cè)格子換位潮饱。
5来氧。重復(fù)1、4香拉,直到空位位于最下側(cè)(最大行)啦扬。

如此,我們已經(jīng)完成了打亂步驟凫碌。當(dāng)然扑毡,我們移動的每一步都需要記錄在案,以便按照記錄逆步驟進(jìn)行還原盛险。注:我提供的游戲源碼中并沒有包含該方案(方案一)的代碼實現(xiàn)瞄摊,感興趣的讀者可以自行實現(xiàn)。

* 方案二

對于方案二枉层,寫這篇文章的時候才臨時考慮加入這個方案泉褐〈托矗基本思路上文中其實已經(jīng)闡明鸟蜡,暫不展開討論。

* 方案三

對于方案三挺邀,容易聯(lián)想到嘗試每種步驟可能性揉忘,最終選出可以復(fù)原的步驟鏈。
圖2.png

上圖即表示每一個狀態(tài)衍生出的可能路徑端铛,排除了重復(fù)的狀態(tài)泣矛。對于這種暴力搜索算法,性能是較低的(關(guān)于搜索算法禾蚕,我此前的文章有介紹過最短路徑的兩個經(jīng)典算法 點我)您朽。拼圖為4階方陣時,拼圖狀態(tài)數(shù)(4*4)! = 20922789888000,廣搜算法已基本不能搜出結(jié)果哗总,直到爆內(nèi)存几颜。拼圖為5階方陣時,狀態(tài)數(shù)(5*5)! = 1.551121004333098e25讯屈,10的25次方蛋哭。先別著急,我們可以選擇性能較高的A*算法為拼圖游戲助力涮母。

  • A*算法簡介:
    A*(A-Star)算法是一種靜態(tài)路網(wǎng)中求解最短路徑最有效的直接搜索方法谆趾,也是解決許多搜索問題的有效算法。它并不是搜索每一種可能的狀態(tài)叛本,而是有選擇地啟發(fā)式搜索沪蓬,每一次在多個狀態(tài)中選擇可能最接近目標(biāo)狀態(tài)的一個。依此層層搜索来候,顯然相比暴力搜索怜跑,少走了很多的彎路。
    本文并不打算深入描述該算法技術(shù)細(xì)節(jié)吠勘。推薦閱讀A*算法詳解性芬。

對于該游戲,對每一個狀態(tài)到目標(biāo)狀態(tài)的“距離”進(jìn)行估算剧防,將每一個方塊偏離它正確位置的距離進(jìn)行累加植锉,取偏離值最小者擇優(yōu)錄取。圖示說明:

圖3.png
當(dāng)前狀態(tài)估價(本例中也就是曼哈頓距離)計算方式:
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拣展;
我們給予空格位特權(quán)彭沼,不對它考核。
5距離它正確的位置也就是上圖中0的位置:橫向0+縱向1=1备埃;
然后將上述距離值累加姓惑。
當(dāng)然實際還可以在這個基礎(chǔ)上對估價進(jìn)行調(diào)整,比如乘以一定系數(shù)按脚。

性能優(yōu)化(TODO)

暫時想到了以下優(yōu)化方向:

  • 當(dāng)前源碼每次UICollectionView數(shù)據(jù)源刷新時于毙,為全局刷新方式,實際除了重置游戲辅搬,每次都只是2個格子在變化唯沮。可以修改為局部刷新。
  • 當(dāng)前源碼為搜索完成后再進(jìn)行拼圖復(fù)原介蛉。需要耗費一定的時間夯缺。嘗試邊搜索邊拼圖的方式(邊“生產(chǎn)”邊“消費”)。
  • 根據(jù)方格數(shù)的多少(難易程度)靈活調(diào)整A*算法的估價甘耿,意在優(yōu)化游戲還原步數(shù)踊兜。

鳴謝

鑒于A* 算法是個通用的算法,筆者就不重復(fù)造輪子了佳恬。本文配套源碼中直接套用了《拼圖游戲和它的AI算法》作者封裝的A*算法捏境,在此對原作者表示感謝。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末毁葱,一起剝皮案震驚了整個濱河市垫言,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌倾剿,老刑警劉巖筷频,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異前痘,居然都是意外死亡凛捏,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進(jìn)店門芹缔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來坯癣,“玉大人,你說我怎么就攤上這事最欠∈韭蓿” “怎么了?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵芝硬,是天一觀的道長蚜点。 經(jīng)常有香客問我,道長拌阴,這世上最難降的妖魔是什么绍绘? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮皮官,結(jié)果婚禮上脯倒,老公的妹妹穿的比我還像新娘实辑。我一直安慰自己捺氢,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布剪撬。 她就那樣靜靜地躺著摄乒,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上馍佑,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天斋否,我揣著相機(jī)與錄音,去河邊找鬼拭荤。 笑死茵臭,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的舅世。 我是一名探鬼主播旦委,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼雏亚!你這毒婦竟也來了缨硝?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤罢低,失蹤者是張志新(化名)和其女友劉穎查辩,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體网持,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡宜岛,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了功舀。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片谬返。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖日杈,靈堂內(nèi)的尸體忽然破棺而出遣铝,到底是詐尸還是另有隱情,我是刑警寧澤莉擒,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布酿炸,位于F島的核電站,受9級特大地震影響涨冀,放射性物質(zhì)發(fā)生泄漏填硕。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一鹿鳖、第九天 我趴在偏房一處隱蔽的房頂上張望扁眯。 院中可真熱鬧,春花似錦翅帜、人聲如沸姻檀。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽绣版。三九已至胶台,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間杂抽,已是汗流浹背诈唬。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留缩麸,地道東北人铸磅。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像杭朱,于是被迫代替她去往敵國和親愚屁。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,592評論 2 353

推薦閱讀更多精彩內(nèi)容

  • 寫了個拼圖游戲痕檬,探討一下相關(guān)的AI算法霎槐。拼圖游戲的復(fù)原問題也叫做N數(shù)碼問題。 拼圖游戲 N數(shù)碼問題 廣度優(yōu)先搜索 ...
    囧書閱讀 15,454評論 37 99
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,072評論 25 707
  • 無聊刷了半小時頭條, "為什么古天樂還在孜孜不倦更新沒有人看的博客梦谜?"丘跌,這篇帖子吸引了我 百度一搜,追根溯源找到他...
    mlxnle閱讀 5,848評論 0 0
  • npm 安裝 安裝 node.js 安裝 git git 安裝淘寶NPM鏡像 npm install -g cnp...
    餅餅_佳閱讀 635評論 0 5
  • 寫在前面: 除卻自己唁桩,就是“他她它”闭树,而究其實筹裕,自己也是內(nèi)在諸多“他她它”的集合魂仍。 故而喻旷,生命就是和許多的TA發(fā)生...