展會(huì)信息港展會(huì)大全

游戲開發(fā)中的遺傳算法
來源:互聯(lián)網(wǎng)   發(fā)布日期:2011-09-07 15:46:16   瀏覽:7477次  

導(dǎo)讀:一直都想用遺傳算法(Genetic Algorithms)實(shí)現(xiàn)足球游戲的人工智能,但因?yàn)閷?shí)現(xiàn)一個(gè)足球游戲的對(duì)戰(zhàn)平臺(tái)太過于繁瑣而沒有動(dòng)手。直到在《Programming Game AI by E...

當(dāng)前位置: 教程  >  游戲開發(fā)  >  游戲程序設(shè)計(jì)  >  正文

游戲開發(fā)中的遺傳算法 作者:吳旭 發(fā)表于 2010-6-23 11:22:07     評(píng)論(0)     閱讀(263)     

一直都想用遺傳算法(Genetic Algorithms)實(shí)現(xiàn)足球游戲的人工智能,但因?yàn)閷?shí)現(xiàn)一個(gè)足球游戲的對(duì)戰(zhàn)平臺(tái)太過于繁瑣而沒有動(dòng)手。直到在《Programming Game AI by Example》一書中看到一個(gè)SimpleSoccer的demo(以下簡(jiǎn)稱demo),實(shí)現(xiàn)了一個(gè)red-blue兩隊(duì)進(jìn)行機(jī)器與機(jī)器對(duì)抗的簡(jiǎn)單足球游戲。在讀過它的源碼之后,我決定在demo上進(jìn)行二次開發(fā)——為它加入遺傳算法,實(shí)驗(yàn)遺傳算法在實(shí)時(shí)戰(zhàn)略游戲(RTS)性質(zhì)的體育游戲中的威力。
demo的架構(gòu)非常好,采用了狀態(tài)機(jī)來實(shí)現(xiàn)游戲流程,并分開計(jì)算游戲決策。因此加入遺傳算法非常容易,只要在原來的狀態(tài)機(jī)中增加一兩個(gè)狀態(tài)即可。red-blue兩個(gè)隊(duì)伍相互對(duì)抗,每隊(duì)有五位球員,其中一位是守門員。這個(gè)demo的足球規(guī)則是簡(jiǎn)化的,除了只有五個(gè)球員外,沒有手球也沒有越位等規(guī)則,甚至連邊界球都沒有——球碰到邊界就反彈回球場(chǎng)。簡(jiǎn)化的規(guī)則有利于我們簡(jiǎn)化實(shí)驗(yàn)的過程,不必把很多精力花費(fèi)在過于復(fù)雜的規(guī)則上。



圖一
在demo的實(shí)現(xiàn)中,球場(chǎng)被分割為18塊大小相等的區(qū)域(見圖一)。每一個(gè)球員都一個(gè)屬于自己的區(qū)域(稱為HomeRegion),如圖一中blue隊(duì)的10號(hào)在自己的HomeRegion(Region5)中處于Wait狀態(tài)(球員的狀態(tài)之一)。當(dāng)一個(gè)球員不處于進(jìn)攻狀態(tài)(Attacking)、助攻(SupportAttacker)、逐球(ChaseBall)、運(yùn)球(Dribble)、踢球(KickBall)及返回(ReturnToHomeRegion)時(shí),他就進(jìn)入Wait狀態(tài)——等待球隊(duì)發(fā)出的下一個(gè)行動(dòng)指令。顯然,就像人類進(jìn)行足球比賽時(shí)需要排兵布陣一樣,demo中球員站在哪個(gè)位置也相當(dāng)重要,能否組織起有效的進(jìn)攻或者防守,決定因素之一就是在合適的位置有沒有球員可以快速有效地執(zhí)行命令。在書中自帶的demo中,球員的站位都是固定的,因此難以組織有效的進(jìn)攻和防守,在某一時(shí)間段內(nèi)容易形成一邊倒的局勢(shì)。使用遺傳算法來對(duì)球員的站位進(jìn)行決策分析,可以找出對(duì)當(dāng)前局勢(shì)就有利的位置編排方案。從而使得球隊(duì)與球隊(duì)之間的對(duì)抗趨于激烈、策略更加有效、攻守都更精彩。

