【问题标题】:C++ 4 In a row AlphaBeta algorithm is not very smartC++ 4 连续 AlphaBeta 算法不是很聪明
【发布时间】:2018-03-27 12:02:24
【问题描述】:

我正在为一个学校项目制作一个 AI 控制的 alpha-beta 算法,但我的算法非常不一致。有时它会成功阻止我的所有动作,有时它会忽略我的连续 3 个动作,如 here 所示。这怎么会发生?我该如何解决这个问题?

int alphaBeta(const State board, int alpha, int beta, const Player player, int depth)
{
    //Max player = Player::O
    //Min player = Player::X

    std::vector<Move> possibleMoves = getMoves(board);

    if(eval(board)==Player::X){return 9999-depth;}      //Player X wins
    else if(eval(board)==Player::O){return -9999+depth;}    //Player O wins
    else if(possibleMoves.size()==0){return 0;}     //Tie
    else{   //Zoek verder
        depth++;
        State nextBoard = board;
        int result;

        if(player==Player::O){
            for (Move move: possibleMoves) {
                nextBoard = doMove(nextBoard, move);
                result = alphaBeta(nextBoard, alpha, beta, Player::X, depth);
                if (result > alpha){    
                    alpha = result; 
                    if (depth == 1){
                                    choice = move; //The actual move he will do
                    }
                }
                else if (alpha >= beta){ 
                    return alpha; 
                }
            }
            return alpha;
        }

        else{
            for (Move move: possibleMoves) {
                nextBoard = doMove(nextBoard, move);
                result = alphaBeta(nextBoard, alpha, beta, Player::O, depth);
                if (result < beta){ 
                    beta = result;
                    if (depth == 1){
                                    choice = move;
                    }
                }
                else if (beta <= alpha){ 
                    return beta;
                }
            }
            return beta;
        }
    }
}

【问题讨论】:

  • 我建议您熟悉一下ClangFormat ;)
  • 欢迎来到 StackOverflow。请按照您创建此帐户时的建议阅读并遵循帮助文档中的发布指南。 Minimal, complete, verifiable example 适用于此。在您发布 MCVE 代码并准确描述问题之前,我们无法有效地帮助您。我们应该能够将您发布的代码粘贴到文本文件中并重现您描述的问题。
  • 您发布的代码仅定义了一个函数并退出而不执行。没有尝试跟踪逻辑和数据流。请参阅这个可爱的 debug 博客寻求帮助。
  • 哇,对不起。我会尽快解决的。

标签: c++ algorithm artificial-intelligence alpha-beta-pruning coderef


【解决方案1】:

您反复修改nextBoard,向其添加(可能是非法的)移动:

nextBoard = doMove(nextBoard, move);

但你应该在原来的棋盘上依次尝试每一步:

State nextBoard = doMove(board, move);

(免责声明:也可能存在其他问题。)

【讨论】:

  • 嗯,但现在我每次使用它时都需要撤消原始板上的移动,对吗?编辑:机器人现在一直将它们全部放在第 0 行,一旦它有 3 个圆圈,他将 3 放在第 1 行等...
  • @KevinSnijder 假设 doMove 没有修改它的 board 参数(否则,为什么要返回一个 board?),您不需要撤消任何操作。如果它确实修改它,让它停止。递归和变异是一种令人不快的组合。
  • 嗯谢谢你的帮助,doMove 会复制它收到的棋盘并返回移动的结果。但还是。使用您的解决方案,我的机器人出于某种原因一直将它们放在第 0 行。 State doMove(const State &amp;state, const Move &amp;m) { State result = state; for (int r=0; r&lt;6; r++) { if (r == 5 || result[r+1][m] != Player::None) { result[r][m] = getCurrentPlayer(state); return result; } } return result; // Invalid move }
  • @KevinSnijder 看起来您的移动搜索已在possibleMovesdoMove 之间“拆分”。将搜索留给possibleMoves,只在doMove 中执行。
  • 我不太清楚你所说的“拆分”是什么意思,我从老师那里得到了 doMove 功能,我应该改变它吗?
【解决方案2】:

1) 不要评估递归调用中的每个节点,那样会耗费太多时间。仅评估叶节点。

2) 在minimax递归调用中使用边界条件,如果深度大于某个值则终止;每个分支都不会导致获胜的举动,搜索会太大,程序可能会挂起。

3) 考虑在顶级分支上使用多线程来加快搜索速度。

int alphaBeta(const State board, int alpha, int beta, const Player player, int depth)
{
    std::vector<Move> possibleMoves = getMoves(board);

    if(CheckForWinX(board))
    {
        return 9999;
    }      
    else 
        if(CheckForWinO(board))
    {
        return -9999;
    }   
    else 
        if(possibleMoves.size()==0)
    {
        return 0;
    }     
    else 
        if( depth >= 5)   // without this boundary condition, the search tree will too big 
    { 
        return eval(board);    // evaluate ( which is more time expensive than CheckForWin() ) only the leaf node, not every nodes 
    }
    else{   
        depth++;
        State nextBoard = board;
        int result;

        if(player==Player::O){
              /**/
            return alpha;
        }
        else{
             /**/
            return beta;
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-04
    相关资源
    最近更新 更多