0

我真的不知道是什么导致了这个问题,但我的程序应该是康威的生命游戏,在2代后崩溃,看起来不管我做什么,而且我我一直在努力寻找错误。2D数组和空指针异常(Java)

我把事业缩小到了一些可能的领域 - 或者至少我认为我有。

short numNeighbors(int x, int y) { 
    short numNeighbors; 
    numNeighbors = 0; 
    if(x > 0 && y > 0 && matrix[x][y] != null){ 
     if (matrix[x+1][y] == true) numNeighbors++; 
     if (matrix[x][y+1] == true) numNeighbors++; 
     if (matrix[x+1][y+1] == true) numNeighbors++; 
     if (matrix[x][y-1] == true) numNeighbors++; 
     if (matrix[x-1][y] == true) numNeighbors++; 
     if (matrix[x+1][y-1] == true) numNeighbors++; 
     if (matrix[x-1][y+1] == true) numNeighbors++; 
     if (matrix[x-1][y-1] == true) numNeighbors++; 
    } 
    return numNeighbors; 
} 
//returns the number of neighbours that a coordinate has 

我假定这部分我上面的二维数组的边界以外的检查,但不应该是可能的,因为我花了预防措施,以确保没有发生。即便如此,这是一个可能的原因。

void nextGen(){ 
    Boolean[][] newMatrix = new Boolean[rows()][cols()]; 

    for (int i = 1; i < cols()-1; i++){ 
     for (int j = 1; j < rows()-1; j++){ 
     //avoiding null pointer errors 
      if (matrix[j][i] == null) matrix[j][i] = false; 
      //if a cell has 3 neighbours, become or stay true 
      if (numNeighbors(j, i) == 3) newMatrix[j][i] = true; 
      //if it doesn't have 3 neighbours, become or stay false 
      else newMatrix[j][i] = false; 
     } 
    } 

    matrix = newMatrix; 
} 
//makes matrix represent the next generation 

这是我对错误原因的下一次猜测,但我无法真正知道会出现什么错误。

for (int j = 0; j < numGenerations; j++){ 
     JOptionPane.showMessageDialog(null,"generation " + (j+1) + ":\n\n" + myGrid.showGrid()); 
     myGrid.nextGen(); 
    } 

我只是发布上面,因为它调用上面的块,我不想排除任何东西。

我真的不知道还有什么问题可以解决,但如果有人想看看我项目的完整源代码,我已经发布了它on pastebin

+0

什么行号是堆栈跟踪中发生的NullPointerException?这将是一个很好的起点。你尝试过调试吗?在发生NullPointerException的行之前放入几个断点并检查数组值。 – 2012-01-07 22:54:15

+1

你可以发布你的错误stacktrace? – 2012-01-07 22:54:21

回答

2

在次世代你这样做:

//avoiding null pointer errors 
if (matrix[j][i] == null) matrix[j][i] = false; 

执行相同的所有IFS在numNeighbors()

short numNeighbors(int x, int y) { 
    short numNeighbors; 
    numNeighbors = 0; 
    if(x > 0 && y > 0 && matrix[x][y] != null){ 
     if (matrix[j][i] != null && matrix[x+1][y] == true) numNeighbors++; 
     if (matrix[j][i] != null && matrix[x][y+1] == true) numNeighbors++; 
     if (matrix[j][i] != null && [x+1][y+1] == true) numNeighbors++; 
     if (matrix[j][i] != null && matrix[x][y-1] == true) numNeighbors++; 
     if (matrix[j][i] != null && matrix[x-1][y] == true) numNeighbors++; 
     if (matrix[j][i] != null && matrix[x+1][y-1] == true) numNeighbors++; 
     if (matrix[j][i] != null && matrix[x-1][y+1] == true) numNeighbors++; 
     if (matrix[j][i] != null && matrix[x-1][y-1] == true) numNeighbors++; 
    } 
    return numNeighbors; 
} 

甚至更​​好提前进行实例化的所有单元格设置为false。

//Run in constructor 
for(int i .. 
    for(int j .. 
     matrix[j][i] = false 
+3

我喜欢关于预先实例化所有单元格的最后部分。 1 + – 2012-01-07 23:06:36

+0

我只是试过这个,它工作,但它与newMatrix,而不是矩阵。为了安全起见,我让矩阵的构造函数为假,但我认为布尔运算符在Java中默认为false,但显然它们是空的。尽管如此,我仍然不知道为什么它能够工作两代。 – Megafonzie 2012-01-07 23:37:33

+0

它的剂量看到我的新答案 – Farmor 2012-01-07 23:57:38

1

实际上,全部块应该用大括号括起来。如果你花时间做这个,你会多次保存你的尾巴。例如,

if (matrix[j][i] == null) { 
    newMatrix[j][i] = false; 
} 

编辑2
你大,如果块都将有边界的问题。为什么不直接使用嵌套的for循环:

short numNeighbors(int x, int y) { 
    short numNeighbors; 
    numNeighbors = 0; 

    int xMin = Math.max(x - 1, 0); 
    int xMax = Math.min(x + 1, MAX_X - 1); // MAX_X is a constant, number of columns 
    int yMin = Math.max(y - 1, 0); 
    int yMax = Math.min(y + 1, MAX_Y - 1); // ditto, number of rows 

    for (int i = xMin; i <= xMax; i++) { 
    for (int j = yMin; j <= yMax; j++) { 
     if (i != x && j != y) { 
      if (matrix[i][j]) { 
       numNeighbors++; 
      } 
     } 
    } 
    } 

    return numNeighbors; 
} 

与其他地方一样,在我的评论中提到,数组应该初始化为非空值,所以应该不需要空检查。

+0

这是一个逻辑问题,但我不会产生NPE。 – Farmor 2012-01-07 22:56:11

+0

我这样做是为了检查矩阵[] []中可能的空值。我对我的代码进行了类似的检查,但他们似乎没有帮助。我也尝试改变它,并没有透露额外的信息。我仍然得到同样的错误,并在两代之后出现同样的崩溃。 – Megafonzie 2012-01-07 23:02:33

+0

我的意见是针对气垫船Full Of Eels编辑回答 – Farmor 2012-01-07 23:04:45

0

我会在检查您的整个项目时发布另一个答案。

void nextGen(){ 
    Boolean[][] newMatrix = new Boolean[rows()][cols()]; 

你做什么其中创建布尔对象的数组,而不是布尔元。

  • 布尔元默认为false
  • 布尔对象默认为空

Java有一种叫做自动装箱原语可以是棘手和隐藏这种“SMaL公司”差异这实际上可以是真正意义上的,如在这里看到的,