遺傳算法概述
遺傳算法因?yàn)樗诮鉀Q許多生產(chǎn)、生活中的問題上的卓越性能而經(jīng)久不衰。隨著計(jì)算機(jī)的計(jì)算能力日益增強(qiáng)和玩家對(duì)游戲中的人工智能的強(qiáng)烈需求,目前在單機(jī)游戲中已經(jīng)開始應(yīng)用遺傳算法、人工神經(jīng)網(wǎng)絡(luò)等現(xiàn)代優(yōu)化計(jì)算方法來增強(qiáng)游戲中的人工智能,并且形成了趨勢(shì)。可見以后為加強(qiáng)機(jī)器的對(duì)抗性能,遺傳算法、人工神經(jīng)網(wǎng)絡(luò)等都會(huì)越來越多地應(yīng)用到游戲中。
遺傳算法是模擬自然界中的生物對(duì)自然界的適應(yīng)而不斷進(jìn)化這一客觀事實(shí)的算法。為了解決某一個(gè)問題,在遺傳算法中,我們虛擬一個(gè)物種(即解的表現(xiàn)形式或者稱為解的編碼),并將其放到“自然環(huán)境”中天下繁殖、進(jìn)化,根據(jù)優(yōu)勝劣汰、適者生存的自然法則,繁衍若干代之后,種群中的佼佼者將非常適應(yīng)“自然環(huán)境”,這個(gè)佼佼者就是我們求得的解了。關(guān)于生物學(xué)與遺傳算法之間的概念的對(duì)應(yīng)關(guān)系可以用表一的形式來表示:



表一
遺傳算法的流程圖如圖二所示:



圖二
遺傳算法運(yùn)行時(shí),先生成初始群體(通常是隨機(jī)產(chǎn)生一定數(shù)量的個(gè)體,這個(gè)數(shù)量就是群體的大。;然后讓群體繁殖下一代,繁殖的方式有交叉、復(fù)制和變異;經(jīng)過繁殖后群體的數(shù)量增加,然后使用評(píng)估模塊對(duì)每一個(gè)個(gè)體進(jìn)行評(píng)估;如果群體中最佳個(gè)體已經(jīng)足夠優(yōu)秀,那就跳出循環(huán),返回最佳個(gè)體;否則判斷是否已經(jīng)繁殖了預(yù)定的代數(shù),如果是就返回最佳個(gè)體,如果不是則淘汰一部分劣質(zhì)個(gè)體并進(jìn)入下一輪繁殖循環(huán)直至結(jié)束。
在遺傳算法的實(shí)現(xiàn)中,最重要的主要有三點(diǎn):一是染色體的編碼,即一個(gè)新物種怎么樣來表示它,通常染色體是問題的一個(gè)可能解的特定格式的表示,通常以二進(jìn)制或者十進(jìn)制的方式編碼;二是為染色體實(shí)現(xiàn)交叉、復(fù)制、變異等算子;三是估值模塊的編寫。下面以這三點(diǎn)為中心,談?wù)刣emo中的遺傳算法實(shí)現(xiàn)。

染色體編碼
染色體編碼的方式有很多種,常見的是二進(jìn)制方法和十制字方式,也有字符串方式的。如著名的旅行商問題(TSP)里,假設(shè)有20個(gè)城市以[0…19]編碼,那么[7,6,9,8…19,3,0,4]這個(gè)包含20個(gè)元素的序列A就可以看作是一個(gè)染色體,每一個(gè)元素Aj(0<=j<20)就是染色體的一個(gè)基因。這個(gè)染色體可以解碼為從編號(hào)為7的城市出發(fā),到達(dá)城市6、城市9等等,最后到達(dá)城市4完成20個(gè)城市的遍歷。顯然,這個(gè)序列是TSP的一個(gè)可能解,因此染色體就是問題的可能解的表示方式;氐轿覀兊淖闱蛴螒蛑衼,我們期望獲得某一隊(duì)的球員的合適站位,那么如果我們把四個(gè)球員以[0…3]編號(hào)(因?yàn)槭亻T員不應(yīng)離開禁區(qū)所以不必考慮他的位置),那序列B[14,11,12,6]就是一個(gè)站位方案,表示0號(hào)球員站在ID為14的Region中,1號(hào)球員站在ID為11的Region中,等。序列B叫做一個(gè)可能解,序列B的編碼方式即是我們?nèi)旧w的編碼方式——十進(jìn)制編碼方式的一個(gè)序列。依照這個(gè)規(guī)則,我們編寫代碼如下:
typedef unsigned int Genetype;
class Chromosome{
private:
std::vector m_Geneme;
int m_iScore;
public:
Chromosome();
~Chromosome(){};
const std::vector& GetGeneme()const{return m_Geneme;}
void SetScore(int iScore){m_iScore = iScore;}
friend void Intercross(const Chromosome& p1, const Chromosome& p2,
Chromosome& c1, Chromosome& c2);

friend void Agamogenesis(const Chromosome& p, Chromosome& c);
friend void Mutant(const Chromosome& p, Chromosome& c);
friend class GT;
};
class GT{
public:
inline bool operator()(const Chromosome* c1, const Chromosome* c2)const{
return c1->m_iScore > c2->m_iScore;
}
};
類Chromosome是染色體封裝,它的成員變量m_Geneme是一個(gè)基因序列,用std::vector容器來保存;成員變量m_iScore是這個(gè)染色體對(duì)“自然環(huán)境”的適應(yīng)值,由評(píng)估模塊評(píng)定。友元類GT實(shí)現(xiàn)了兩個(gè)Chromosome的大小比較;還定義了三個(gè)友元函數(shù)分別實(shí)現(xiàn)交叉、復(fù)制及變異三個(gè)遺傳算子,詳見下節(jié)。

