貪吃蛇 AI 的實現 snake AI
1.首先看下這個非常在微博上很火的貪吃蛇gif
這次我們嘗試用程式碼來模擬下,說不定上面這個圖就是計算機搞的。
2.講貪吃蛇AI之前,我們先看下貪吃蛇移動的特點
物理上給人的感覺是整個貪吃蛇往右移了一步,在貪吃蛇非常長的情況下給人的感覺移一步要做很多事情。但是在計算機中我們可以簡單的考慮貪吃蛇的移動,假設用一個數組來儲存所有組成貪吃蛇的格子,那麼移動一步,就是把將來的格子插入到這個陣列的頭部,然後再去掉這個陣列的最後一個元素。我們只做兩件事情,就完成了一整條蛇的移動!往下看之前,再仔細考慮下移動這個問題。
在說貪吃蛇AI之前,我們要考慮一個問題:怎樣保證貪吃蛇永遠不死?我們知道無論往那個方向前進一步,尾巴的格子都會空出來,那麼追著貪吃蛇的尾巴移動,就能保證貪吃蛇永遠不死!
3.尋路演算法之A Star
貪吃蛇一般情況下要找一個最短路線去吃蘋果,這個時候A star尋路演算法就派上用場了,如果你對A Star 演算法還不瞭解,可以先看下這篇文章:《Cocos2d-x 尋路演算法之三 A Star》 。這裡用A Star 需要特別注意兩個問題:1.整個蛇的身體是不可接觸的格子的,要排除掉。2.因為貪吃蛇移動是一個動態的過程,所以每走一步,要重新進行尋路,而不是一次尋路完,走完路線,因為尾巴的位置會不斷的空出來。
4.單純使用尋路演算法遇到的問題
4.1會進入死衚衕
黃色的是貪吃蛇的頭部,紅色是我們要吃的東西,根據尋路演算法,黑色的就是最短路線,可以在腦子裡腦補下,吃完這個東西,貪吃蛇就掛了!
4.2 找不到路線
在貪吃蛇足夠長的情況下,蘋果可能會在蛇身體包圍的圈中,看上圖,黃色表示頭部,那麼蛇就找不到路線了!
4.3 一味的最短路線吃東西,留下太多洞
我們看下這張圖,紅色的表示現在出現的蘋果,橙色的表示吃完紅色的蘋果後,蘋果可能出現的位置,如果我們簡單的用最短路線去吃紅色的,即無腦往左走,那麼橙色的就在會出現在蛇的包圍圈中,將來要吃這個就非常不利,要走很多步。
這個時候比較好的走法是下圖:
儘可能的多繞,儘可能地把空白地方填完,而不是以最短路線去吃,要為將來打算。
5. 貪吃蛇的最佳無腦模式
一想到4.3的問題,我就覺得貪吃蛇AI是非常難的一個問題,難道還是設及到“
就是在最後一行空出來,留做逃生的路線,然後像彈簧一樣無腦向右推進,吃完後,從底部繞回最左邊,繼續這樣的策略,直到填滿整個遊戲區域。不知道讀者懂不懂這樣的策略。
6.開始講我的貪吃蛇AI實現了
一定要先理解上面的東西,才好繼續往下看。我們知道追著尾巴跑,蛇就不會死,所以我們以最短路線去吃蘋果時,要給自己留條後路,策略1.如果吃完蘋果還可以找到到自己尾巴路線的話,才去吃蘋果。
下面給出的是虛擬碼:
var canFindPath= false; //可以找到吃蘋果的路線
var canFindTail = false; //可以找到自己尾巴的路線
canFindPath = startPathFinding(); //開始尋找路線
if(canFindPath){ //如果可以找到吃蘋果的路線
moveSnake() //移動一條看不見的貪吃蛇去吃
canFindTail = startPathFinding(); //嘗試找自己尾巴路線
if(canFindTail){ //如果可以找到自己尾巴路線
return safePathCell; //返回吃蘋果路線的第一步
}
}
策略2.如果找不到吃蘋果路線或者吃完蘋果後,會發生找不到自己尾巴路線的話,那麼就在頭部的周圍找一個格子,這個格子要滿足兩個條件,條件1,走完這個格子要能找到到尾巴的路線,條件2,這個格子到蘋果的距離是最遠的。
策略2中的條件1,我們肯定是能找的到的,因為我們的AI的基礎都是基於策略1。
策略2的虛擬碼如下:
var canFindPath= false; //可以找到吃蘋果的路線
var canFindTail = false; //可以找到自己尾巴的路線
canFindPath = startPathFinding(); //開始尋找路線
if(canFindPath){ //如果可以找到吃蘋果的路線
moveSnake() //移動一條看不見的貪吃蛇去吃
canFindTail = startPathFinding(); //嘗試找自己尾巴路線
if(canFindTail){ //如果可以找到自己尾巴路線
return safePathCell; //返回吃蘋果路線的第一步
}
}
if(canFindPath == false || canFindTail == false ){
return getACellThatIsFarthestToGoal();
}
注意下策略2中的條件2,我們沒有用什麼高深的演算法,我們僅僅是把蛇往一個到蘋果最遠的格子移動,執行起我們的貪吃蛇,我們發現貪吃蛇AI可以工作了!!這個就有點哲學的味道了,看似在往遠離目標的方向上行動,沒有想到蛇剛好自己在繞了,繞掉了大部分的身體後,就可以用策略1找到路線了。
看了好幾遍自己貪吃蛇AI的移動,不可避免的會有4.3提到的這個問題,後期留下太多洞了,貪吃蛇要追隨自己尾巴,移動很久才能吃到一個蘋果,我們知道有標題5 提到的無腦模式,我們在想,要不後期就不要以最短路線去吃蘋果,而是無腦繞,來吃,這樣反而會快些!
怎樣才能產生無腦繞的效果呢?我們發現策略2中的條件2會產生這樣的效果,在後期,我們就走離蘋果最遠的格子且這個格子能有到達尾巴的路線,我們發現這樣走無意中就會產生這樣的無腦繞效果!有點像圓。圓心就是目標,最終還算會不斷地接近目標的!
這樣算是貪吃蛇遊戲的後期呢?我這裡就簡單如果蛇的長度等於整個遊戲格子數量的一半,就算到後期了。
7.最終貪吃蛇AI效果圖:
8.貪吃蛇AI線上試玩地址
用Cocos2d html5實現的。
9.貪吃蛇snake html5 下載
github: https://github.com/waitingfy/snake