Java Chess: not sure how to clone correctly

I am writing a basic Java chess game and have written the following classes: Game, Player, Board, Square, Piece (the superclass of each of the separate pieces) and each specific class of pieces (for example, Pawn, Knight, Bishop, etc.)

One of the most difficult methods is to find out if the movement is valid based on whether it results in a checking of the moving player. My solution is this:

  • clone of the current board
  • make a move
  • See if the moving player is checked.
  • if so, prohibit traffic; else, allow move

I take my recommendations on how to clone from here: http://www.jusfortechies.com/java/core-java/cloning.php

The PCB object now consists of a 2d array of square objects. Every square object has a chunk margin that is either null (without it) or refers to a chunk object (there is a chunk on it). The board object also has whiteKingSquare and blackKingSquare (both are square objects) to make finding the white king or black king faster or easier.

In the Board class, I wrote the following method:

public Object clone() throws CloneNotSupportedException {
    Board clonedBoard = (Board) super.clone();
    for (int i = 0; i < HEIGHT; i++) {
        for (int j = 0; j < WIDTH; j++) {
            clonedBoard.myBoard[i][j] = new Square(this, i, j); 
            clonedBoard.whiteKingSquare = myBoard[7][4];
            clonedBoard.blackKingSquare = myBoard[0][4];
        }
    }
    return clonedBoard; 
}

      

However, since the Board refers to an 8 x 8 array of Square objects, I have to clone each one. I wrote this method in the Square class:

public Object clone() throws CloneNotSupportedException {
    return (Square) super.clone();
}

      

Finally, I wrote this method in the Piece class:

public Object clone() throws CloneNotSupportedException {
    return (Piece) super.clone();
}

      

On questions:

  • Does it look right?
  • My Square objects also have a Board field that basically allows me to reference the board they belong to. Would it be a mess with my trying to clone if each of my 64 squares clones the board separately?
+3


source to share


2 answers


I have an alternative solution, see if you like it or not.

No need to use clone

! I wrote a Chinese chess program some time ago. Let me explain what I did: (This is just an outline, you have to make the details yourself)



I had a 2D array Piece

and another 2D array of buttons. When the user clicks on Piece, an abstract method getValidLocations

on the class is called Piece

and that method returns a bunch of coordinates to indicate where it can go Piece

. When the user presses the button, the piece moves to the position of the button.

Bad news: I don't know how to play chess. I only know Chinese chess, so I cannot tell you how to write an algorithm getValidLocations

, sorry!

+7


source


Do not use clone()

. It's broken, make a full deep copy of your board instead. Here is a discussion with Josh Bloch on the copy and clone constructor

By making a deep copy, you will have different objects for each part, so moving them will not ruin the state of the corresponding part on the other board representing the alternate move.

It might make sense to make a method copy()

on all of your parts so that they can make valid copies of all of their internal states.



Example copy method:

Suppose your class Pawn

has a variable if it is moved with or without. This determines if it can traverse 2 spaces or just 1.

class Pawn{ 
       private boolean hasMovedAlready=false;
       ...
       public Pawn copy(){
          return new Pawn(hasMovedAlready, ...);
}

      

+4


source







All Articles