遺傳算子
交叉、復(fù)制和變異三個(gè)遺傳算子是遺傳算法能夠找到最優(yōu)解的途徑。這三個(gè)遺傳算子模擬了自然界的物種交配和生殖的方式,為產(chǎn)生新的可行解提供了有效手段(見表一)。遺傳算子聲明為染色體類Chromosome的友元函數(shù)是為了方便操作它的私有變量,實(shí)現(xiàn)如下:
void Intercross(const Chromosome& p1, const Chromosome& p2,
Chromosome& c1, Chromosome& c2){
unsigned int IntercrossPoint = RangeRandom(0, GeneLen);
unsigned int i = 0;
for(; i < IntercrossPoint; ++i){
c1.m_Geneme[i] = p1.m_Geneme[i];
c2.m_Geneme[i] = p2.m_Geneme[i];
}
for(; i < GeneLen; ++i){
c1.m_Geneme[i] = p2.m_Geneme[i];
c2.m_Geneme[i] = p1.m_Geneme[i];
}
}
void Agamogenesis(const Chromosome& p, Chromosome& c){
c.m_Geneme = p.m_Geneme;
}
void Mutant(const Chromosome& p, Chromosome& c){
unsigned int MutantPoint = RangeRandom(0, GeneLen);
Genetype NewGene = RangeRandom(0,18);
c.m_Geneme = p.m_Geneme;
c.m_Geneme[MutantPoint] = NewGene;
}
Intercross,Agamogenesis和Mutant三個(gè)函數(shù)分別對(duì)應(yīng)交叉、復(fù)制和變異三個(gè)遺傳算子。Intercross函數(shù)傳入兩個(gè)Chromosome的實(shí)例,隨機(jī)選擇一點(diǎn)進(jìn)行交叉,組成兩個(gè)新的染色體用作返回值。Agamogenesis函數(shù)傳入一個(gè)Chromosome實(shí)例,返回一個(gè)相同的染色體,以保證優(yōu)勢(shì)的種群可以壯大,從而使得遺傳算法可以在有限的運(yùn)行時(shí)間內(nèi)收斂。Mutant函數(shù)傳入一個(gè)Chromosome實(shí)例,隨機(jī)選擇一個(gè)元素(分量)賦以一個(gè)隨機(jī)的Region ID,返回這一改變后的染色體,變異可以使得遺傳算法跳出局部最優(yōu),趨近全局最優(yōu)。三個(gè)遺傳算子的操作結(jié)果如表二所示:



表二

