問一下有關博弈樹的編程問題(100分求教)


對於一個人機對弈的棋游戲,在當前棋局狀態下構造了博弈樹,其中某枝
必定是下一個回合后所產生的博弈樹的根部分,為了不再重復搜索已搜索
的樹枝,並且盡可能的縮短時間,盡可能減少內存分配或釋放指令但又要
保證內存的有效利用率?
請問該怎么用C\C++編程實現?

另外,哪位高手能給點alpha-beta剪枝的資料或源碼。//bow

10 个解决方案

#1


hash; killer move list

#2


具體怎么編程實現呢?有比較詳細注釋的源碼嗎?

#3


我有,留下Email 或發短信息。

#4


sprime@eyou.com
謝謝

#5


自己到網上找找,應該可以找到相關資料。
可以看看http://windz.jzwm.com/doc/wuziqi.htm
此外,還要對搜索算法進行優化,只用alpha-beta剪枝效果很差,要加上歷史啟發等等。

#6


樓上的大俠能說說怎么加歷史啟發(網上搜不到這個)嗎?或者其它的優化措施,
thx
在博弈樹方面我是個初學者.

#7


我做的五子棋的博弈樹算法,你可以參考一下,以下是主要部分


void computer_do(void)
{
int i;

for(i=0;i<s.k;i++) //計算第一層結點的個數successornum逐一產生s結點的子狀態,分別送入successor[1...successornum]
{
successor[i]=s;
successor[i].state[s.limit[i][0]][s.limit[i][1]]='*';
successor[i].col=s.limit[i][0];
successor[i].row=s.limit[i][1];
}
value=-maxint;
for(i=0;i<s.k;i++)
{
successor[i].value=search(successor[i],player,value,0);//逐一求出第一層中每個子結點的倒推值
value=select(value,successor[i].value,computer); //取其中最大的倒推值賦根結點
}
for(i=0;i<s.k;i++)
if(value==successor[i].value)
{
s=successor[i]; //求出具有與根結點相同倒推值的那個子結點存入s,作為下一步走
drawbar(s.col,s.row);
mode=player; //下一步輪對方走
MoveTo(750,500);
SetColor(LightGreen);
LineWriteASCII("I have put a chess!");
break;
}
}




int search(node q,modetype mode,int oldvalue,int depth)
//search為帶α-β裁剪的極大極小過程,通過后序遍歷的方法構造以q結點為根的博奕樹
//q--待擴展結點;mode--走步對象;oldvalue--父結點的倒推值;depth--當前深度
{
node successor,*p; //q的子結點
int value; //q的當前倒推值
int i;

p=&q;
if((depth<maxdepth)&&(abs(evlation(q,mode))!=maxint))
{
if(mode==computer)
value=-maxint;
else
value=maxint;
search_all(p);
for(i=0;i<q.k;i++) //在循環結構中逐一擴展和處理q的子結點
{
if(!(((mode==computer)&&(value>oldvalue))||((mode==player)&&(value<oldvalue))))
//若q結點不滿足α-β裁剪條件,則擴展q的子結點successor
{
successor=q;
//根據走步對象mode值,擴展出q結點的子結點successor
if(mode==computer)
successor.state[q.limit[i][0]][q.limit[i][1]]='*';
else
successor.state[q.limit[i][0]][q.limit[i][1]]='@';
successor.col=q.limit[i][0];
successor.row=q.limit[i][1];
//通過后序遍歷求出q結點的當前倒推值
if(mode==computer)
value=select(value,search(successor,player,value,depth+1),computer);
else
value=select(value,search(successor,computer,value,depth+1),player);
}


}

return value;
}
else
//若q結點狀態為一方獲勝的格局,則q結點的倒推值為極大(或極小)值
return evlation(q,mode);
//若到達深度限制,則葉結點q的倒推值即為估價函數值


}

int select(int a,int b,modetype mode)
//a--結點當前的倒推值;b--其子結點的倒推值;mode--倒推值為a的那個結點所對應的走步對象
//若輪computer方走步,則在倒推值為a和b的兩個結點之間選擇具有最大倒推值的結點,該最大值作為
//computer結點的當前倒推值;若輪player走步,則在倒推值為a和b的兩個結點之間選擇具有最小倒推值
//的結點,該最大值作為player結點的當前倒推值
{
if(((a>b)&&(mode==computer))||((a<b)&&(mode==player)))
return a;
else
return b;
}

#8


http://thecct.51.net 
http://www.gamedev.net/reference/
http://www.maths.nottingham.ac.uk/personal/anw/G13GAM/header.html

電腦報出了一本人機博弈編程的書,介紹了中國象棋的實例。

#9


書上附帶原代碼我已發過去,注意查收,里面有很多搜索算法。

#10


zhengzewei(zzw) 的源碼不錯,thanks :)
也感謝glanatiess(bamboo)

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com