Копирование двумерного массива - все еще использует ссылки?

У меня (ИМХО) странное поведение в моем коде. В настоящее время я реализую минимаксный алгоритм для игры Tic Tac Toe. В моем методе «преемник» я хочу определить все возможные ходы. Вот код:

private ArrayList<TicTacToeState[][]> successor(final TicTacToeState[][] field, TicTacToeState s) {
    ArrayList<TicTacToeState[][]> returnList = new ArrayList<TicTacToeState[][]>();
    for (int i = 0; i < TicTacToeGame.FIELDSIZE; i++) {
        for (int j = 0; j < TicTacToeGame.FIELDSIZE; j++) {
            if (field[i][j] == TicTacToeState.Empty) {
                TicTacToeState[][] currentCopy = new TicTacToeState[TicTacToeGame.FIELDSIZE][TicTacToeGame.FIELDSIZE];
                System.arraycopy(field, 0, currentCopy, 0, field.length);
                currentCopy[i][j] = s; // <- field seems to be referenced?!
                returnList.add(currentCopy);
            }
        }
    }
    return returnList;
}

Как видите, я хочу получить все возможные ходы и сохранить их в массиве. К сожалению, при установке значения в "currentCopy" меняется и "поле". Но поле не должно быть переработано, потому что я скопировал массив. Где ошибка? Я уже пробовал использовать метод clone() для двумерного массива -> та же проблема.

Спасибо за любую помощь.

(К вашему сведению, TicTacToeState — это перечисление, включающее «Player1», «Player2» и «Empty»)


person oopbase    schedule 22.04.2012    source источник


Ответы (2)


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

Другой способ решить эту проблему — сделать свой ход, повторить, а затем отменить ход. Тогда вам вообще не нужно копировать массив.

person Tony Ennis    schedule 22.04.2012

Вы используете двумерный массив, но копируете только первое измерение массива в копии системного массива. Я бы посоветовал не делать все это копирование. Возможно, используйте что-то еще, чтобы описать возможные ходы. Обратите также внимание, что вы не копируете содержимое массива, а только сам массив.

person Mattias Isegran Bergander    schedule 22.04.2012