估值模塊
通俗一點(diǎn)說,估值模塊就是閻羅王,個(gè)體淘汰與否就得看估值模塊的臉色了。估值模塊判定每一個(gè)染色體對(duì)“自然環(huán)境”的適應(yīng)度:如前文關(guān)于TSP的染色體,它的估值函數(shù)就返回遍歷20個(gè)城市要走過的路程的總長(zhǎng)度,總長(zhǎng)度越短的染色體適應(yīng)度越高,反之則越低。在足球游戲中,估值模塊就沒有這么簡(jiǎn)單了,一個(gè)染色體就是一個(gè)站位組合,這個(gè)組合的優(yōu)劣是與當(dāng)前局勢(shì)有很大關(guān)系,如球的位置、對(duì)方球員的站位、已方球員的站位和控球權(quán)等有關(guān),綜合以上各種因素,編寫如下估值模塊:
int Environment:: Evaluate (const std::vector& candidate){
int iValue = 0;
for( unsigned int i = 0; i < GeneLen; ++i){
//減去移動(dòng)需要的損耗
iValue -= DistOfTwoRgn(candidate[i], m_CurrGeneme[i]) * m_pPrm->CrossCostPerRgn;

//有利于防守?
iValue += GetDefendValue(candidate[i], m_OppGeneme);
//有利于進(jìn)攻?
iValue += GetAttackValue(candidate[i], m_OppGeneme);
//有利于搶球或者保球?
if(m_iTeamColor == m_iControllingTeam
&& m_iBallRgnIdx == candidate[i])
iValue += m_pPrm->PlyrKeepBallValue;
else if(m_iTeamColor != m_iControllingTeam
&& m_iBallRgnIdx == candidate[i])
iValue += m_pPrm->PlyrChaseBallValue;
}
return iValue;
}
int Environment::GetDefendValue(const int iPlyrIdx, const std::vector& OppGeneme){
int iValue = 0;
int OppInMyGround = 0;
std::vector::const_iterator ci = OppGeneme.begin();
for(; ci != OppGeneme.end(); ++ci){
if(IsInMyGround(*ci))
++OppInMyGround;
}

if(OppInMyGround > 1 ){
if(IsInMyGround(static_cast(iPlyrIdx)))
iValue += m_pPrm->DefendValuePerPlyr;
else
iValue += m_pPrm->DefendValuePerPlyr * 0.5;
}
else{
iValue += m_pPrm->DefendValuePerPlyr * 0.8;
}
if(m_iControllingTeam == m_iTeamColor)
iValue *= 1.2;
else
iValue *= 0.8;
return iValue;
}
int Environment::GetAttackValue(const int iPlyrIdx, const std::vector& OppGeneme){
int iValue = 0;
int OppNoInMyGround = 0;
std::vector::const_iterator ci = OppGeneme.begin();
for(; ci != OppGeneme.end(); ++ci){
if( !IsInMyGround(*ci))
++OppNoInMyGround;
}
if( OppNoInMyGround > 2 ){
if(IsInMyGround(static_cast(iPlyrIdx)))
iValue += m_pPrm->AttackValuePerPlyr * 0.5;

else
iValue += m_pPrm->AttackValuePerPlyr;
}
if(m_iControllingTeam == m_iTeamColor)
iValue *= 1.2;
else
iValue *= 0.8;
return iValue;
}
Evaluate函數(shù)主要從以下幾方面來對(duì)染色體進(jìn)行評(píng)估:
·從當(dāng)前位置到目的位置所要經(jīng)過的路徑的代價(jià)
·是否有利于進(jìn)攻或者防守
·是否有利于持球或者搶球
其中計(jì)算是否有利于進(jìn)攻或者防守是通過計(jì)算兩個(gè)球隊(duì)間球員的位置來判斷的:對(duì)方的球員在已方半場(chǎng)時(shí)如果已方球員的目的位置也在已方半場(chǎng)就有利于防守;對(duì)方的球員在已方半場(chǎng)時(shí)如果已方球員的目的位置在對(duì)方半場(chǎng)則有利于進(jìn)攻。通過這一簡(jiǎn)單的估值模塊,可以使得遺傳算法在淘汰劣質(zhì)個(gè)體時(shí)有法可依,從而能夠收斂得到較優(yōu)解。通過精細(xì)化估值模塊考慮更多因素(如對(duì)方球隊(duì)可能采取的策略等)可使遺傳算法的收斂速度加快,在真實(shí)的游戲項(xiàng)目中必定會(huì)使用精細(xì)化的估值模塊的。

程序架構(gòu)
確定了遺傳算法的編碼方式、實(shí)現(xiàn)了三個(gè)遺傳算子和估值模塊之后,這個(gè)遺傳算法基本上就完成了。但我們還沒有看到它是怎么初始化種群、怎么繁殖和怎么淘汰劣質(zhì)個(gè)體的,這時(shí)候有必要了解一下遺傳算法的程序架構(gòu)。在demo中,我們?cè)O(shè)計(jì)的遺傳算法的架構(gòu)如圖三:

Environment
Population
Chromosome
Gene




