Я изучаю игры Конвея жизни осуществить это самостоятельно, и наткнулся на следующую реализацию с правилами:Java: Как реализовать игру жизни Конвея?
Учитывая доску с т по п ячеек, каждая ячейка имеет начальное состояние живого (1) или мертвым (0). Каждая клетка взаимодействует с его восемью соседями (по горизонтали, по вертикали, по диагонали), используя следующие четыре правила (взятые из выше статьи Википедии):
- Любая живая клетка с менее чем двумя живыми соседями умирает, как будто вызваны под -Население.
- Любая живая ячейка с двумя или тремя живыми соседями живет следующим поколением.
- Любая живая клетка с более чем тремя живыми соседями умирает, как если бы она переполнена.
- Любая мертвая ячейка с ровно тремя живыми соседями становится живой клеткой, как бы путем размножения.
И реализация (https://discuss.leetcode.com/topic/29054/easiest-java-solution-with-explanation):
public void gameOfLife(int[][] board) {
if (board == null || board.length == 0) return;
int m = board.length, n = board[0].length;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
int lives = liveNeighbors(board, m, n, i, j);
// In the beginning, every 2nd bit is 0;
// So we only need to care about when will the 2nd bit become 1.
if (board[i][j] == 1 && lives >= 2 && lives <= 3) {
board[i][j] = 3; // Make the 2nd bit 1: 01 ---> 11
}
if (board[i][j] == 0 && lives == 3) {
board[i][j] = 2; // Make the 2nd bit 1: 00 ---> 10
}
}
}
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
board[i][j] >>= 1; // Get the 2nd state.
}
}
}
public int liveNeighbors(int[][] board, int m, int n, int i, int j) {
int lives = 0;
for (int x = Math.max(i - 1, 0); x <= Math.min(i + 1, m - 1); x++) {
for (int y = Math.max(j - 1, 0); y <= Math.min(j + 1, n - 1); y++) {
lives += board[x][y] & 1;
}
}
lives -= board[i][j] & 1;
return lives;
}
И водитель:
public static void main(String args[]) {
GameOfLife gl = new GameOfLife();
int[][] board = {
{0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 1, 0, 0, 0, 0, 0},
{0, 1, 0, 1, 0, 0, 0, 0, 0},
{0, 0, 1, 1, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0}
};
gl.gameOfLife(board);
}
И мой вопрос, что делать x
и y
в liveNeighbors()
представляют? Не понимаю, зачем нужна Math.min()
и Math.max()
. А также, lives
представляет количество инициализированных жизней на доске?
Возможно, я не понимаю, как это осуществить, для уточнения, и прежде чем я приму/отвечу на ответ, вы могли бы прокомментировать, что происходит на каждой итерации? Действительно помогло бы прояснить ситуацию. –
Большое вам спасибо. Это многое прояснило! Еще несколько вопросов. Я до сих пор не получаю 'lives - = board [i] [j] & 1' часть. Разве у нас нет 1 на нашей площади? В '(1,2)'? И в чем причина вычитания 1? РЕДАКТИРОВАЙТЕ: Ах, именно в этой точке мы находим квадрат вокруг, и если это само является 1, мы вычитаем 1, правильно? –
Кроме того, что делать & 1 в 'board [x] [y] & 1' и >> = 1 в' board [i] [j] >> = 1' do? –