问题描述
我正在使用 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 中发现了这个问题,因此它没有正确重置并在一块板上进行多次移动。