| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1887 人关注过本帖
标题:关于五子棋博弈树的算法
只看楼主 加入收藏
不想取名字
Rank: 1
等 级:新手上路
帖 子:1
专家分:0
注 册:2015-11-28
收藏
 问题点数:0 回复次数:0 
关于五子棋博弈树的算法
大一新生在搞建模,弄一个五子棋的获胜策略
现在就是整体思路有了,但是程序写不出来
网上有很多人机对战的算法,但是我们做的是从一个己经形成的阵法开始,一个电脑模拟两个人进行比赛,两方同时使用博弈树程序知道一方胜出,所以就跟网上给的有点不同
下面是网上给的五子棋算法的一段,而我并没有看懂这个的目的和作用。。求大神解答。。。

//将历史记录表中所有项目全置为初值  
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);  
}  

搜索更多相关主题的帖子: 大一新生 五子棋 记录表 
2015-11-28 20:20
快速回复:关于五子棋博弈树的算法
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.017906 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved