Deep copy (clone) of an object with matrix (Java)
i have some trouble with deep copying. I have this java project, chess, and I need to use the clone() method, because I need to try new configurations without changing the board.
Board scacchiera = new Board();
Initialization(scacchiera);
Board clone = scacchiera.clone();
System.out.println(scacchiera.toString());
System.out.println(clone.toString());
I create an object, scacchiera, then I clone it. I think I have done correctly a deep copy, but when I change something in scacchiera, clone changes too. In object 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;
}
I have this double array of Pedine, and I have to clone it too, so I do:
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();
}
Why it doesn't work?
I tried this code too, but it doesn't work.
@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 extends Object)
The problem, as sharonbn indicates, is in the double-array. While you can clone it manually with a double-loop, your chess engine is going to suffer a performance penalty: you will be cloning a lot of boards, and you can benefit from making them a lot easier to copy around.
One option is to use a flat array and some clever addressing to speed things up:
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];
}
Now, instead of accessing board[row][col]
you use at(col, row)
. And copying and creating boards is a lot easier:
board = other.board.clone();
... should now work as expected.
I also strongly recommend having immutable pieces, with no state information whatsoever. Your current pieces have an x
and y
field, for example. What do they need those for? You should tell them their actual positions only while moving them; that way, you don't need to clone pieces at all -- because all pawns are exactly alike, and you can actually use the same "black pawn" for everything black-pawn related.
如此处所解释的,多维数组的深度克隆应该被自定义编码
链接地址: http://www.djcxy.com/p/6974.html