Игра жизни, метод не работает

Я не уверен, что схожу с ума, но вот в чем моя проблема:

Я программирую игру «Жизнь» и использую «счетный» метод, который подсчитывает, сколько окружающих полей живо.

    public int countalive(Board board, int yaxis, int xaxis) { //defekt

    int living = board.getfields()[yaxis - 1][xaxis - 1] + board.getfields()[yaxis - 1][xaxis] + board.getfields()[yaxis - 1][xaxis + 1] + 
            board.getfields()[yaxis][xaxis - 1] + board.getfields()[yaxis][xaxis + 1] + board.getfields()[yaxis + 1][xaxis - 1] +
            board.getfields()[yaxis + 1][xaxis] + board.getfields()[yaxis + 1][xaxis + 1];
    return living;
}

Этот метод, кажется, работает отлично. Но когда я делаю это

 public Board evolve(Board board) {
    Board tmpboard = board;
    System.out.println(countalive(board, 1, 3));  //I test with this. SHOULD AND IS 2!!
    int aliveneighbours = 0;
    for (int i = 1; i < board.getfields().length - 1; i++) {
        for (int j = 1; j < board.getfields()[i].length - 1; j++) {
            System.out.print("i = " +i);
            System.out.print("j = " +j +" ");
            aliveneighbours = countalive(board, i, j);
            System.out.println(aliveneighbours);

            if (aliveneighbours == 3) {
                tmpboard.getfields()[i][j] = 1;
            } else if (aliveneighbours < 2 || aliveneighbours > 3) {
                tmpboard.getfields()[i][j] = 0;
            }
        }
        System.out.println("");
    }
    return tmpboard;
}

Я получаю это в консоли:

2
i = 1j = 1 1
i = 1j = 2 1
i = 1j = 3 1
i = 1j = 4 1
i = 1j = 5 0
...

хотя i = 1 и j = 3 должно быть 2, а не 1. Как видите, метод countalive(board, 1, 3) работает, но в цикле for он дает другой результат. Вы можете найти мою ошибку?


person Peter111    schedule 14.09.2014    source источник
comment
Я думаю, нам также может понадобиться увидеть ваше состояние тестирования Board. Однако стоит отметить, что вы обращаетесь к (Y, X), что показалось мне странным (соглашение (X, Y), не так ли?)   -  person Dan    schedule 14.09.2014
comment
Дает ли эта строка Board tmpboard = board; копию текущей доски? Ваш результат может быть объяснен, если каким-то образом tmpboard == board -- то есть вы меняете board, изменяя tmpboard. Если правила Java неясны в этом (для меня они непонятны), вы можете проверить, изменив что-то в tmpboard, а затем изучив саму board.   -  person Jongware    schedule 14.09.2014
comment
@Jongware Да, board tmpboard = board дает мне копию. Я печатал плату и tmpboard после каждой итерации, и вы, похоже, правы. Плата также меняется, хотя она не должна   -  person Peter111    schedule 14.09.2014
comment
Это потому, что Java принимает линию tmpboard = board буквально! Действительно, поскольку они равны, изменение одного изменяет и другое. Создайте новую пустую доску и вместо этого скопируйте отдельные ячейки.   -  person Jongware    schedule 14.09.2014
comment
СПАСИБО, ты бог. Я не знал об этом. Теперь это работает!!   -  person Peter111    schedule 14.09.2014
comment
Какой беспорядок, кошмар для отладки   -  person Mark Homer    schedule 14.09.2014
comment
Вы намеренно пропускаете пограничные ячейки?   -  person Fildor    schedule 14.09.2014
comment
@MarkHomer, да, я нуб :( Филдор, да, они - рамка поля   -  person Peter111    schedule 14.09.2014


Ответы (1)


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

person Vatine    schedule 14.09.2014
comment
к сожалению, нет, я меняю живых в tmpboard, но присматриваю за соседями в неизмененной доске. Я никогда не меняю плату, я только меняю ее копию (tmpboard) и возвращаю копию РЕДАКТИРОВАТЬ: хорошо, похоже, вы правы. Не знаю почему, но оригинал тоже меняется - person Peter111; 14.09.2014
comment
массив - это объект в java. если у вас есть указатель board на этот массив и вы создаете tmpBoard, они оба указывают на один и тот же массив. Вот почему вам нужна настоящая копия. - person donmarkusi; 14.09.2014