如何在不出现引用问题的情况下正确更新字典



我正试图在跳棋游戏中使用MinMax为电脑玩家编写AI,但我遇到了一个奇怪的问题。我有一本字典:

Dictionary<int, Field> gameBoard;

查看方法ApplyMove((和RevertMove((

public int MinMax(Dictionary<int, Field> gameBoard, string color, Boolean maximizingPlayer, int depth)
{
int bestValue;
if (0 == depth)
return ((color == myColor) ? 1 : -1) * evaluateGameBoard(gameBoard, color);
int val;
if (maximizingPlayer)
{
bestValue = int.MinValue;
foreach (Move move in GetPossibleMoves(gameBoard, color))
{
gameBoard = ApplyMove(gameBoard, move);
val = MinMax(gameBoard, color, false, depth - 1);
bestValue = Math.Max(bestValue, val);
gameBoard = RevertMove(gameBoard, move);
}
return bestValue;
}
else
{
bestValue = int.MaxValue;
foreach (Move move in GetPossibleMoves(gameBoard, Extend.GetEnemyPlayerColor(color)))
{
gameBoard = ApplyMove(gameBoard, move);
val = MinMax(gameBoard, color, true, depth - 1);
bestValue = Math.Min(bestValue, val);
gameBoard = RevertMove(gameBoard, move);
}
return bestValue;
}
}

方法ApplyMove((运行良好,ApplyMmove((和RevertMove((都是返回主题的gameBoard。

应用移动((

public Dictionary<int, Field> ApplyMove(Dictionary<int, Field> gameBoard, Move move)
{
gameBoard_old = Extend.CloneGameBoard(gameBoard);
gameBoard = UpdateFieldTo(gameBoard, move);
if (move.indexThrough == 0)
gameBoard = UpdateFieldThrough(gameBoard, move);
gameBoard = UpdateFieldFrom(gameBoard, move);
return gameBoard;
}

RevertMove((

public Dictionary<int, Field> RevertMove(Dictionary<int, Field> gameBoard, Move move)
{
gameBoard[move.indexFrom] = gameBoard_old[move.indexFrom];
if (move.indexThrough != 0)
{
gameBoard[move.indexThrough] = gameBoard_old[move.indexThrough];
}
gameBoard[move.indexTo] = gameBoard_old[move.indexTo];
return gameBoard;
}

问题出现在RevertMove((:中

return gameBoard; ---> value is correct

但当该通道在MinMax((中执行时:

gameBoard = RevertMove(gameBoard, move);

存在0效果。。。GameBoard忽略RevertMove((中的值,并保留旧值
我不知道我做错了什么。。。我怀疑参考文献有一些问题。是那个操作员吗="更改字典值的方法不好吗?我不知道发生了什么……一次效果好,另一次效果不好。请不要责怪我,我是c#的新手


编辑(1(

public static Dictionary<int, Field> CloneGameBoard(Dictionary<int, Field> gameBoard)
{
string json = Newtonsoft.Json.JsonConvert.SerializeObject(gameBoard);
return Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<int, Field>>(json);
}

如何完全不需要恢复的示例:

public int MinMax(Dictionary<int, Field> gameBoard, string color, Boolean maximizingPlayer, int depth)
{
int bestValue;
if (0 == depth)
return ((color == myColor) ? 1 : -1) * evaluateGameBoard(gameBoard, color);
int val;
if (maximizingPlayer)
{
bestValue = int.MinValue;
foreach (Move move in GetPossibleMoves(gameBoard, color))
{
var movedGameBoard = ApplyTentativeMove(gameBoard, move);
val = MinMax(movedGameBoard, color, false, depth - 1);
bestValue = Math.Max(bestValue, val);
}
return bestValue;
}
else
{
bestValue = int.MaxValue;
foreach (Move move in GetPossibleMoves(gameBoard, Extend.GetEnemyPlayerColor(color)))
{
var movedGameBoard = ApplyTentativeMove(gameBoard, move);
val = MinMax(movedGameBoard, color, true, depth - 1);
bestValue = Math.Min(bestValue, val);
}
return bestValue;
}
}
public void ApplyMove(Dictionary<int, Field> gameBoard, Move move)
{
UpdateFieldTo(gameBoard, move);
if (move.indexThrough != 0)
UpdateFieldThrough(gameBoard, move);
UpdateFieldFrom(gameBoard, move);
}
public Dictionary<int, Field> ApplyTentativeMove(Dictionary<int, Field> gameboard, Move move)
{
var gameBoardAfterMove = Extend.CloneGameBoard(gameBoard);
ApplyMove(gameBoardAfterMove, move);
return gameBoardAfterMove;
}

public void ApplyMove是修改实际棋盘的函数,这是你在游戏中使用的函数。

公共词典<int,字段>ApplyTentativeMove是一个通过该动作创建新董事会的功能。进入下一个循环步骤后,此临时板将被丢弃。

相关内容

最新更新