Java拷贝多维数组,随机错误

时间:2013-09-12 22:42:14

标签: java arrays

我一直在调试我的生命游戏的实现,我的主要问题看起来就像是我使用数组的方式。

public boolean[][] oldState;
public boolean[][] newState;
private boolean gameState = true;

public LifeBoard(Seed seed) {
    oldState = seed.getSeed();
    newState = new boolean[oldState.length][oldState[0].length];
    run();
}

public void run() {
    //debug code to run for x generations
    for (int i = 0; i < 5; i++) {
        BoardPrinter.print(oldState);
        evaluateCells();
        oldState = newState;        
    }
    BoardPrinter.print(oldState);
    System.out.println("game over");
}
来自Seed的boolean [] []是一个5x5网格,除了中间行的3个水平中间单元之外全部为假(死)

00000
00000
0+++0
00000
00000

evaluateCells()查看网格中的每个单元格,查看它周围的8个单元格,对它们进行计数,并根据邻居数量将新值写入newState。

应该发生什么:使用oldState计算newState,将newState复制到oldState,然后返回newState,再根据新的oldState写入每个单元格。

真正发生的事情:第一代正常工作,但之后结果越来越奇怪,它评估单元格是假的,我知道是真的等等。问题似乎是我复制数组的方式

如果我初始化第3个空白数组blankState [] [] = new boolean [5] [5]; 并且在运行循环期间说:

public void run() {
    //debug code to run for x generations
    for (int i = 0; i < 5; i++) {
        BoardPrinter.print(oldState);
        evaluateCells();
        oldState = newState;
            newState = blankState;
    }
    BoardPrinter.print(oldState);
    System.out.println("game over");
}

...然后游戏正常运行1代,然后奇怪的垃圾返回。

我有两个问题:首先,看起来我必须使用System.arraycopy(),但除非有人告诉我有关多维数组的版本,否则我将编写一个简单的循环。

我真正的问题:为什么你必须使用这种特殊的System方法来复制数组?为什么不能使用=运算符?

编辑:下面接受概念性答案。以下是解决实现问题的代码:

for (int n = 0; n < oldState.length; n++) {
            System.arraycopy(newState[n], 0, oldState[n], 0, oldState.length);
}
for (int t = 0; t < newState.length; t++) {
            System.arraycopy(blankState[t], 0, newState[t], 0, newState.length);
}

同样,对于记录,System.arraycopy(boolean[][], 0, boolean[][], 0, boolean.length);无法正常工作,您必须遍历每一行。

2 个答案:

答案 0 :(得分:6)

  

我真正的问题:为什么你必须使用这种特殊的System方法来复制数组?为什么不能使用=运算符?

这实际上是一个重要的Java课程,所以 要注意 。你在关注吗?好。这对将来很重要。

现在,这适用于Java中的所有对象,因为数组是对象。如果你使用=,那么你只需设置引用,并遇到here所见的各种乐趣。也就是说,如果我有一个带有带有公共int TestClass的名为test的getter和setter的简单类,那么以下代码将起作用:

TestClass t=new TestClass();
t.test=1;
TestClass t1=t;
t1.test=6;
System.out.println(t.test); //prints 6.

现在,为什么?因为引用tt1指向堆上的相同对象。 这也适用于数组。要获取副本,您需要执行特定于对象的任务。有些让你直接调用clone()Cloneable接口),有些让你把另一个实例传递给构造函数来获取一个新实例(比如ArrayList构造函数),还有一些使用实用程序方法,比如这里的数组。

答案 1 :(得分:1)

  

evaluateCells()查看网格中的每个单元格,查看8个单元格   围绕它,计算它们,并根据它写的邻居数量   newState的新值。

     

应该发生什么:使用oldState计算newState,复制newState   到oldState,然后返回newState,再次写入每个单元格   基于新的oldState。

     

真正发生的事情:第一代工作正常,但之后   结果越来越奇怪,它评估细胞   是的,我知道这是真的,等等。这个问题似乎在阻碍   我正在复制数组。

如果没有看到你的位移代码,我敢打赌这是由更高级别的问题造成的。很可能你的位移算法在某个地方有一个bug。

您是否使用Eclipse的调试器完成了代码?如果没有,请阅读本教程并尝试一些不同的种子。这将告诉您算法在何处(如果有的话)发生位移错误。

http://www.vogella.com/articles/EclipseDebugging/article.html