圖三
Environment是自然環(huán)境的模擬,它實(shí)現(xiàn)了估值函數(shù)、繁殖迭代的控制和環(huán)境的初始化和銷毀等功能,最重要的是它包含了一種成員變量——Population的實(shí)例。每一個(gè)Environment還有一個(gè)算法參數(shù)包裝類ParamLoader的實(shí)例指針m_pPrm用以存取配置文件。每一個(gè)球隊(duì)擁有一個(gè)Environment實(shí)例,專門用以計(jì)算適合本隊(duì)的球員位置編排。簡(jiǎn)化的Environment的聲明如下:
class Environment{
private:
ParamLoader* m_pPrm;
Population m_Population;
private:
int Evaluate(const std::vector& candidate);
int GetDefendValue(const int iPlyrIdx, const std::vector& OppGeneme);
int GetAttackValue(const int iPlyrIdx, const std::vector& OppGeneme);

bool IsInMyGround(unsigned int iRgnIdx)
double DistOfTwoRgn(unsigned int iRgnIdx1, unsigned int iRgnIdx2)
public:
const std::vector GetBestGeneme();
};
當(dāng)調(diào)用GetBestGnenme()時(shí),遺傳算法便開始運(yùn)行,GetBestGeneme()控制繁殖迭代的次數(shù),并挑選最優(yōu)的染色體個(gè)體,它的實(shí)現(xiàn)如下:
const std::vector Environment::GetBestGeneme(){
for(unsigned int i = 0; i < m_pPrm->GAGeneration; ++i){
m_Population.NexGeneration();
unsigned int uiPopulationSize = m_Population.GetPopulationSize();
for(unsigned int i = 0; i < uiPopulationSize; ++i){
int score = Evaluate(m_Population.GetGenemeByID(i));
m_Population.SetScoreByID(i, score);
}
m_Population.KeepColonySize(m_pPrm->ColonySize);
}
return m_Population.GetBestGeneme();
}
Population是物種群體的抽象,它實(shí)現(xiàn)一個(gè)最重要的函數(shù)就是NextGeneration(),Environment通過調(diào)用這個(gè)函數(shù)讓群體執(zhí)行繁殖任務(wù);另一個(gè)重要的函數(shù)就是KeepColonySize(),這個(gè)函數(shù)淘汰掉劣質(zhì)的個(gè)體,讓競(jìng)爭(zhēng)力較強(qiáng)的個(gè)體進(jìn)入下一輪繁殖。簡(jiǎn)化的Population聲明如下:
class Population
{
private:
std::vector m_Colony;
unsigned int m_iColonySize;
double m_dIntercrossRate,
m_dAgamogenesisRate,

m_dMutantRate;
std::vector m_BestGeneme;
public:
void Initial(unsigned int iColonySize,
double dIntercrossRate,
double dAgamogenesisRate,
double dMutantRate);
void Release();
void NexGeneration();
void KeepColonySize(unsigned int size = 100)
private:
void Intercross();
void Agamogenesis();
void Mutant();
};
Population用std::vector容器保存物種的所有個(gè)體(m_iColonySize個(gè)Chromosome的實(shí)例),m_dIntercrossRate、m_dAgamogenesisRate和m_dMutantRate三個(gè)變量分別是交叉率、復(fù)制率和變異率,其中染色體交叉是自然界中生物繁殖的最常見方式,可以保證優(yōu)秀的基因可以遺傳到下一代或者有很大的機(jī)會(huì)使得部分優(yōu)秀基因和另一部分優(yōu)秀基因結(jié)合為一個(gè)非常優(yōu)秀的染色體,因此交叉率比較高,一般取值在0.1~0.5之間;復(fù)制率即是無(wú)性繁殖的機(jī)率,無(wú)性繁殖在自然界中是普遍存在的正常現(xiàn)象(如植物中的落地生根和動(dòng)物中的蚯蚓),無(wú)性繁殖可以確保優(yōu)秀的個(gè)體有一定的機(jī)會(huì)壯大自己的種群,一般復(fù)制率取值在0.03~0.1之間;變異在自然界中是發(fā)生機(jī)率極小的事件,而且變異多是惡性的,所以變異率的取值范圍在0.005~0.05之間,但變異可以讓遺傳算法跳出局部最優(yōu),因而是必須的一個(gè)操作算子。m_iColonySize是種群的大小,種群越大,找到解的機(jī)會(huì)越大,但花費(fèi)的時(shí)間也相對(duì)比較多,一般設(shè)為可以接受的固定值,也可以編寫與問題難度相關(guān)的函數(shù)來決定,本實(shí)驗(yàn)使用m_iColonySize=100的固定值方式。
Population另外還有一個(gè)關(guān)鍵函數(shù)NextGeneration()是實(shí)現(xiàn)種群進(jìn)行一代繁殖操作的,它的實(shí)現(xiàn)如下:
void Population::NexGeneration(){
Intercross();
Agamogenesis();
Mutant();
}
很簡(jiǎn)單地調(diào)用了Intercross()、Agamogenesis()和Mutant()三個(gè)成員函數(shù),下面以Intercross()的實(shí)現(xiàn)為例看看這三個(gè)函數(shù)是怎么實(shí)現(xiàn)繁殖操作的:

