2

我正在尝试在井字游戏中嵌入一个非常基本的 AI,但我在使用数组来识别最合适的方格时遇到了问题。

我有一个数组表示当前状态下的游戏网格,另一个表示如果某个方格被认领时的样子。

人工智能不断做出奇怪的决定,所以我决定让它在某些里程碑报告各种信息。

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


MessageBox.Show(currentGrid);

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

MessageBox.Show(currentGrid);

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

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

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

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

中间的两行是直接从源代码复制的,应该只影响假设的网格。应该很明显,这些线应该重置假设的网格,然后在有问题的正方形上添加一个“O”。

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

我究竟做错了什么?

4

3 回答 3

3

该行hypotheticalGrid = currentGrid;不会复制currentGrid,而是两个变量都指向同一个数组。因此,在 hypotheticalGrid 中所做的任何更改也会在 currentGrid 中看到。

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

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

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

于 2012-09-23T17:00:38.843 回答
2

问题是你的任务:

hypotheticalGrid = currentGrid;

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

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

于 2012-09-23T16:59:42.883 回答
0

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

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

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

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


编辑:

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

string[] hypotheticalGrid = currentGrid.Clone();
于 2012-09-23T17:08:15.613 回答