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