C#/ Unity-需要帮助调试我的国际象棋程序-在同一个类的另一个实例中创建该类的实例时遇到麻烦

时间:2018-11-14 18:54:28

标签: c# unity3d

我正在创建一个国际象棋程序。我决定这样做,以便在选择一块时显示所有可能的合法动作。为了使它起作用,我必须有一种机制来预测举动的结果(例如,因为您不能采取法律行动来阻止自己的国王)。当我开始与计算机对手打交道时,这也将非常有用,因为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()的预期功能是获取列表数组。数组中的每个列表都包含玩家棋子之一的合法移动。但是,这实际上似乎正在更改实际的电路板数据,我不知道为什么。

  1. 当玩家尝试移动棋子时,游戏会中断,因为棋子不在应有的位置,并且软件无法应对。被移动的片段不会将其自身移出其旧位置(尽管我已尽力而为),这导致该对象存在两个实例,当一段代码尝试访问第17个元素时,导致indexoutofrange异常包含16个元素的数组。

如果有人能帮助我,我将不胜感激,我觉得我已经在这上面浪费了整整一天,而且我确定自己缺少一些简单的东西。

我的代码的链接为https://github.com/FC123321/Chess

1 个答案:

答案 0 :(得分:1)

Array.Clone不会创建数组的深层副本,因此,当您在boardLayout.Clone()(然后在SimulateBoard构造函数中)调用ChessBoardSim时,您正在复制boardLayout中对新数组的引用。这意味着新数组中的片段与旧数组中的片段是同一对象。

这意味着当您在MovePiece的{​​{1}}中并调用SimulateBoard并在该复制数组的成员上调用时,您需要设置片段在副本的来源。

您需要遍历整个源数组,而不是使用piece.SetPosition,并执行boardLayout.Clone(),然后将值复制到新的newBoardLayout[x,y] = new ChessPiece();。另外,您可以创建一个新的ChessPiece构造函数,该构造函数将使用另一个棋子并将其值复制到其中:

ChessPiece
相关问题