双人贪吃蛇@botzone算法设计
單人貪吃蛇游戲的一般算法思路是進行前向預測,尋找空間最大的可能走法。 
 雙人對戰中,對方的走法不確定,必須加以預測。此外,還可以堵截對方的權值。 
 為了實現以上目的,需要對于己方蛇體、對方蛇體、地圖障礙物進行建模。建立局面對象包含全部信息,每移動一個回合遞歸復制局面對象,以某種規則預測對手行為進行更新。
需要傳遞的數據有: 
 - 地圖信息(本游戲中為靜態,故傳全局指針單一對象) 
 - 對方蛇所在位置 
 - 我方蛇所在位置 
 - 蛇歷史運動數據*
可以供決策的技術指標: 
 1. 近步成殺。即按照這一走法,己方不死,對方無論怎么走都會死。該情況屬于硬性勝利條件,只要存在即實施,無須再看其他指標。 
 2. 自己不死的自由度大小,對方可假設為路徑貪心:適用于敵人的模型,假設對手(我)為不動,選取可行步數最長的方向 
 3. 連通性分析尋找關鍵通道,力求將對方包圍在盡量小的封閉區域內。應用最短路徑算法,對于每個方格假設按最短路徑到達,則令對方到達各方格最曲折甚至不能到達的就是最優路徑。 
 有一點需要注意,即不同的路徑有不同的長度,我們在評價最優的時候需要排除單純由于走的路線長占據的格點多而使得對方無路可走。這種“最優”是被動的,因為會輕易被對方的移動所攪亂,故不具有實用性。解決方法是將評價函數S設置為: 
 S=SUM(1/(1+對方的可行方格數的步數))+自身步數/6
然后取MAXS-S最大的前幾個方案,按照初始方向累加,返回最大的方向和對應權值。 
 其中MAXS是S的最大值,超過此值就沒意義了不合格。 
 4. 貼近對方,并且自己能逃脫
搜索最短路徑使用dijistra算法,使用小頂堆尋找未放入連通子圖的最近的頂點。 
 從堆頂取出頂點時,關心的是其值和坐標; 
 在更新頂點的值的時候,需要修改指定坐標頂點的值,然后修正堆(也可以刪除指定頂點,修改值后重新插入)。需要通過坐標索引小頂堆的位置; 
 于是,我們需要一個數據結構具有雙向指向功能
為了加快移動速度,節省空間,小頂堆中存儲的都是指針
typedef struct _Block {int val; //地圖中的距離int index; //堆中的索引值//int xy=x*MAX_MAP+y; //地圖中的坐標 直接用數組索引值替代了 }Block; Block *heap[MAX_MAP*MAX_MAP];
 小頂堆的精髓在于,使用數組順序存儲時,若以1作為堆頂索引號,則任意一個節點i,父節點索引為i/2,左子節點索引為2*i 
 
 添加節點時從數組尾部,不斷比較大小上浮即可
 移除堆頂時,也是同樣的策略從上到下將小元素逐個上浮。有一個特殊情況需要處理:設堆最后一個元素是L,在推進到倒數第二層時,可能使得最后一層的某個孩子被換上去而產生一個洞。為了保持堆的結構,必須把最后一個元素運過去補上,此時如果L比那個孩子小的話就不能保證堆序的性質了。例如:
解決方法是每一級判斷子元素是否大于最后一個元素,如果大于,則應該直接把最后一個元素移動上來,然后終止向下過程返回。
MinElement=Elements[1]; LastElement=Elements[Size--];for(i=1;i*2<=Size;i=Child) {/* Find smaller child */Child =i*2;if(Child!=Size && Elements[Child+1] <Elements[Child])Child++;/* Percolate one level */if(LastElement>Elements[Child])Elements[i]=Elements[Child];elsebreak;}Elements[i]=LastElement;
 最短路徑算法中,頻繁出現的是對于堆中元素的修改操作,相應的調整堆算法如下:
 以上算法均為針對常規數值,本程序中需要改寫為指針數據進行訪問,且每次數據移動都需要增加相應修改index的步驟。例如,insert()中
代碼見 https://github.com/merfii/DoubleSnakeAI
總結
以上是生活随笔為你收集整理的双人贪吃蛇@botzone算法设计的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: win7系统的两种硬盘格式mbr和gpt
 - 下一篇: 554 5.7.1详细排错过程