你玩過咱們昨天介紹的HTML5 小遊戲2048麼?玩通關了麼?若是沒有玩通關過,別急,看過本文以後通關不再是難事!html
基本的算法是,若是2^k
是最大的數字,那麼咱們努力將2^(k-1)
放在它的旁邊,而後再把2^(k-2)
放在2^(k-1)
的旁邊,以此類推。git
爲了達成這一點,咱們努力將最大的數字放在角落,而後將第二大的數字放在它旁邊,以此類推。將最大的數字放在角落,這樣就能夠留出足夠的空間來組合出更大的數字。github
最終咱們指望造成這樣的圖形:算法
x x x x 4 2 x x 8 16 32 64 1024 512 256 128
這是適用於人類的算法,若是是機器呢?可使用更強力、複雜的算法。segmentfault
ovolve編寫了一個針對2048的AI程序,能夠自動幫你通關。函數
在機器的眼裏,2048是一個回合制的遊戲,是一個離散的狀態空間,和象棋之類的遊戲同樣。所以徹底可使用成熟的極小化極大 + α-β剪枝算法。爲了提高搜索的效率,考慮了兩個因素:性能
單調性指儘可能使各個方向上的數字保持單調(遞增或遞減),這樣能夠防止小數字被分割開來。spa
爲了便於合併,相鄰的塊(tile)差距要儘量地小,這經過衡量平滑性來判斷。code
咱們能夠從圖論的角度來解釋平滑性。咱們能夠把遊戲的狀態當作是G(V, E)
,其中V表明活動的塊的集合,而E表明鏈接相鄰塊的邊角,邊角的差距經過函數c(v1, v2)
來衡量。由於推動遊戲要求相鄰塊數值相同,也就是說c(v1, v2)
返回0。所以咱們須要儘量地減小相鄰塊的差距,或者說,確保移動致使各處相鄰塊c(v1, v2)
之和最小。htm
經過這樣的算法,咱們能獲得大約90%的勝率,同時也有不錯的性能。(沒人願意等上半天才看到AI動一步……
撰文 SegmentFault