简体   繁体   English

为什么我的国际象棋 Minimax 算法需要这么长时间来评估一步棋?

[英]Why is my Minimax algorithm for chess taking so long to evaluate a move?

I am trying to create a simple chess AI in C# and have so far been successful to an extent using the minimax algorithm with alpha-beta pruning.我正在尝试在 C# 中创建一个简单的国际象棋 AI,到目前为止,使用带有 alpha-beta 修剪的极小极大算法在一定程度上取得了成功。 However, with the code below it literally takes around 5 seconds for it to evaluate a move at depth 3 and I would like it to be faster if possible.但是,使用下面的代码,它实际上需要大约 5 秒的时间来评估深度 3 的移动,如果可能的话,我希望它更快。 I have been tinkering with it for hours and any change I make to it seems to just break the ai.我已经对它进行了几个小时的修补,我对它所做的任何更改似乎都会破坏 ai。 Any help is greatly appreciated!任何帮助是极大的赞赏!

private void makeAIMove(Piece[,] board)
{
    Move bestMove;
    int score;

    List<Piece[,]> possiblePositions = getAllPossiblePositions(board, Team.Black);
    List<Move> possibleMoves = getAllPossibleMoves(board, Team.Black);

    bestMove = possibleMoves[0];
    score = evaluatePosition(possiblePositions[0], int.MinValue, int.MaxValue, DEPTH, Team.White);
    if (numTurns > 0)
    {
        for (int i = 1; i < possiblePositions.Count; i++)
        {
            int pos = evaluatePosition(possiblePositions[i], int.MinValue, int.MaxValue, DEPTH, Team.White);
            if (pos >= score)
            {
                bestMove = possibleMoves[i];
                score = pos;
            }
        }
    }
    else
    {
        bestMove = possibleMoves[Random.Range(0, possibleMoves.Count)];
    }
    numTurns += 1;
    updateBoard(bestMove);
}

private int evaluatePosition(Piece[,] board1, int alpha, int beta, int depth, int team)
{
    Piece[,] board = (Piece[,])board1.Clone();
    if (depth == 0)
    {
        return evaluate(board);
    }
    if (team == Team.White)
    {
        List<Move> moves = getAllPossibleMoves(board, team);
        int newBeta = beta;
        foreach (Move moveName in moves)
        {
            fastMove(board, board[moveName.start.y, moveName.start.x], moveName);
            newBeta = Mathf.Min(newBeta, evaluatePosition(board, alpha, beta, depth - 1, oppositeTeam(team)));
            if (newBeta <= alpha) break;
        }
        return newBeta;
    }
    else
    {
        List<Move> moves = getAllPossibleMoves(board, team);
        int newAlpha = alpha;
        foreach (Move moveName in moves)
        {
            fastMove(board, board[moveName.start.y, moveName.start.x], moveName);
            newAlpha = Mathf.Max(newAlpha, evaluatePosition(board, alpha, beta, depth - 1, oppositeTeam(team)));
            if (beta <= newAlpha) break;
        }
        return newAlpha;
    }
}

It is hard to say exactly why since we don't see your entire code but here are a few suggestions on where to start looking:很难确切地说出原因,因为我们没有看到您的全部代码,但这里有一些关于从哪里开始寻找的建议:

  1. Your move generation code can be slow.您的移动生成代码可能很慢。 Try to make a perft test on some positions and see how many nodes/s you get.尝试对某些位置进行性能测试,看看你得到了多少个节点。 It should be in the millions if you have a well written code.如果你有一个写得很好的代码,它应该是数百万。

  2. Your evaluation can be slow.您的评估可能很慢。 Try to first just do a simple evaluation where you only calculate material for each side.尝试先做一个简单的评估,您只计算每一面的材料。

  3. It is weird that you have "if team == Team.White".奇怪的是你有“if team == Team.White”。 Does this mean that you always have the AI to play as black?这是否意味着你总是有 AI 来扮演黑人? Use as in the pseudo code instead for alpha/beta where you have the Maximizing player in if statement instead.在伪代码中使用 as 而不是 alpha/beta,在 if 语句中使用最大化播放器。

  4. You set newBeta = beta in the minimizing player loop (first if statement).您在最小化播放器循环(第一个 if 语句)中设置 newBeta = beta。 Here you should set newBeta = someLargeValue.在这里你应该设置 newBeta = someLargeValue。 Same for alpha in the else statement. else 语句中的 alpha 也是如此。 Also, I think it is better to use the term score in both cases to make it more clear.另外,我认为在这两种情况下都使用术语分数会更好,以使其更清楚。

  5. You forget to set new alpha and beta values.您忘记设置新的 alpha 和 beta 值。 In the first case it should be something like this:在第一种情况下,它应该是这样的:

     newBeta = Mathf.Min(newBeta, evaluatePosition(board, alpha, beta, depth - 1, oppositeTeam(team))); if (newBeta <= alpha) break; beta = Mathf.Min(beta, newBeta);

Please look at pseudo code and try to implement as closely as possible, it will make it more simple: https://en.wikipedia.org/wiki/Alpha%E2%80%93beta_pruning .请查看伪代码并尝试尽可能接近地实现,这将使它更简单: https://en.wikipedia.org/wiki/Alpha%E2%80%93beta_pruning Also consider make it Negamax instead which will simplify the logic even further: https://en.wikipedia.org/wiki/Negamax .还可以考虑改为使用 Negamax,这将进一步简化逻辑: https://en.wikipedia.org/wiki/Negamax This is a neccesity for making further optimizations down the road.这是进一步优化的必要条件。

When you get everything to work as expected you can start doing other things to improve performance such as move ordering and different pruning techniques.当你让一切都按预期工作时,你可以开始做其他事情来提高性能,例如移动顺序和不同的修剪技术。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么我的目录搜索需要这么长时间? - Why is my directory search taking so long? C# 中国际象棋的 MiniMax 算法无法正常工作 - MiniMax Algorithm with Chess in C# not working properly 为什么循环要花这么长时间又这么慢? - Why the loop is taking so long and so slow? 为什么需要这么长时间才能更新 - Why its taking so long to update 为什么Container.Configure需要这么长时间? - Why is Container.Configure taking so long? 当我从Visual Studio中运行程序时,为什么我的ComboBox需要这么长时间才能下载? - Why is my ComboBox taking so long to drop down when I run my program from within Visual Studio? 为什么实体框架dbSet.Include需要这么长时间才能返回? - Why is Entity Framework dbSet.Include taking so long to return? 为什么EF查询数据需要这么长时间才能加载到内存中? - Why is EF query data taking so long to load into memory? 为什么GC System.Threading.OverlappedData需要这么长时间? - Why is it taking so long to GC System.Threading.OverlappedData? 为什么我的行进立方体算法这么慢? - why is my marching cubes algorithm so slow?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM