我想編程一個國際象棋遊戲,並花了幾天的時間來修復代碼。我甚至嘗試了最小值,但以相同的結果結束。人工智能總是從角落開始,並將一個棋子移開,然後每次轉動時,這隻車就會前後移動。如果它被吃掉,那麼AI會將每一塊從一側移動到另一側,直到所有食物都被吃掉。你知道下面的代碼有什麼問題嗎?negamax算法..有什麼不對?
public Move MakeMove(int depth)
{
bestmove.reset();
bestscore = 0;
score = 0;
int maxDepth = depth;
negaMax(depth, maxDepth);
return bestmove;
}
public int EvalGame() //calculates the score from all the pieces on the board
{
int score = 0;
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
if (AIboard[i, j].getPiece() != GRID.BLANK)
{
score += EvalPiece(AIboard[i, j].getPiece());
}
}
}
return score;
}
private int negaMax(int depth, int maxDepth)
{
if (depth <= 0)
{
return EvalGame();
}
int max = -200000000;
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
for (int k = 0; k < 8; k++)
{
for (int l = 0; l < 8; l++)
{
if(GenerateMove(i, j, k, l)) //generates all possible moves
{
//code to move the piece on the board
board.makemove(nextmove);
score = -negaMax(depth - 1, maxDepth);
if(score > max)
{
max = score;
if (depth == maxDepth)
{
bestmove = nextmove;
}
}
//code to undo the move
board.undomove;
}
}
}
}
}
return max;
}
public bool GenerateMove(int i, int j, int k, int l)
{
Move move;
move.moveFrom.X = i;
move.moveFrom.Y = j;
move.moveTo.X = k;
move.moveTo.Y = l;
if (checkLegalMoves(move.moveTo, move.moveFrom)) //if a legal move
{
nextMove = move;
return true;
}
return false;
}
是最好的移動全局變量?如果是,那就錯了。您的negamax函數的每個遞歸調用將使用bestmove的同一副本,而您希望每個調用都擁有它自己的副本。它不言而喻,但你應該(幾乎)不會使用全局變量。 –
@MathieuPagé仔細觀察,似乎在他的案件中解決。他從不在搜索例程中使用最佳移動,並且搜索退出的最後一個節點將成爲根節點。 – Zong
@宗正立你說得對。但它仍然不是一個好主意。 –