void Population::Intercross(){
unsigned int iIntercrossTimes = static_cast(
m_Colony.size() * m_dIntercrossRate);
for(unsigned int i = 0; i < iIntercrossTimes; ++i){
unsigned int iChromoIdx1 = RangeRandom(0, m_Colony.size());
unsigned int iChromoIdx2 = RangeRandom(0, m_Colony.size());
if(iChromoIdx1 == iChromoIdx2){
++iChromoIdx2;
iChromoIdx2 = (iChromoIdx2 + 1) % m_Colony.size();
}
Chromosome* Chromo1 = new Chromosome;
Chromosome* Chromo2 = new Chromosome;
::Intercross(*m_Colony[iChromoIdx1],*m_Colony[iChromoIdx2],
*Chromo1, *Chromo2);
m_Colony.push_back(Chromo1);
m_Colony.push_back(Chromo2);
}
}
交叉操作先根據(jù)交叉率計(jì)算出要進(jìn)行多少次交叉繁殖,然后在執(zhí)行每一次交叉繁殖時(shí)隨機(jī)選擇兩個(gè)染色體調(diào)用前文的Intercross算子實(shí)施交叉,并將新產(chǎn)生的兩個(gè)新染色體加入到群體中。復(fù)制和變異都是相似的,因篇幅所限就不在這里贅述了,詳見源碼。

實(shí)驗(yàn)結(jié)果
遺傳算法是有效但費(fèi)時(shí)的一個(gè)算法。為了保證游戲運(yùn)行流暢,我們不可能在每一次刷新的時(shí)候都執(zhí)行一次遺傳算法。因此隔多久執(zhí)行一次遺傳算法和控制遺傳算法的遺傳代數(shù)是很重要的。demo中是在控球權(quán)發(fā)生改變時(shí)執(zhí)行遺傳算法為red-blue兩個(gè)球隊(duì)計(jì)算新的站位方案的。同時(shí)為了游戲能比較流暢,遺傳代數(shù)控制在20左右。
實(shí)驗(yàn)證明遺傳算法對(duì)足球的決策有非常好的效果,主要表現(xiàn)為:1、使用遺傳算法后,球員的站位比較到位,跑動(dòng)積極。比較少進(jìn)入Wait狀態(tài)的結(jié)果就是當(dāng)進(jìn)攻或者防守的時(shí)候很容易在周邊發(fā)現(xiàn)支持者可以輕易將球傳出。這使得看起來球員之間的配合非常有默契,攻守兩方都能打出更好的組合戰(zhàn)術(shù),增加了可觀賞性。簡(jiǎn)單來說,就是加了遺傳算法之后,踢的球越來越像人踢的。2、遺傳算法加強(qiáng)了球隊(duì)的對(duì)抗能力。未增加遺傳算法的時(shí)候,運(yùn)行本游戲20分鐘總進(jìn)球數(shù)在20~30,在增加遺傳算法后,20分鐘的總進(jìn)球數(shù)減少到10~20個(gè)。主要原因是球員的站位更加合理,能根據(jù)當(dāng)前的局勢(shì)變換站位,這非常有效地抵抗了進(jìn)攻,單刀入球也大大減少了。同時(shí),在變換站位時(shí)球員的跑動(dòng)積極,能夠很好地增加的搶球和斷球事件的發(fā)生,增強(qiáng)了兩隊(duì)的競(jìng)爭(zhēng)。
遺傳算法不僅可以用在球員的站位策略上,也可以用在確定傳球路線、尋找最佳射門角度和障礙回避等多個(gè)方面,在未來肯定會(huì)應(yīng)用更多游戲中去,歡迎大家一齊學(xué)習(xí)、探討。

贊助本站

相關(guān)內(nèi)容
AiLab云推薦
展開

熱門欄目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能實(shí)驗(yàn)室 版權(quán)所有    關(guān)于我們 | 聯(lián)系我們 | 廣告服務(wù) | 公司動(dòng)態(tài) | 免責(zé)聲明 | 隱私條款 | 工作機(jī)會(huì) | 展會(huì)港