part 3.2 + new class

This commit is contained in:
Lucie 2025-05-06 11:08:52 +02:00
parent 46d7812ed5
commit 45144b42e7
5 changed files with 534 additions and 153 deletions

View File

@ -13,7 +13,6 @@ public class Main {
Board testBoard = new Board(8, 8);
testBoard.populateBoard();
System.out.println(testBoard.toString());
// launches graphical interface :
MyInterface mjf = new MyInterface();
mjf.setVisible(true);

View File

@ -11,29 +11,42 @@ public class Board {
private int y;
private int turns;
private boolean whiteTurn;
private int[][] knightMoves = {{1, 2}, {2, 1}, {2, -1}, {1, -2}, {-1, -2}, {-2, -1}, {-2, 1}, {-1, 2}};
private int[][] kingMoves = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}, {1, 1}, {-1, -1}, {1, -1}, {-1, 1}};
private int[][] whitePawn = {{6}, {0, -1}, {1, -1}, {-1, -1}, {0, -2}};
private int[][] blackPawn = {{1}, {0, 1}, {1, 1}, {-1, 1}, {0, 2}};
private boolean enPassant;
private int enPassantX;
private int enPassantY;
private int pawnX;
private int pawnY;
private boolean whiteRookLeft;
private boolean whiteRookRight;
private boolean blackRookLeft;
private boolean blackRookRight;
private boolean whiteKing;
private boolean blackKing;
private boolean castlingRight;
private boolean castlingLeft;
public Board(int colNum, int lineNum) {
// CONSTRUCTOR
public Board(int colNum, int lineNum) {
this.colNum = colNum;
this.lineNum = lineNum;
this.board = new Piece[lineNum][colNum];
x = -1;
y = -1;
this.x = -1;
this.y = -1;
turns = 0;
whiteTurn = true;
enPassant = false;
pawnX = -1;
pawnY = -1;
whiteRookLeft = false;
whiteRookRight = false;
blackRookLeft = false;
blackRookRight = false;
whiteKing = false;
blackKing = false;
castlingRight = false;
castlingLeft = false;
}
// GETTERS
public int getWidth() {
return this.colNum;
}
@ -50,6 +63,24 @@ public class Board {
return whiteTurn;
}
// INITIALISE THE BOARD
public void initialise() {
x = -1;
y = -1;
turns = 0;
whiteTurn = true;
enPassant = false;
pawnX = -1;
pawnY = -1;
whiteRookLeft = false;
whiteRookRight = false;
blackRookLeft = false;
blackRookRight = false;
whiteKing = false;
blackKing = false;
}
public void setPiece(boolean isWhite, PieceType type, int x, int y) {
board[y][x] = new Piece(isWhite, type, x, y);
}
@ -76,10 +107,7 @@ public class Board {
}
public void cleanBoard() {
x = -1;
y = -1;
turns = 0;
whiteTurn = true;
initialise();
for (int i = 0; i < lineNum; i++) {
for (int j = 0; j < colNum; j++) {
board[i][j] = null;
@ -87,10 +115,14 @@ public class Board {
}
}
// WRITE THE BOARD AS A READABLE STRING
public String toString() {
String str = "";
String str = "";
// iterate through lines
for (int i = 0; i < lineNum; i++) {
// iterate through columns
for (int j = 0; j < colNum; j++) {
// write the corresponding letters depending on the piece on the board
if (board[i][j] == null) {
str += " ";
}
@ -109,6 +141,7 @@ public class Board {
return str;
}
// LIST THE PIECES OF THE BOARD
public ArrayList<Piece> getPieces() {
ArrayList<Piece> pieces = new ArrayList<>();
for (int i = 0; i < colNum; i++) {
@ -120,48 +153,6 @@ public class Board {
}
return pieces;
}
public void userTouch(int x, int y) {
if (this.x == -1 && this.y == -1) {
if (board[y][x] != null && board[y][x].isWhite() == whiteTurn) {
this.x = x;
this.y = y;
}
}
else {
if (this.x == x && this.y == y || board[this.y][this.x] == null) {
this.x = -1;
this.y = -1;
}
else if (isHighlighted(x,y)) {
if (enPassant == true && board[this.y][this.x].getType() == PieceType.Pawn && x == enPassantX && y == enPassantY) {
board[this.y][this.x].setX(x);
board[this.y][this.x].setY(y);
board[y][x] = board[this.y][this.x];
board[this.y][this.x] = null;
board[pawnY][pawnX] = null;
enPassant = false;
pawnX = -1;
pawnY = -1;
}
else {
if (board[this.y][this.x].getType() == PieceType.Pawn && (y == this.y+2 || y == this.y-2)) {
enPassant = true;
pawnX = x;
pawnY = y;
}
board[this.y][this.x].setX(x);
board[this.y][this.x].setY(y);
board[y][x] = board[this.y][this.x];
board[this.y][this.x] = null;
}
turns += 1;
this.x = -1;
this.y = -1;
whiteTurn = !whiteTurn;
}
}
}
public boolean inBoard(int x, int y) {
if (x > -1 && x < colNum && y > -1 && y < lineNum) {
@ -170,102 +161,113 @@ public class Board {
return false;
}
public void linearMoves(ArrayList<int[]> moves, int x, int y, int x2, int y2, boolean white) {
int i = x + x2;
int j = y + y2;
boolean metPiece = false;
while (metPiece == false && i > -1 && inBoard(i,j)) {
if (board[j][i] != null) {
metPiece = true;
if (board[j][i].isWhite() != white) {
moves.add(new int[]{i, j});
}
}
else {
moves.add(new int[]{i, j});
}
i += x2;
j += y2;
public Piece getPieceAt(int x, int y) {
if (inBoard(x,y)) {
return board[y][x];
}
return null;
}
public ArrayList<int[]> getMove(PieceType type, boolean isWhite, int x, int y) {
ArrayList<int[]> moves = new ArrayList<>();
int i;
int j;
int[][] pieceMoves;
if (type == PieceType.Rook || type == PieceType.Queen) {
linearMoves(moves, x, y, 1, 0, isWhite);
linearMoves(moves, x, y, -1, 0, isWhite);
linearMoves(moves, x, y, 0, -1, isWhite);
linearMoves(moves, x, y, 0, 1, isWhite);
}
if (type == PieceType.Bishop || type == PieceType.Queen) {
linearMoves(moves, x, y, 1, 1, isWhite);
linearMoves(moves, x, y, -1, 1, isWhite);
linearMoves(moves, x, y, 1, -1, isWhite);
linearMoves(moves, x, y, -1, -1, isWhite);
}
if (type == PieceType.Knight || type == PieceType.King) {
if (type == PieceType.Knight) {
pieceMoves = knightMoves;
// PROCESS THE USER CLICK
public void userTouch(int x, int y) {
// there have been no preselected location (no piece is selected)
if (this.x == -1 && this.y == -1) {
// if the location selected has a piece and the piece has the right color
if (board[y][x] != null && board[y][x].isWhite() == whiteTurn) {
// update coordinates
this.x = x;
this.y = y;
}
else {
pieceMoves = kingMoves;
}
// a piece is already selected (so the new click is where the user wants to move the piece)
else {
Move move = new Move(this.x,this.y,x,y);
MoveCalculator legalMoves = new MoveCalculator(this.board);
// if the new location is the same as before, de-selects the piece and no move happens
if (this.x == x && this.y == y || board[this.y][this.x] == null) {
this.x = -1;
this.y = -1;
}
for (int n = 0; n < pieceMoves.length; n++) {
i = x + pieceMoves[n][0];
j = y + pieceMoves[n][1];
if (inBoard(i,j)) {
if (board[j][i] != null && board[j][i].isWhite() != isWhite) {
moves.add(new int[] {i, j});
// the new location is highlighted, meaning it is a legal displacement
else if (isHighlighted(x,y)) {
// handling en passant
if (enPassant == true && board[this.y][this.x].getType() == PieceType.Pawn && x == legalMoves.getEnPassantX() && y == legalMoves.getEnPassantY()) {
playMove(move);
board[pawnY][pawnX] = null;
}
// castling to the left
else if (this.castlingLeft && x == this.x-2) {
if (board[this.y][this.x].isWhite()) {
// rook displacement (white left)
playMove(new Move(0,7,x+1,y));
}
else if (board[j][i] == null){
moves.add(new int[] {i, j});
else {
// rook displacement (black left)
playMove(new Move(0,0,x+1,y));
}
// king displacement
playMove(move);
}
// castling to the right
else if (this.castlingRight && x == this.x+2) {
if (board[this.y][this.x].isWhite()) {
// rook displacement (white right)
playMove(new Move(7,7,x-1,y));
}
else {
// rook displacement (black right)
playMove(new Move(7,0,x-1,y));
}
// king displacement
playMove(move);
}
// basic legal move
else {
// verify if the pawn goes two steps forward (to know if en passant will be possible for the opponent)
if (board[this.y][this.x].getType() == PieceType.Pawn && (y == this.y+2 || y == this.y-2)) {
enPassant =true;
pawnX = x;
pawnY = y;
}
// check if rooks or kings are beeing moved to enable (or not) castling later
if (board[this.y][this.x].getType() == PieceType.Rook) {
if (this.x == 0) {
if (board[this.y][this.x].isWhite() && whiteRookLeft == false) {
whiteRookLeft = true;
}
else if (board[this.y][this.x].isWhite() == false && blackRookLeft == false) {
blackRookLeft = true;
}
}
else if (this.x == 7) {
if (board[this.y][this.x].isWhite() && whiteRookRight == false) {
whiteRookRight = true;
}
else if (board[this.y][this.x].isWhite() == false && blackRookRight == false) {
blackRookRight = true;
}
}
}
else if (board[this.y][this.x].getType() == PieceType.King) {
if (board[this.y][this.x].isWhite()) {
whiteKing = true;
}
else if (board[this.y][this.x].isWhite() == false) {
blackKing = true;
}
}
playMove(move);
}
turns += 1;
this.x = -1;
this.y = -1;
whiteTurn = !whiteTurn;
}
}
if (type == PieceType.Pawn) {
if (isWhite == false) {
pieceMoves = blackPawn;
}
else {
pieceMoves = whitePawn;
}
i = x + pieceMoves[1][0];
j = y + pieceMoves[1][1];
if (inBoard(i,j) && board[j][i] == null) {
moves.add(new int[] {i, j});
if (y == pieceMoves[0][0]) {
i = x + pieceMoves[4][0];
j = y + pieceMoves[4][1];
if (inBoard(i,j) && board[j][i] == null) {
moves.add(new int[] {i, j});
}
}
}
for (int n = 2; n < 4; n++) {
i = x + pieceMoves[n][0];
j = y + pieceMoves[n][1];
if (inBoard(i,j) && board[j][i] != null && board[j][i].isWhite() != isWhite) {
moves.add(new int[] {i, j});
}
else if(inBoard(i,j) && board[j][i] == null && enPassant == true && i == pawnX && y == pawnY) {
moves.add(new int[] {i, j});
enPassantX = i;
enPassantY = j;
}
}
}
return moves;
}
public boolean isSelected(int x, int y) {
@ -291,11 +293,6 @@ public class Board {
this.colNum = 8;
this.lineNum = 8;
this.board = new Piece[lineNum][colNum];
this.x = -1;
this.y = -1;
this.turns = 0;
this.whiteTurn = true;
this.enPassant = false;
String[] line;
boolean white;
@ -320,8 +317,25 @@ public class Board {
/* The following methods require more work ! */
public boolean isHighlighted(int x, int y) {
boolean king;
boolean rookRight;
boolean rookLeft;
if (this.x != -1 && this.y != -1) {
ArrayList<int[]> moves = getMove(board[this.y][this.x].getType(), board[this.y][this.x].isWhite(), this.x, this.y);
if (board[this.y][this.x].isWhite()) {
king = whiteKing;
rookRight = whiteRookRight;
rookLeft = whiteRookLeft;
}
else {
king = blackKing;
rookRight = blackRookRight;
rookLeft = blackRookLeft;
}
MoveCalculator legalMoves = new MoveCalculator(this.board);
ArrayList<int[]> moves = legalMoves.getMove(board[this.y][this.x].getType(), board[this.y][this.x].isWhite(), this.x, this.y, king, rookRight, rookLeft, enPassant, pawnX, pawnY);
this.castlingLeft = legalMoves.getCastlingLeft();
this.castlingRight = legalMoves.getCastlingRight();
for (int i = 0; i < moves.size(); i++) {
if (x == moves.get(i)[0] && y == moves.get(i)[1]) {
return true;
@ -338,12 +352,13 @@ public class Board {
public Board(Board board) {
//TODO
}
public void playMove(Move move) {
//TODO
board[move.getFromY()][move.getFromX()].setX(move.getToX());
board[move.getFromY()][move.getFromX()].setY(move.getToY());
board[move.getToY()][move.getToX()] = board[move.getFromY()][move.getFromX()];
board[move.getFromY()][move.getFromX()] = null;
}
}

View File

@ -1,5 +1,38 @@
package backend;
public class Move {
private int fromX;
private int fromY;
private int toX;
private int toY;
public Move(int fromX, int fromY, int toX, int toY) {
this.fromX = fromX;
this.fromY = fromY;
this.toX = toX;
this.toY = toY;
}
public int getFromX() {
return this.fromX;
}
public int getFromY() {
return this.fromY;
}
public int getToX() {
return this.toX;
}
public int getToY() {
return this.toY;
}
public boolean noMove() {
if (fromX == toX && fromY == toY) {
return true;
}
return false;
}
}

View File

@ -0,0 +1,327 @@
package backend;
import java.util.ArrayList;
public class MoveCalculator {
private Piece[][] board1;
private int colNum;
private int lineNum;
private int[][] knightMoves;
private int[][] kingMoves;
private int[][] whitePawn;
private int[][] blackPawn;
private int[][] directions;
private boolean castlingRight;
private boolean castlingLeft;
private int enPassantX;
private int enPassantY;
ArrayList<int[]> moves;
public MoveCalculator(Piece[][] boardF) {
board1 = boardF;
knightMoves = new int[][] {{1, 2}, {2, 1}, {2, -1}, {1, -2}, {-1, -2}, {-2, -1}, {-2, 1}, {-1, 2}};
kingMoves = new int[][] {{1, 0}, {0, 1}, {-1, 0}, {0, -1}, {1, 1}, {-1, -1}, {1, -1}, {-1, 1}, {2, 0}, {-2, 0}};
whitePawn = new int[][] {{6}, {0, -1}, {1, -1}, {-1, -1}, {0, -2}};
blackPawn = new int[][] {{1}, {0, 1}, {1, 1}, {-1, 1}, {0, 2}};
directions = new int[][] {{0, 1}, {0, -1}, {1, 0}, {-1, 0}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}};
lineNum = 8;
colNum = 8;
castlingRight = false;
castlingLeft = false;
enPassantX = -1;
enPassantY = -1;
}
// GETTERS
public int getEnPassantX() {
return this.enPassantX;
}
public int getEnPassantY() {
return this.enPassantY;
}
public boolean getCastlingRight() {
return this.castlingRight;
}
public boolean getCastlingLeft() {
return this.castlingLeft;
}
// CHECK IF THE COORDINATES ARE IN THE BOARD
public boolean inBoard(int x, int y) {
if (x > -1 && x < colNum && y > -1 && y < lineNum) {
return true;
}
return false;
}
// CALCULATE LEGAL MOVES
// return if the piece of coordinates x,y in parameter is in check or not
public boolean check(Piece[][] board2, int x, int y, boolean white) {
int i;
int j;
// verify for knight or pawn displacements
for (int n = 0; n < knightMoves.length; n++) {
i = x + knightMoves[n][0];
j = y + knightMoves[n][1];
// verify if the coordinates are still in the board
if (inBoard(i,j)) {
// verify if the location is empty, if not, verify if the piece is a knight from the opponent
if (board2[j][i] != null && board2[j][i].isWhite() != white && board2[j][i].getType() == PieceType.Knight) {
return true;
}
}
}
// verify for pawn displacements
int[][] pawn;
if (white) {
pawn = whitePawn;
}
else {
pawn = blackPawn;
}
// consider only the diagonal displacements
for (int o = 2; o < 4; o++) {
i = x + pawn[o][0];
j = y + pawn[o][1];
// verify if the coordinates are still in the board
if (inBoard(i,j)) {
// verify if the location is empty, if not, verify if the piece is a pawn from the opponent
if (board2[j][i] != null && board2[j][i].isWhite() != white && board2[j][i].getType() == PieceType.Pawn) {
return true;
}
}
}
// verify for linear displacements (from directions array)
for (int p = 0; p < directions.length; p++) {
i = x + directions[p][0];
j = y + directions[p][1];
boolean metPiece = false;
// continue until the end of the board or until a piece is met
while (inBoard(i,j) && metPiece == false) {
// if the location is not empty
if (board2[j][i] != null) {
// verify if the met piece is from the opponent
if (board2[j][i].isWhite() != white) {
// first 4 directions correspond to horizontal and vertical displacements
if (p < 4 && (board2[j][i].getType() == PieceType.Rook || board2[j][i].getType() == PieceType.Queen)) {
return true;
}
// last 4 directions correspond to diagonal displacements
else if (p > 3 && (board2[j][i].getType() == PieceType.Bishop || board2[j][i].getType() == PieceType.Queen)) {
return true;
}
}
// if the met piece is not from the opponent, this means that in this direction, the piece is protected
else {
// stop the while loop to change direction
metPiece = true;
}
}
i += directions[p][0];
j += directions[p][1];
}
}
// if no true statement has been returned, the piece is not in check
return false;
}
// create a temporary board
// return if the king would be left in check if the move in parameter is played
public boolean checkIf(Move move, int kingX, int kingY, boolean white) {
// create a copy of the actual board
Piece[][] temporaryBoard = new Piece[lineNum][colNum];
for (int i = 0; i < colNum; i++) {
for (int j = 0; j < lineNum; j++) {
if (board1[j][i] != null) {
temporaryBoard[j][i] = new Piece(board1[j][i]);
}
}
}
// make the displacement in the temporary board
temporaryBoard[move.getFromY()][move.getFromX()].setX(move.getToX());
temporaryBoard[move.getFromY()][move.getFromX()].setY(move.getToY());
temporaryBoard[move.getToY()][move.getToX()] = temporaryBoard[move.getFromY()][move.getFromX()];
temporaryBoard[move.getFromY()][move.getFromX()] = null;
// verify if in this temporary board, the king is in check
return check(temporaryBoard, kingX, kingY, white);
}
// return the coordinates of the king of the color stated in parameter
public int[] findKing(boolean white) {
int[] coordinates = {-1, -1};
// iterate through all columns
for (int i = 0; i < colNum; i++) {
// iterate through all lines
for (int j = 0; j < lineNum; j++) {
// if the location is not empty, verify if it is the king from the right color
if (board1[j][i] != null && board1[j][i].getType() == PieceType.King && board1[j][i].isWhite() == white) {
// update the coordinates to return
coordinates[0] = i;
coordinates[1] = j;
}
}
}
return coordinates;
}
// calculate linear move of the piece at x,y for the direction x+x2,y+y2
public void linearMoves(ArrayList<int[]> moves, int x, int y, int x2, int y2, boolean white) {
int i = x + x2;
int j = y + y2;
boolean metPiece = false;
// continue until the end of the board or a piece is met
while (metPiece == false && inBoard(i,j)) {
Move move = new Move(x,y,i,j);
// locate the king to know if it would be in check if the selected piece moves
int[] coordinates = findKing(white);
// if the location is not empty
if (board1[j][i] != null) {
metPiece = true;
// verify if the piece met is from the opponent and that it won't let the king in check
if (board1[j][i].isWhite() != white && checkIf(move,coordinates[0],coordinates[1],white) == false) {
moves.add(new int[]{i, j});
}
}
// if the location is empty
else {
// verify if the piece won't let the king in check
if (checkIf(move,coordinates[0],coordinates[1],white) == false) {
moves.add(new int[]{i, j});
}
}
i += x2;
j += y2;
}
}
public ArrayList<int[]> getMove(PieceType type, boolean isWhite, int x, int y, boolean king, boolean rookRight, boolean rookLeft, boolean enPassant, int pawnX, int pawnY) {
// create an array list that will store the legal moves
ArrayList<int[]> moves = new ArrayList<>();
int i;
int j;
int[][] pieceMoves;
// locate the king to later see if the displacement is possible
int[] coordinates = findKing(isWhite);
// the piece selected is a rook or the queen (it moves vertically and horizontally)
if (type == PieceType.Rook || type == PieceType.Queen) {
for (int n = 0; n < 4; n++) {
i = directions[n][0];
j = directions[n][1];
linearMoves(moves, x, y, i, j, isWhite);
}
}
// the piece selected is a bishop or the queen (it moves diagonally)
if (type == PieceType.Bishop || type == PieceType.Queen) {
for (int n = 4; n < 8; n++) {
i = directions[n][0];
j = directions[n][1];
linearMoves(moves, x, y, i, j, isWhite);
}
}
// the piece selected is a knight or the king (it has a precise number of possible moves)
if (type == PieceType.Knight || type == PieceType.King) {
if (type == PieceType.Knight) {
pieceMoves = knightMoves;
}
else {
pieceMoves = kingMoves;
}
// iterates for the different possible moves
for (int n = 0; n < pieceMoves.length; n++) {
i = x + pieceMoves[n][0];
j = y + pieceMoves[n][1];
Move move = new Move(x,y,i,j);
// verify if the coordinates are still in the board
if (inBoard(i,j)) {
// the last 2 moves correspond to castling (right and left), so it verifies if the king and the (right or left) rook have never moved
if (n == 8 && king == false && rookRight == false) {
// verify if all the locations are empty and not threatened
if (board1[j][i-1] == null && board1[j][i] == null && check(board1,i,j,isWhite) == false && check(board1,i-1,j,isWhite) == false) {
moves.add(new int[] {i, j});
castlingRight = true;
}
}
// same for the other one
else if (n == 9 && king == false && rookLeft == false) {
if (board1[j][i+1] == null && board1[j][i] == null && board1[j][i-1] == null && check(board1,i,j,isWhite) == false && check(board1,i+1,j,isWhite) == false) {
moves.add(new int[] {i, j});
castlingLeft = true;
}
}
// if the location is not empty, verify if the piece met is from the opponent and that it won't let the king in check
else if (n < 8 && board1[j][i] != null && board1[j][i].isWhite() != isWhite && checkIf(move,coordinates[0],coordinates[1],isWhite) == false) {
moves.add(new int[] {i, j});
}
// if the location is empty, verify that it won't let the king in check
else if (n < 8 && board1[j][i] == null && checkIf(move,coordinates[0],coordinates[1],isWhite) == false){
moves.add(new int[] {i, j});
}
}
}
}
// the piece selected is a pawn
if (type == PieceType.Pawn) {
// select the right color
if (isWhite == false) {
pieceMoves = blackPawn;
}
else {
pieceMoves = whitePawn;
}
i = x + pieceMoves[1][0];
j = y + pieceMoves[1][1];
Move move = new Move(x,y,i,j);
// verify if the location in front of the pawn is in the board and empty, and if it won't let the king in check
if (inBoard(i,j) && board1[j][i] == null && checkIf(move,coordinates[0],coordinates[1],isWhite) == false) {
moves.add(new int[] {i, j});
// verify if the pawn is at its initial location
if (y == pieceMoves[0][0]) {
i = x + pieceMoves[4][0];
j = y + pieceMoves[4][1];
move = new Move(x,y,i,j);
// verify if the location is empty and won't let the king in check
if (inBoard(i,j) && board1[j][i] == null && checkIf(move,coordinates[0],coordinates[1],isWhite) == false) {
moves.add(new int[] {i, j});
}
}
}
// verify if there is any opponent piece in diagonal that the pawn can take
for (int n = 2; n < 4; n++) {
i = x + pieceMoves[n][0];
j = y + pieceMoves[n][1];
move = new Move(x,y,i,j);
// verify if the location is in the board and not empty, if the piece is from the opponent and if it won't let the king in check
if (inBoard(i,j) && board1[j][i] != null && board1[j][i].isWhite() != isWhite && checkIf(move,coordinates[0],coordinates[1],isWhite) == false) {
moves.add(new int[] {i, j});
}
// if en passant is possible, and if the piece right next to the selected one (on the same line) is the pawn of the opponent that went two steps forward the previous turn
else if(inBoard(i,j) && board1[j][i] == null && enPassant == true && i == pawnX && y == pawnY && checkIf(move,coordinates[0],coordinates[1],isWhite) == false) {
moves.add(new int[] {i, j});
// store the coordinates of the en passant move for later
enPassantX = i;
enPassantY = j;
}
}
}
return moves;
}
}

View File

@ -38,4 +38,11 @@ public class Piece {
return this.isWhite;
}
public Piece(Piece other) {
this.isWhite = other.isWhite;
this.type = other.type;
this.x = other.x;
this.y = other.y;
}
}