人机博弈-吃子棋游戏(四)搜索算法

来源:互联网 发布:suse linux 安装gcc 编辑:程序博客网 时间:2024/06/05 05:07

博弈树搜索技术简介:

博弈树的搜索算法,负值极大搜索,alpha-beta搜索,渴望搜索,PVS极窄窗口搜索等。通常来说,搜索算法常常和以下技术联合在一起。

如下:

1.置换表,记录已经搜索过的棋局,避免再次搜索。

2.吃子启发,优先试下能够吃对方棋子的走法。

3.杀手启发,历史启发简化版。

4.历史启发,优先试下历史统计数据得出的比较好的走法。

5.静止期搜索,继续对某些叶子结点搜索,避免水平线效应。

6.迭代加深搜索,根据搜索时间,状态。决定是否继续搜索。

 有兴趣的朋友可以深入研究一下上述技术和算法。

 

吃子棋搜索算法:

我的程序最初的实现使用的负值极大搜索算法,之后改用alpha-beta搜索算法,后来又使用PVS极窄窗口搜索算法。

在我自己的实现里没有使用置换表,历史启发等技术。是因为吃子棋每层的走法数相对较少,所以并没有使用。

但我们知道,这些技术可以很大的提高搜索效率。

 

吃子棋搜索算法源码:

接下来,看看吃子棋搜索算法的源代码:

负值极大算法

int CNegaMaxEngine::negaMax(int depth){    int currentMaxScore = -20000;//init value mini    int score;    int nextMoveCount;    int overNum = IsGameOver(CurPosition, depth);    if (overNum != 0)return overNum;    if (depth <= 0)        return m_pEval->Eveluate(CurPosition, (m_nMaxDepth - depth ) % 2 );    nextMoveCount = m_pMG->CreatePossibleMove(CurPosition, depth, (m_nMaxDepth - depth) % 2);    for (int i = 0; i < nextMoveCount; i++)    {        MakeMove(&m_pMG->m_MoveList[depth][i], (m_nMaxDepth - depth) % 2);        score = -negaMax(depth-1);        UnMakeMove(&m_pMG->m_MoveList[depth][i]);        if (score>currentMaxScore)        {            currentMaxScore = score;            if (depth == m_nMaxDepth){                            m_cmBestMove = m_pMG->m_MoveList[depth][i];            }        }    }    return currentMaxScore;}
alpha-beta算法
int CAlphtBetaEngine::alphabeta(int depth,int alpha ,int beta){        int score;    int nextMoveCount;    int overNum = IsGameOver(CurPosition, depth);        if (overNum != 0)return overNum;    int whoTurn = (m_nMaxDepth - depth) % 2;    if (depth <= 0)        return m_pEval->Eveluate(CurPosition, whoTurn);    nextMoveCount = m_pMG->CreatePossibleMove(CurPosition, depth, whoTurn);    for (int i = 0; i < nextMoveCount; i++)    {        MakeMove(&m_pMG->m_MoveList[depth][i], whoTurn);        score = -alphabeta(depth - 1, -beta, -alpha);        UnMakeMove(&m_pMG->m_MoveList[depth][i]);        if (score>alpha)        {            alpha = score;            if (depth == m_nMaxDepth){                m_cmBestMove = m_pMG->m_MoveList[depth][i];            }        }        if (alpha >= beta)break;    }    return alpha;}

PVS算法:

int CPVS_Engine::PrincipalVariation(int depth, int alpha, int beta){    int score;    int Count, i;    BYTE type;    int best;    i = IsGameOver(CurPosition, depth);    if (i != 0)        return i;    if (depth <= 0)    //叶子节点取估值        return m_pEval->Eveluate(CurPosition, false);    Count = m_pMG->CreatePossibleMove(CurPosition, depth, (m_nMaxDepth - depth ) % 2);     MakeMove(&m_pMG->m_MoveList[depth][0], (m_nMaxDepth - depth ) % 2);    best = -PrincipalVariation(depth - 1, -beta, -alpha);    UnMakeMove(&m_pMG->m_MoveList[depth][0]);    if (depth == m_nMaxDepth)        m_cmBestMove = m_pMG->m_MoveList[depth][0];    for (i = 1; i<Count; i++)    {        if (best < beta)        {            if (best > alpha)                alpha = best;            MakeMove(&m_pMG->m_MoveList[depth][i], (m_nMaxDepth - depth ) % 2);            score = -PrincipalVariation(depth - 1, -alpha - 1, -alpha);            if (score > alpha && score < beta)            {                best = -PrincipalVariation(depth - 1, -beta, -score);                if (depth == m_nMaxDepth)                    m_cmBestMove = m_pMG->m_MoveList[depth][i];            }            else if (score > best)            {                best = score;                if (depth == m_nMaxDepth)                    m_cmBestMove = m_pMG->m_MoveList[depth][i];            }            UnMakeMove(&m_pMG->m_MoveList[depth][i]);        }    }    return best;}


0 0