MiniMax 似乎正在做出所有可用的动作

问题描述

我正在使用 c# Monogame 制作国际象棋游戏。提前道歉我是编程新手,所以这可能是一个非常愚蠢的问题。在玩家移动后,MiniMax 被调用,但它似乎在进行每一个可用的移动,而不是选择具有最佳评估的移动。据我所知,我认为这可能是 getallmoves 函数的问题,但我找不到问题所在。可能值得注意的是, PieceList 是棋盘上剩余所有棋子的列表,而 Move 是一个类,其中包含进行移动后棋盘的状态以及对该棋盘的评估。在此先感谢您的帮助,非常感谢!

Board[intSelectedX,intSelectedY] = null;
Board[intX,intY] = strPieceSelected;
strPieceSelected = null;
PieceList[intIndex].intMoves += 1;

Board = MiniMax(Board,1,true).newBoard;  

public Move MiniMax(string[,] board,int intDepth,bool booIsMaximising)
    {
    if (intDepth == 0)
    {
        return new Move(board,intEvaluateBoard(board));
    }

    if (booIsMaximising)
    {
        maxEval = -999999;
        BestMove = null;

        foreach (Move move in getAllMoves(board))
        {
            evaluation = MiniMax(move.newBoard,intDepth - 1,false).Eval;
            maxEval = Math.Max(evaluation,maxEval);

            if (maxEval == evaluation)
            {
                BestMove = move;
            }
        }

        return (new Move(BestMove.newBoard,maxEval));
    }
    else
    {
        mineval = 999999;
        BestMove = null;

        foreach (Move move in getAllMoves(board))
        {
            evaluation = MiniMax(move.newBoard,true).Eva
            mineval = Math.Min(evaluation,mineval);

            if (mineval == evaluation)
            {
                BestMove = move;
            }
        }

        return (new Move(BestMove.newBoard,mineval));
    }
}

public List<Move> getAllMoves(string[,] board_)
{
    List<Move> MovesList = new List<Move>();
    string [,] tempBoard;

    foreach (Piece piece in getAllPieces())
    {

        for (int i = 0; i < 8; i++)
        {
            for (int j = 0; j < 8; j++)
            {
                if (board_[j,i] == strPiecesList[PieceList.IndexOf(piece)])
                {
                    intComputerX = j;
                    intComputerY = i;
                }
            }
        }

        for (int i = 0; i < 8; i++)
        {
            for (int j = 0; j < 8; j++)
            {
                tempBoard = board_;
                Piece tempPiece = piece;

                if (isValidMove(j,i,intComputerX,intComputerY,PieceList.IndexOf(tempPiece)) == true)
                {
                    if ((tempBoard[j,i] == null) || (tempBoard[j,i] != null && PieceList[strPiecesList.IndexOf(tempBoard[j,i])].strColour == "White"))
                    {
                        if (tempBoard[j,i] != null)
                        {
                            tempBoard[j,i] = null;
                        }

                        tempBoard[j,i] = tempBoard[intComputerX,intComputerY];
                        tempBoard[intComputerX,intComputerY] = null;

                        MovesList.Add(new Move(tempBoard,intEvaluateBoard(tempBoard)));
                    }
                }
            }
        }
    }
    return MovesList;
}

public List<Piece> getAllPieces()
{
    List<Piece> PiecesList = new List<Piece>();

    foreach (Piece piece in PieceList)
    {
        if (piece.strColour == "Black")
        {
            PiecesList.Add(piece);
        }
    }

    return PiecesList;
}

解决方法

我很确定你的 getAllMoves 不起作用,它绝对不会产生合法的国际象棋移动。

同时拥有游戏状态和评估的类是非常不寻常的。我会将评估分离为一个返回值的简单函数。这是正常的做法。

在极小极大循环中,您可以复制棋盘并在棋盘副本上进行移动,也可以进行移动、评估和取消移动。我看不出你做了任何这些,你只是在棋盘上做所有的动作?

,

我发现了这个问题,当我将 tempboard 重置为 board_tempboard 时,在 getallmoves 中发现了这个问题,因此它没有正确重置并在一块板上进行多次移动。