貪喫蛇 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實現的。

http://www.waitingfy.com/html5/snake

 

 http://www.waitingfy.com/archives/951

9.貪喫蛇snake html5 下載

 

 http://www.waitingfy.com/?attachment_id=962

github:  https://github.com/waitingfy/snake


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章