如果 min max 算法容易自毁,如何修复它?
How to fix the min max algorithm if it tends to self-destruct?
我正在尝试使用 MinMax 将 AI 算法编写到跳棋游戏中。在最终测试之前一切都很好......计算机选择任何一块然后他就会来找我的人。他真的很想快点死。这是我的代码:
public MoveAndPoints MinMax(Dictionary<int, Field> gameBoard, string myColor, Boolean maximizingPlayer, int depth)
{
MoveAndPoints bestValue = new MoveAndPoints();
if (0 == depth)
{
return new MoveAndPoints(((myColor == enemyColor) ? 1 : -1) * evaluateGameBoard(gameBoard, myColor), bestValue.move);
}
MoveAndPoints val = new MoveAndPoints();
if (maximizingPlayer)
{
bestValue.points = int.MinValue;
foreach (Move move in GetPossibleMoves(gameBoard, myColor))
{
gameBoard = ApplyMove(gameBoard, move);
bestValue.move = move;
val = MinMax(gameBoard, Extend.GetEnemyPlayerColor(myColor), false, depth - 1);
bestValue.points = Math.Max(bestValue.points, val.points);
gameBoard = RevertMove(gameBoard, move);
}
return bestValue;
}
else
{
bestValue.points = int.MaxValue;
foreach (Move move in GetPossibleMoves(gameBoard, myColor))
{
gameBoard = ApplyMove(gameBoard, move);
val = MinMax(gameBoard, Extend.GetEnemyPlayerColor(myColor), true, depth - 1);
bestValue.points = Math.Min(bestValue.points, val.points);
gameBoard = RevertMove(gameBoard, move);
}
return bestValue;
}
}
这是我的启发:
public int evaluateGameBoard(Dictionary<int, Field> gameBoard, string color)
{
return Extend.GetNumberOfPieces(gameBoard, color) - Extend.GetNumberOfPieces(gameBoard, Extend.GetEnemyPlayerColor(color));
}
比如我有那个场景:
他选择去死而不是移动到任何其他地方:
如果我自己选择死亡,他只会杀了我,因为他必须这样做,因为这是他唯一的举动。
有人可以帮我解决这个问题吗?我认为问题出在 MinMax 内部。我几乎可以肯定这不是很成问题,但我真的找不到它:(
这是我的树的深度 3:
我没有你所有的代码,所以我无法完全验证这些。但是,我相信至少你的问题之一是你在玩家之间混合颜色。在您的 MinMax 调用中,您为两个位置传递了相同的颜色:
这是最大化播放器中的调用:
val = MinMax(gameBoard, Extend.GetEnemyPlayerColor(myColor), false, depth - 1);
这是另一个调用:
val = MinMax(gameBoard, Extend.GetEnemyPlayerColor(myColor), true, depth - 1);
无论是否最大化,你都正确地切换了,但你不应该在玩家之间切换颜色。
在实践中真的很想跟踪谁是根玩家,因为所有的评估都是相对于根玩家的。在那种情况下,您将一直传递颜色,并且除了在评估函数中外,永远不要使用敌人的颜色。
我正在尝试使用 MinMax 将 AI 算法编写到跳棋游戏中。在最终测试之前一切都很好......计算机选择任何一块然后他就会来找我的人。他真的很想快点死。这是我的代码:
public MoveAndPoints MinMax(Dictionary<int, Field> gameBoard, string myColor, Boolean maximizingPlayer, int depth)
{
MoveAndPoints bestValue = new MoveAndPoints();
if (0 == depth)
{
return new MoveAndPoints(((myColor == enemyColor) ? 1 : -1) * evaluateGameBoard(gameBoard, myColor), bestValue.move);
}
MoveAndPoints val = new MoveAndPoints();
if (maximizingPlayer)
{
bestValue.points = int.MinValue;
foreach (Move move in GetPossibleMoves(gameBoard, myColor))
{
gameBoard = ApplyMove(gameBoard, move);
bestValue.move = move;
val = MinMax(gameBoard, Extend.GetEnemyPlayerColor(myColor), false, depth - 1);
bestValue.points = Math.Max(bestValue.points, val.points);
gameBoard = RevertMove(gameBoard, move);
}
return bestValue;
}
else
{
bestValue.points = int.MaxValue;
foreach (Move move in GetPossibleMoves(gameBoard, myColor))
{
gameBoard = ApplyMove(gameBoard, move);
val = MinMax(gameBoard, Extend.GetEnemyPlayerColor(myColor), true, depth - 1);
bestValue.points = Math.Min(bestValue.points, val.points);
gameBoard = RevertMove(gameBoard, move);
}
return bestValue;
}
}
这是我的启发:
public int evaluateGameBoard(Dictionary<int, Field> gameBoard, string color)
{
return Extend.GetNumberOfPieces(gameBoard, color) - Extend.GetNumberOfPieces(gameBoard, Extend.GetEnemyPlayerColor(color));
}
比如我有那个场景:
他选择去死而不是移动到任何其他地方:
如果我自己选择死亡,他只会杀了我,因为他必须这样做,因为这是他唯一的举动。 有人可以帮我解决这个问题吗?我认为问题出在 MinMax 内部。我几乎可以肯定这不是很成问题,但我真的找不到它:(
这是我的树的深度 3:
我没有你所有的代码,所以我无法完全验证这些。但是,我相信至少你的问题之一是你在玩家之间混合颜色。在您的 MinMax 调用中,您为两个位置传递了相同的颜色:
这是最大化播放器中的调用:
val = MinMax(gameBoard, Extend.GetEnemyPlayerColor(myColor), false, depth - 1);
这是另一个调用:
val = MinMax(gameBoard, Extend.GetEnemyPlayerColor(myColor), true, depth - 1);
无论是否最大化,你都正确地切换了,但你不应该在玩家之间切换颜色。
在实践中真的很想跟踪谁是根玩家,因为所有的评估都是相对于根玩家的。在那种情况下,您将一直传递颜色,并且除了在评估函数中外,永远不要使用敌人的颜色。