简体   繁体   English

具有矩阵(Java)的对象的深层复制(克隆)

[英]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. 我有这个Java项目,国际象棋,并且我需要使用clone()方法,因为我需要在不更改开发板的情况下尝试新的配置。

    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. 我创建一个对象scacchiera,然后将其克隆。 I think I have done correctly a deep copy, but when I change something in scacchiera, clone changes too. 我认为我已经正确地做了一个深拷贝,但是当我在scacchiera中更改某些内容时,克隆也将更改。 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: 我有双排的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();

}

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) (Pedine扩展对象)

多维阵列的深克隆应当定制编码,如解释这里

The problem, as sharonbn indicates, is in the double-array. 正如sharonbn指出的那样,问题出在双数组中。 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) . 现在,使用at(col, row)代替访问board[row][col] 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. 例如,您当前的作品有一个xy字段。 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. 这样,您根本不需要克隆片段-因为所有的pawn都是一样的,并且实际上您可以为所有与black-pawn相关的东西使用相同的“ black pawn”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM