我正在创建一个国际象棋程序。我决定这样做,以便在选择一块时显示所有可能的合法动作。为了使它起作用,我必须有一种机制来预测举动的结果(例如,因为您不能采取法律行动来阻止自己的国王)。当我开始与计算机对手打交道时,这也将非常有用,因为AI必须预先能够看到几转才能做出明智的决定。
为此,我做到了,因此,在每个回合开始时,都会针对玩家的棋子计算所有可能的动作,然后模拟这些可能的动作中的每一个,以查看是否离开国王在检查。如果是这样,该选项将被删除。我有一个名为BoardManager的主类,它控制视觉效果并包含实际的棋盘布局(在ChessBoardSim中),还有ChessBoardSim类,其对象每个都包含一个可能的棋盘状态。 ChessBoardSim可以创建ChessBoardSim的其他实例,从而可以预先模拟板的状态任意数量的匝数。
我有一个已经苦苦挣扎了5个多小时的错误,该错误是在我尝试重组许多代码之后出现的。我已经快要死了,我只需要一双新鲜的眼睛。问题在于,移动时不会将其从原来的位置上移开,并且板上某些部件的位置似乎向上方移动了两个磁贴。我相信,基于调试,该问题出现在ChessBoardSim类的CalculateAllMovementOptions()中,由于某种原因,当ChessBoardSim具有ChessBoardSim子级,而CalculateAllMovementOptions()函数在子级中被调用时,它将更改父母。 我在下面提供了完整的代码,我将尽力描述具体问题。
问题的根源是:
1:调用BoardManager中的private void Start()。
2:程序正确绘制并填充了木板。将创建一个ChessBoardSim(称为ChessPieces)以包含当前板状态的数据。
3:为了开始游戏,在BoardManager中调用StartTurn()。
4:StartTurn()调用ChessPieces.CalculateAllMovementOptions()。 CalculateAllMovementOptions()的预期功能是获取列表数组。数组中的每个列表都包含玩家棋子之一的合法移动。但是,这实际上似乎正在更改实际的电路板数据,我不知道为什么。
如果有人能帮助我,我将不胜感激,我觉得我已经在这上面浪费了整整一天,而且我确定自己缺少一些简单的东西。
答案 0 :(得分:1)
Array.Clone
不会创建数组的深层副本,因此,当您在boardLayout.Clone()
(然后在SimulateBoard
构造函数中)调用ChessBoardSim
时,您正在复制boardLayout
中对新数组的引用。这意味着新数组中的片段与旧数组中的片段是同一对象。
这意味着当您在MovePiece
的{{1}}中并调用SimulateBoard
并在该复制数组的成员上调用时,您需要设置片段在副本的来源。
您需要遍历整个源数组,而不是使用piece.SetPosition
,并执行boardLayout.Clone()
,然后将值复制到新的newBoardLayout[x,y] = new ChessPiece();
。另外,您可以创建一个新的ChessPiece
构造函数,该构造函数将使用另一个棋子并将其值复制到其中:
ChessPiece