Глубокая копия (клон) объекта с матрицей (Java)

У меня проблемы с глубоким копированием. У меня есть проект java, шахматы, и мне нужно использовать метод clone(), потому что мне нужно попробовать новые конфигурации, не меняя плату.

    Board scacchiera = new Board();
    Initialization(scacchiera);
    Board clone = scacchiera.clone();
    System.out.println(scacchiera.toString());
    System.out.println(clone.toString());

Я создаю объект, scacchiera, затем я клонирую его. Я думаю, что правильно сделал глубокую копию, но когда я что-то меняю в scacchiera, клон тоже меняется. В объекте Board:

public class Board implements Cloneable{
//TODO
//rivedere se check e checkmate public o private;
//se private, costruire get e set;

public Pedine[][] board;
public boolean check;
public boolean checkmate;
//creating 2 lists for all the pieces; Neri=black, Bianchi=White
public ArrayList<Pedine> Neri;
public ArrayList<Pedine> Bianchi;

public Board(){

    this.board = new Pedine [8][8];
    this.check = false;
    this.checkmate = false;
    this.Neri = new ArrayList<Pedine>();
    this.Bianchi = new ArrayList<Pedine>();


}

...

@Override
public Board clone() throws CloneNotSupportedException{

    Board cloned = (Board) super.clone();
    cloned.board = (Pedine[][]) board.clone();
    return cloned;
}

У меня есть этот двойной массив Pedine, и я тоже должен его клонировать, поэтому я делаю:

public class Pedine implements Cloneable{

private int x;
private int y;
private Piece pezzo;
private Colour colore;

...

@Override
public Pedine clone() throws CloneNotSupportedException{

    return (Pedine) super.clone();

}

Почему это не работает?

Я тоже пробовал этот код, но он не работает.

@Override
public Board clone() throws CloneNotSupportedException{

    Board cloned = (Board) super.clone();
    cloned.board = (Pedine[][]) board.clone();
    for (int i=0; i<8; i++)
        for(int j=0; j<8; j++){
            cloned.board[i][j] = board[i][j].clone();
        }
    return cloned;
}

(Pedine расширяет объект)

+1
источник поделиться
2 ответа

Проблема, как указывает sharonbn, находится в двойном массиве. Хотя вы можете клонировать его вручную с помощью двойного цикла, ваш шахматный движок будет страдать от штрафа за производительность: вы будете клонировать множество досок, и вы можете извлечь выгоду из того, чтобы сделать их намного проще для копирования.

Один из вариантов - использовать плоский массив и некоторую умную адресацию для ускорения работы:

private Piece[] board; // 64 Pieces in there
public Piece at(col, row) {
    if (row < 0 || row >= 8 || col < 0 || col >= 8) return null;
    return board[col + row*8];
}

Теперь вместо доступа к board[row][col] вы используете at(col, row). А копирование и создание плат намного проще:

board = other.board.clone(); 

... должен работать так, как ожидалось.

Я также настоятельно рекомендую иметь непреложные части, без какой-либо информации о состоянии. Например, ваши текущие элементы имеют поле x и y. Для чего они нужны? Вы должны сказать им их фактические позиции только при перемещении их; Таким образом, вам не нужно клонировать кусочки вообще, потому что все пешки в точности одинаковы, и вы можете использовать одну и ту же "черную пешку" для всего, что связано с черной пешкой.

0
источник

глубокое клонирование многоразмерных массивов должно быть закодировано на заказ, как объясняется здесь

+1
источник

Посмотрите другие вопросы по меткам или Задайте вопрос