Как вы убиваете живые клетки и оживляете живые клетки, не портя прилавок? Логическая ошибка в игре жизни Конвея - PullRequest
0 голосов
/ 01 ноября 2018

Я кодирую игру жизни Конвея на Java и обнаружил логическую ошибку в моем коде. Если вы не знакомы с игрой, вот основные правила:

Игра Жизни - это простая симуляция, которая происходит в сетке ячеек. Каждая клетка может быть либо живой, либо мертвой, и она взаимодействует со своими соседями (по горизонтали, вертикали или диагонали). На каждой итерации будет приниматься решение о том, остаются ли живые клетки живыми или мертвые клетки становятся живыми. Алгоритм выглядит следующим образом:

Если клетка жива: Если у него менее двух живых соседей, он умирает из-за одиночества. Если у него есть два или три живых соседа, он доживает до следующего поколения Если у него более трех живых соседей, он умирает из-за перенаселения.

Если клетка мертва: если у него ровно три живых соседа, он становится живым благодаря размножению.

Код, который у меня есть для подсчета мертвых и живых клеток, выглядит следующим образом:

// Go through each dead cell and check all neighboring cells to see if it 
// will be revived
// reviveDeadCells()

neighborCount = 0;
for (y = 0; y , 15; y++ ) {
    for (x = 0; x < 15; x++) {
        if (board[x][y] = 0 ) {
            for ( i = x - 1; i = x + 1; i ++ ) {
                for (j = y - 1; j = y + 1; j ++) {
                    if (board[i][j] = 1 ) {
                        neighborCount = neighborCount + 1;
                    }
                }
                if (neighborCount = 4) {
                    board[i][j] = 1;
                }
            }
        }
    }
}





// Go through each live cell and see if it should be executed
// killLiveCell()

for (y = 0; y , 15; y++ ) {
    for (x = 0; x < 15; x++) {
        if (board[x][y] = 1 ) {
            for ( i = x - 1; i = x + 1; i ++ ) {
                for (j = y - 1; j = y + 1; j ++) {
                    if (board[i][j] = 1 ) {
                    neighborCount = neighborCount + 1;
                }
            }
        if (neighborCount < 3) || (nieghborCount > 4) {
            board[x][y] = 0;
        }
    }
} 

Теперь я понимаю, что проблема с этим кодом в том, что есть логическая ошибка. Сначала я считаю все соседние клетки мертвых клеток, а затем подсчитываю, сколько их живо. Затем я оживлю их, если будет ровно 3 живых соседа. Единственная проблема с этим заключается в том, что теперь он будет влиять на счетчик соседних клеток живых клеток. Как я могу изменить живые клетки мертвых и живых соседей одновременно, не влияя на счетчик другого? У меня такое чувство, что у меня есть весь код, но мне, вероятно, нужно где-то переместить его в цикле for. Я просто не знаю точно, где мне нужно поместить это, чтобы исправить эту ошибку. Любая помощь будет высоко ценится, спасибо.

1 Ответ

0 голосов
/ 01 ноября 2018

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

// Create a simple tuple class for the co-ordinates
Class CoordPair(){
    int x;
    int y;

    CoordPair(int x, int y){
        this.x = x;
        this.y = y;
    } 
}

// In your code, use Hash Set to prevent having two copies of the Coordinates
HashSet<CoordPair> changeSet = new HashSet<CoordPair>();
...
            if (neighborCount = 4) {
                CoordPair changePair = new CoordPair(i,j);
                changeSet.add(changePair);
            }
...
// After identifying all the changing pairs on the board
for(CoordPair pair : changeSet){
    board[pair.x][pair.y] ^= 1; //XOR to flip the value
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...