首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Minimax Beta剪枝不起作用,但Minimax单独起作用

Minimax Beta剪枝不起作用,但Minimax单独起作用
EN

Stack Overflow用户
提问于 2021-02-09 22:31:35
回答 1查看 99关注 0票数 0

我的问题是在对Minimax应用Alpha/Beta修剪时。它做了非常奇怪和糟糕的动作。当我使用没有Alpha/Beta的Minimax时,它工作得很好。这两个函数如下所示:

带有Alpha/Beta剪枝的Minimax:

代码语言:javascript
运行
复制
public int minimaxAB(Piece[,] board, int depth, int a, int b, bool maximizingPlayer, bool WhiteToPlay)
{
    if (depth == 0)
    {
        return EvaluatePosition(board, WhiteToPlay);
    }

    var moves = GenerateMoves(board, WhiteToPlay);
    if (maximizingPlayer)
    {
        int value = int.MinValue;
        foreach (var move in moves)
        {
            int minmaxResult = minimaxAB(move, depth - 1, a, b, false, !WhiteToPlay);
            value = Math.Max(value, minmaxResult);

            a = Math.Max(a, value);

            if (a >= b)
                return a;

            if (depth == depthB)
            {
                moveScores.Add(move, minmaxResult);
            }
        }
        return value;
    }
    else
    {
        int value = int.MaxValue;
        foreach (var move in moves)
        {
            int minmaxResult = minimaxAB(move, depth - 1, a, b, true, !WhiteToPlay);
            value = Math.Min(value, minmaxResult);

            b = Math.Min(b, value);

            if (b <= a)
                return b;

            if (depth == depthB)
            {
                moveScores.Add(move, minmaxResult);
            }
        }
        return value;
    }
}

没有A/B的Minimax:

代码语言:javascript
运行
复制
public int minimax(Piece[,] board, int depth, bool maximizingPlayer, bool WhiteToPlay)
{
    if (depth == 0)
    {
        int result = EvaluatePosition(board, WhiteToPlay);
        return result;
    }

    var moves = GenerateMoves(board, WhiteToPlay);
    if (maximizingPlayer)
    {
        int value = int.MinValue;
        foreach (var move in moves)
        {
            int minmaxResult = minimax(move, depth - 1, false, !WhiteToPlay);
            value = Math.Max(value, minmaxResult);
            if (depth == depthB)
            {
                moveScores.Add(move, minmaxResult);
            }
        }
        return value;
    }
    else
    {
        int value = int.MaxValue;
        foreach (var move in moves)
        {
            int minmaxResult = minimax(move, depth - 1, true, !WhiteToPlay);
            value = Math.Min(value, minmaxResult);
            if (depth == depthB)
            {
                moveScores.Add(move, minmaxResult);
            }
        }
        return value;
    }
}

我的求值函数:

代码语言:javascript
运行
复制
public int EvaluatePosition(Piece[,] boardPos, bool ForWhite)
{
    int eval_W = 0;
    int eval_B = 0;
    int eval = 0;
    for (int i = 0; i < 8; i++)
    {
        for (int j = 0; j < 8; j++)
        {
            if (boardPos[i, j] != Piece.Empty)
            {
                if (IsPieceWhite(boardPos[i, j]))
                {
                    eval_W += GetPieceWorth(boardPos[i, j]) + DistanceToCenter(i, j);
                    eval += GetPieceWorth(boardPos[i, j]);
                }
                else if (IsPieceBlack(boardPos[i, j]))
                {
                    eval_B += GetPieceWorth(boardPos[i, j]) + DistanceToCenter(i, j);
                    eval -= GetPieceWorth(boardPos[i, j]);
                }
            }
        }
    }

    if (ForWhite)
        return eval_W - eval_B;
    else
        return eval_B - eval_W;
}

我使用的是:minimaxAB(CurrentBoard, depthB, int.MinValue, int.MaxValue, true, whiteToMove);

我知道带有AB的Minimax应该会产生完全相同的结果,但在我的例子中并非如此。我希望有人能发现我做错了什么。

EN

回答 1

Stack Overflow用户

发布于 2021-02-10 23:52:25

我弄明白了,我需要一个白和黑的alpha和beta。这是因为我对白色和黑色移动都调用了minimaxAB函数。

工作方法:

代码语言:javascript
运行
复制
public int minimaxAB(Piece[,] board, int depth, int alpha_White, int beta_White, int alpha_Black, int beta_Black, bool maximizingPlayer, bool WhiteToPlay)
{
    if (depth == 0 || !HasKings(board))
    {
        return EvaluatePosition(board, WhiteToPlay);
    }

    var moves = GenerateMoves(board, WhiteToPlay);
    if (maximizingPlayer)
    {
        int value = int.MinValue;
        foreach (var move in moves)
        {
            int minmaxResult = minimaxAB(move, depth - 1, alpha_White, beta_White, alpha_Black, beta_Black, false, !WhiteToPlay);
            value = Math.Max(value, minmaxResult);

            if (WhiteToPlay)
            {
                alpha_White = Math.Max(alpha_White, value);
                if (alpha_White >= beta_White)
                    return alpha_White;
            }
            else
            {
                alpha_Black = Math.Max(alpha_Black, value);
                if (alpha_Black >= beta_Black)
                    return alpha_Black;
            }

            if (depth == depthB)
            {
                moveScores.Add(move, minmaxResult);
            }
        }
        return value;
    }
    else
    {
        int value = int.MaxValue;
        foreach (var move in moves)
        {
            int minmaxResult = minimaxAB(move, depth - 1, alpha_White, beta_White, alpha_Black, beta_Black, true, !WhiteToPlay);
            value = Math.Min(value, minmaxResult);

            if (WhiteToPlay)
            {
                beta_White = Math.Min(beta_White, value);
                if (beta_White <= alpha_White)
                    return beta_White;
            }
            else
            {
                beta_Black = Math.Min(beta_Black, value);
                if (beta_Black <= alpha_Black)
                    return beta_Black;
            }
            if (depth == depthB)
            {
                moveScores.Add(move, minmaxResult);
            }
        }
        return value;
    }
}

调用时使用:

代码语言:javascript
运行
复制
minimaxAB(CurrentBoard, depthB, int.MinValue, int.MaxValue, int.MinValue, int.MaxValue, true, whiteToMove);
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66121002

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档