由于没有表面上的原因,更改了数组的值

时间:2012-09-23 16:57:08

标签: c# arrays multidimensional-array tic-tac-toe

我正在尝试在 Tic Tac Toe 的游戏中嵌入一个非常基本的AI,并且我遇到了一个问题,我使用的阵列来辨别最合适的方块。

我有一个数组代表当前状态的游戏网格,另一个数组代表某个方格声称的方式。

AI一直做出奇怪的决定,所以我决定让它在某些里程碑上报告各种信息。

string[,] currentGrid;
string[,] hypotheticalGrid;


MessageBox.Show(currentGrid);

hypotheticalGrid = currentGrid;
hypotheticalGrid[x, y] = "O";

MessageBox.Show(currentGrid);
  

请记住,以上是实际代码的非常简化版本。

数组沿线分配值,消息框设置为将currentGrid显示为其包含值的序列。

除了消息框之间的代码之外,一切正常。

问题是两个消息框显示不同的结果,即使后者是前者的副本,并且在两者之间的空间中未指定对currentGrid的更改。

中间的两行直接从源代码复制,只应影响假设的网格。显而易见的是,这些线应该重置假想网格,然后向所讨论的方块添加“O”。

但是,由于某种原因,“O”也会被置于当前网格中。

我做错了什么?

3 个答案:

答案 0 :(得分:3)

hypotheticalGrid = currentGrid;不会复制currentGrid,而是两个变量都指向同一个数组。因此,假设网格中的任何更改都将在currentGrid中看到。

你应该让hypotheticalGrid成为currentGrid的副本:

hypotheticalGrid = (string[,])currentGrid.Clone();

在这种情况下,Clone()将起作用,因为字符串在.NET中是不可变的。在其他情况下,Clone可能不够好,只需注意一些事项。

答案 1 :(得分:2)

问题在于你的任务:

hypotheticalGrid = currentGrid;

仅仅是一个引用赋值,这意味着现在它们都指向内存中的相同数组,因此对假设网格的任何更改都会影响当前网格。

您需要一个完整的项目副本,以便它们不会相互干扰。

答案 2 :(得分:0)

请记住,该数组是引用类型。您的作业会复制引用,但不会创建数组的副本。赋值后,两个数组变量都指向同一个数组!

您可以像这样创建一个数组副本:

string[] hypotheticalGrid = new string[currentGrid.Length];
Array.Copy(currentGrid, hypotheticalGrid, currentGrid.Length);

请注意,这不会创建数组中包含的项的副本,但这不是问题,因为字符串是不可变的。即如果你操纵其中一个数组中的字符串,这会创建一个新字符串,因此对第二个数组没有影响。


编辑:

通过查看其他帖子,我发现使用Clone方法可以更轻松地完成:

string[] hypotheticalGrid = currentGrid.Clone();