我怎样才能使这个极小极大算法完美地工作
How can I make this minimax algorithm work perfectly
我一直在尝试在 tic-tac-toe 游戏 unity3d 中实现 minimax(negamax) C# 算法,它在几乎最终状态下运行良好(每个玩家大约 2 件预先放置在棋盘上开始时),我只是无法在开始时从空白板上做出完美的决定。
//recursive function call
internal AIMove GetBestMove(char[] board, char player)
{
// testboard = board;
AIMove bestMove = null;
for (int i = 0; i < moveTile.emptyPoints.Count; i++)
{
AIMove move = new AIMove();
move.point = System.Convert.ToInt32(moveTile.emptyPoints[i].name);
board[System.Convert.ToInt32(moveTile.emptyPoints[i].name)] = player == GameManager.Player2Piece ? GameManager.Player2Piece : GameManager.Player1Piece; // If player is O use O else use X
var rv = CheckVictorySim(board, player, System.Convert.ToInt32(moveTile.emptyPoints[i].name));
// print(rv);
if (rv == 10) //AI wins
{
move.score = 1;
}
else if (rv == -10) // AI loses
{
move.score = -1;
}
else if (rv == 0) // draw
{
move.score = 0;
}
else if (rv == -1) //other
{
char[] newboard = new char[9]; //System.Array.Copy(umpire.board, newboard, 9); //board state
move.score = -GetBestMove(newboard, player == GameManager.Player2Piece ? GameManager.Player1Piece : GameManager.Player2Piece).score; // if player is O use X else use O
}
if (bestMove == null || move.score > bestMove.score)
{
bestMove = move;
}
//aiMoves.Add(bestMove);
print(bestMove.point);
}
//return the best move
return bestMove;
}
我认为一个问题是您将一个空的(刚创建的)板传递给 GetBestMove 的递归调用:
char[] newboard = new char[9];
move.score = -GetBestMove(newboard, /*other args*/)
所以基本上所有关于棋盘上发生的动作的信息都丢失了。您应该使用实际棋盘的副本调用 GetBestMove 函数。
另一件事是一旦你设置好
move.point = System.Convert.ToInt32(moveTile.emptyPoints[i].name);
您可以使用 move.point
而不是 System.Convert.ToInt32(moveTile.emptyPoints[i].name)
在适当的地方避免重复并使您的代码更具可读性。
我一直在尝试在 tic-tac-toe 游戏 unity3d 中实现 minimax(negamax) C# 算法,它在几乎最终状态下运行良好(每个玩家大约 2 件预先放置在棋盘上开始时),我只是无法在开始时从空白板上做出完美的决定。
//recursive function call
internal AIMove GetBestMove(char[] board, char player)
{
// testboard = board;
AIMove bestMove = null;
for (int i = 0; i < moveTile.emptyPoints.Count; i++)
{
AIMove move = new AIMove();
move.point = System.Convert.ToInt32(moveTile.emptyPoints[i].name);
board[System.Convert.ToInt32(moveTile.emptyPoints[i].name)] = player == GameManager.Player2Piece ? GameManager.Player2Piece : GameManager.Player1Piece; // If player is O use O else use X
var rv = CheckVictorySim(board, player, System.Convert.ToInt32(moveTile.emptyPoints[i].name));
// print(rv);
if (rv == 10) //AI wins
{
move.score = 1;
}
else if (rv == -10) // AI loses
{
move.score = -1;
}
else if (rv == 0) // draw
{
move.score = 0;
}
else if (rv == -1) //other
{
char[] newboard = new char[9]; //System.Array.Copy(umpire.board, newboard, 9); //board state
move.score = -GetBestMove(newboard, player == GameManager.Player2Piece ? GameManager.Player1Piece : GameManager.Player2Piece).score; // if player is O use X else use O
}
if (bestMove == null || move.score > bestMove.score)
{
bestMove = move;
}
//aiMoves.Add(bestMove);
print(bestMove.point);
}
//return the best move
return bestMove;
}
我认为一个问题是您将一个空的(刚创建的)板传递给 GetBestMove 的递归调用:
char[] newboard = new char[9];
move.score = -GetBestMove(newboard, /*other args*/)
所以基本上所有关于棋盘上发生的动作的信息都丢失了。您应该使用实际棋盘的副本调用 GetBestMove 函数。
另一件事是一旦你设置好
move.point = System.Convert.ToInt32(moveTile.emptyPoints[i].name);
您可以使用 move.point
而不是 System.Convert.ToInt32(moveTile.emptyPoints[i].name)
在适当的地方避免重复并使您的代码更具可读性。