0

この問題の原因はよくわかりませんが、Conway のライフ ゲームであると思われる私のプログラムは、何をしても、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

上記のこのセクションでは、2D 配列の境界の外側をチェックしていると想定していますが、それが起こらないように予防策を講じたので、それは不可能です。それでも、これは考えられる原因の 1 つです。

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

または、すべてのセルを false に事前インスタンス化することをお勧めします。

//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;
}

また、他の場所と私のコメントで述べたように、配列は null 以外の値に初期化する必要があるため、null チェックは必要ありません。

于 2012-01-07T22:52:59.277 に答える