如何在没有参考问题的情况下正确更新词典?
How to properly update Dictionary without having problems with reference?
我正在尝试在西洋跳棋游戏中使用 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() 运行良好,ApplyMove() 和 RevertMove() 都是主题返回 gameBoard。
ApplyMove()
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 是修改实际棋盘的函数,这是您将在游戏本身中使用的函数。
public Dictionary ApplyTentativeMove 是一个使用该移动创建新棋盘的函数。
在您进入下一个循环步骤后,这个临时板将被丢弃。
我正在尝试在西洋跳棋游戏中使用 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() 运行良好,ApplyMove() 和 RevertMove() 都是主题返回 gameBoard。
ApplyMove()
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 是修改实际棋盘的函数,这是您将在游戏本身中使用的函数。
public Dictionary