关于五子棋博弈树的算法
大一新生在搞建模,弄一个五子棋的获胜策略现在就是整体思路有了,但是程序写不出来
网上有很多人机对战的算法,但是我们做的是从一个己经形成的阵法开始,一个电脑模拟两个人进行比赛,两方同时使用博弈树程序知道一方胜出,所以就跟网上给的有点不同
下面是网上给的五子棋算法的一段,而我并没有看懂这个的目的和作用。。求大神解答。。。
//将历史记录表中所有项目全置为初值
void ResetHistoryTable()
{
memset(m_HistoryTable,10,GRID_COUNT*sizeof(int));
}
//从历史得分表中取给定走法的历史得分
int GetHistoryScore(STONEMOVE* move)
{
return m_HistoryTable[move->StonePos.x][move->StonePos.y];
}
//将一最佳走法汇入历史记录
void EnterHistoryScore(STONEMOVE* move,int depth)
{
m_HistoryTable[move->StonePos.x][move->StonePos.y]+=2<<depth;
}
//对走法队列从小到大排序
//STONEMOVE* source原始队列
//STONEMOVE* target目标队列
//合并source[l…m]和 source[m +1…r]至target[l…r]
void Merge(STONEMOVE* source,STONEMOVE* target,int l,int m,int r)
{
//从小到大排序
int i=l;
int j=m+1;
int k=l;
while(i<=m && j<=r)
if(source[i].Score<=source[j].Score)
target[k++]=source[i++];
else
target[k++]=source[j++];
if(i>m)
for(int q=j;q<=r;q++)
target[k++]=source[q];
else
for(int q=i;q<=m;q++)
target[k++]=source[q];
}
void Merge_A(STONEMOVE* source,STONEMOVE* target,int l,int m,int r)
{
//从大到小排序
int i=l;
int j=m+1;
int k=l;
while(i<=m &&j<=r)
if(source[i].Score>=source[j].Score)
target[k++]=source[i++];
else
target[k++]=source[j++];
if(i>m)
for(int q=j;q<=r;q++)
target[k++]=source[q];
else
for(int q=i;q<=m;q++)
target[k++]=source[q];
}
//合并大小为 S 的相邻子数组
//direction 是标志,指明是从大到小还是从小到大排序
void MergePass(STONEMOVE* source,STONEMOVE* target,const int s,const int n,const bool direction)
{
int i=0;
while(i<=n-2*s)
{
//合并大小为 s的相邻二段子数组
if(direction)
Merge(source,target,i,i+s-1,i+2*s-1);
else
Merge_A(source,target,i,i+s-1,i+2*s-1);
i=i+2*s;
}
if(i+s<n)//剩余的元素个数小于2s
{
if(direction)
Merge(source,target,i,i+s-1,n-1);
else
Merge_A(source,target,i,i+s-1,n-1);
}
else
for(int j=i;j<=n-1;j++)
target[j]=source[j];
}
void MergeSort(STONEMOVE* source,int n,bool direction)
{
int s=1;
while(s<n)
{
MergePass(source,m_TargetBuff,s,n,direction);
s+=s;
MergePass(m_TargetBuff,source,s,n,direction);
s+=s;
}
}
int CreatePossibleMove(unsigned char position[][GRID_NUM], int nPly, int nSide)
{
int i,j;
m_nMoveCount=0;
for(i=0;i<GRID_NUM;i++)
for(j=0;j<GRID_NUM;j++)
{
if(position[i][j]==(unsigned char)NOSTONE)
AddMove(j,i,nPly);
}
//使用历史启发类中的静态归并排序函数对走法队列进行排序
//这是为了提高剪枝效率
// CHistoryHeuristic history;
MergeSort(m_MoveList[nPly],m_nMoveCount,0);
return m_nMoveCount;//返回合法走法个数
}
//在m_MoveList中插入一个走法
//nToX是目标位置横坐标
//nToY是目标位置纵坐标
//nPly是此走法所在的层次
int AddMove(int nToX, int nToY, int nPly)
{
m_MoveList[nPly][m_nMoveCount].StonePos.x=nToX;
m_MoveList[nPly][m_nMoveCount].StonePos.y=nToY;
m_nMoveCount++;
m_MoveList[nPly][m_nMoveCount].Score=PosValue[nToY][nToX];//使用位置价值表评估当前走法的价值
return m_nMoveCount;
}
void CNegaScout_TT_HH()
{
ResetHistoryTable();
// m_pThinkProgress=NULL;
}
void SearchAGoodMove(unsigned char position[][GRID_NUM],int Type)
{
int Score;
memcpy(CurPosition,position,GRID_COUNT);
m_nMaxDepth=m_nSearchDepth;
CalculateInitHashKey(CurPosition);
ResetHistoryTable();
Score=NegaScout(m_nMaxDepth,-20000,20000);
X=m_cmBestMove.StonePos.y;
Y=m_cmBestMove.StonePos.x;
MakeMove(&m_cmBestMove,Type);
memcpy(position,CurPosition,GRID_COUNT);
}