2D-массивы и исключения нулевых указателей (Java) - PullRequest
0 голосов
/ 08 января 2012

Я действительно не знаю, что вызывает эту проблему, но моя программа, которая должна быть «Игрой жизни» Конвея, вылетает через 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-массива, но это не должно быть возможным, потому что я принял меры предосторожности, чтобы этого не произошло.Тем не менее, это одна из возможных причин.

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 .

Ответы [ 3 ]

2 голосов
/ 08 января 2012

В nextGen вы делаете:

 //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
1 голос
/ 08 января 2012

И на самом деле, все блоки должны быть заключены в фигурные скобки. Вы сохраните свой хвост много раз, если вы уделите время этому. например,

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

Редактировать 2
У вашего большого блока if будут проблемы с границами. Почему бы просто не использовать вложенные циклы:

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 голосов
/ 08 января 2012

Я опубликую другой ответ, когда я проверял весь ваш проект.

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

Что вы делаете, когда создаете массив логических объектов, а не логических примитивов.

  • булевы примитивы по умолчанию ложно
  • Булевы объекты по умолчанию равны нулю

В Java есть нечто, называемое автобоксом для примитивов, котороемогут быть хитрыми и скрывать такого рода «мелкие» различия, которые на самом деле могут быть очень значительными, как показано здесь,

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...