0

我真的不知道是什么导致了这个问题,但是我的程序,应该是康威的生命游戏,在 2 代后崩溃,似乎不管我做什么,我已经尝试了好几天来定位错误。

我已将原因缩小到几个可能的领域——或者至少,我认为我有。

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();
    }

我只是发布上面的内容,因为它调用了上面的块,我不想排除任何事情。

我真的不知道还有什么问题,但以防万一有人想查看我项目的完整源代码,我已将其发布在 pastebin 上

4

3 回答 3

2

在 nextGen 中,您可以:

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

对所有 if 执行相同的操作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;
}

或者甚至更好地将所有单元预实例化为假。

//Run in constructor
for(int i ..
   for(int j ..
      matrix[j][i] = false
于 2012-01-07T23:00:10.983 回答
1

实际上,所有块都应该用花括号括起来。如果你花时间这样做,你会多次拯救你的尾巴。例如,

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

编辑 2
你的大 if 块会有边界问题。为什么不简单地使用嵌套的 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;
}

正如在其他地方和我的评论中提到的那样,数组应该初始化为非空值,因此不需要进行空检查。

于 2012-01-07T22:52:59.277 回答
0

当我检查你的整个项目时,我会发布另一个答案。

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

你在哪里做的是创建一个布尔对象数组而不是布尔基元。

  • 布尔原语默认为 false
  • 布尔对象默认为 null

Java 有一种称为自动装箱的原语,这可能很棘手,并隐藏了这种“小”差异,实际上就像这里看到的那样,它们真的很重要,

于 2012-01-07T23:56:32.240 回答