tried to clean the code

This commit is contained in:
Lucie 2025-05-24 18:43:28 +02:00
parent 5a80488b2f
commit ba441cc3da
7 changed files with 595 additions and 446 deletions

View File

@ -12,6 +12,7 @@ public class AutoPlayer {
int randomY;
MoveCalculator moveCalc;
Piece piece;
Board board;
PieceType type;
boolean[] bool;
boolean enPassant;
@ -27,11 +28,10 @@ public class AutoPlayer {
public void computeBestMove(Board board) {
legalMoves = new ArrayList<>();
board1 = board.getBoard(board);
this.board = board;
board1 = board.getBoard();
isWhite = board.isTurnWhite();
rand = new Random();
System.out.println(board.toString());
boolean ok = true;
while (legalMoves.size() == 0) {
randomX = rand.nextInt(8);
randomY = rand.nextInt(8);
@ -39,36 +39,23 @@ public class AutoPlayer {
randomX = rand.nextInt(8);
randomY = rand.nextInt(8);
}
moveCalc = new MoveCalculator(board1);
moveCalc = new MoveCalculator(board);
piece = board1[randomY][randomX];
type = board1[randomY][randomX].getType();
bool = board.getBooleans();
enPassant = bool[0];
rookLeft = true;
rookRight = true;
king = true;
if (isWhite) {
rookLeft = bool[1];
rookRight = bool[2];
king = bool[5];
}
else {
rookLeft = bool[3];
rookRight = bool[4];
king = bool[6];
}
pawnX = board.getPawnX();
pawnY = board.getPawnY();
legalMoves = moveCalc.getMove(type, isWhite, randomX, randomY, king, rookRight, rookLeft, enPassant, pawnX, pawnY);
enPassant = board.getEnPassant();
rookLeft = board.hasPieceMoved(PieceType.Rook, isWhite, false);
rookRight = board.hasPieceMoved(PieceType.Rook, isWhite, true);
king = board.hasPieceMoved(PieceType.King, isWhite, false);
legalMoves = moveCalc.getMove(type, isWhite, randomX, randomY);
}
board.userTouch(randomX, randomY);
board.userTouch(randomX, randomY, board);
randomX = rand.nextInt(8);
randomY = rand.nextInt(8);
while (board.isHighlighted(randomX, randomY)==false) {
while (board.isHighlighted(randomX, randomY, board)==false) {
randomX = rand.nextInt(8);
randomY = rand.nextInt(8);
}
board.userTouch(randomX, randomY);
board.userTouch(randomX, randomY, board);
}

View File

@ -3,27 +3,23 @@ package backend;
import java.util.ArrayList;
public class Board {
private Check check;
private Piece piece;
private Move move;
private MoveCalculator moveCalc;
private MoveGenerator playMove;
private int colNum;
private int lineNum;
private Piece[][] board;
private int x;
private int y;
private int selectedX;
private int selectedY;
private int turns;
private boolean whiteTurn;
private int[] secondPieceCoord;
private boolean enPassant;
private int pawnX;
private int pawnY;
private int enPassantX;
private int enPassantY;
private boolean whiteRookLeft;
private boolean whiteRookRight;
private boolean blackRookLeft;
private boolean blackRookRight;
private boolean whiteKing;
private boolean blackKing;
private boolean castlingRight;
private boolean castlingLeft;
ArrayList<String> states;
// CONSTRUCTOR
@ -70,46 +66,34 @@ public class Board {
return null;
}
public boolean isCheckmate() {
Check check = new Check(board);
public boolean isCheckmate(Board board2) {
check = new Check(board2);
return check.isCheckmate(whiteTurn);
}
public Piece[][] getBoard(Board board1) {
System.out.println(board1.board);
return board1.board;
public Piece[][] getBoard() {
return this.board;
}
public boolean[] getBooleans() {
boolean[] bool = {enPassant, whiteRookLeft, whiteRookRight, blackRookLeft, blackRookRight, whiteKing, blackKing};
return bool;
public int[] getSecondPiece() {
return secondPieceCoord;
}
public int getPawnX() {
return pawnX;
}
public int getPawnY() {
return pawnY;
public boolean getEnPassant() {
return enPassant;
}
// INITIALISE THE BOARD
public void initialise() {
this.x = -1;
this.y = -1;
selectedX = -1;
selectedY = -1;
turns = 0;
whiteTurn = true;
enPassant = false;
pawnX = -1;
pawnY = -1;
enPassantX = -1;
enPassantY = -1;
whiteRookLeft = false;
whiteRookRight = false;
blackRookLeft = false;
blackRookRight = false;
whiteKing = false;
blackKing = false;
secondPieceCoord = new int[2];
secondPieceCoord[0] = -1;
secondPieceCoord[1] = -1;
states = new ArrayList<>();
}
@ -122,7 +106,7 @@ public class Board {
}
public void setPiece(boolean isWhite, PieceType type, int x, int y) {
board[y][x] = new Piece(isWhite, type, x, y);
board[y][x] = new Piece(isWhite, type, x, y, false);
}
public void setPiece(Piece piece) {
@ -130,6 +114,65 @@ public class Board {
int y = piece.getY();
board[y][x] = new Piece(piece);
}
public int[] findPiece(PieceType type, boolean isWhite) {
int[] coordinates = new int[2];
for (int i = 0; i < colNum; i++) {
for (int j = 0; j < lineNum; j++) {
if (!noPiece(i,j) && board[j][i].getType() == type && board[j][i].isWhite() == isWhite) {
coordinates[0] = i;
coordinates[1] = j;
return coordinates;
}
}
}
return null;
}
public boolean hasMoved(int x, int y) {
if (!noPiece(x,y)) {
return board[y][x].hasMoved();
}
return true;
}
public boolean hasPieceMoved(PieceType type, boolean isWhite, boolean right) {
int y1 = 0;
if (isWhite) {
y1 = 7;
}
if (type == PieceType.Rook) {
if (right) {
return hasMoved(7,y1);
}
return hasMoved(0,y1);
}
else if (type == PieceType.Knight) {
if (right) {
return hasMoved(6,y1);
}
return hasMoved(1,y1);
}
else if (type == PieceType.Bishop) {
if (right) {
return hasMoved(5,y1);
}
return hasMoved(2,y1);
}
else if (type == PieceType.Queen) {
return hasMoved(3,y1);
}
else if (type == PieceType.King) {
return hasMoved(4,y1);
}
else {
return true;
}
}
public void setEnPassant(boolean enPassant) {
this.enPassant = enPassant;
}
public void populateBoard() {
for (int i = 0; i < lineNum; i++) {
@ -189,15 +232,43 @@ public class Board {
if (isTurnWhite()) {
end = "W";
}
boolean whiteRookLeft = true;
boolean whiteRookRight = true;
boolean blackRookLeft = true;
boolean blackRookRight = true;
boolean whiteKing = true;
boolean blackKing = true;
if (!noPiece(0,0)) {
blackRookLeft = board[0][0].hasMoved();
}
if (!noPiece(7,0)) {
blackRookRight = board[0][7].hasMoved();
}
if (!noPiece(0,7)) {
whiteRookLeft = board[7][0].hasMoved();
}
if (!noPiece(7,7)) {
whiteRookRight = board[7][7].hasMoved();
}
if (!noPiece(4,7)) {
whiteKing = board[7][4].hasMoved();
}
if (!noPiece(4,0)) {
blackKing = board[0][4].hasMoved();
}
Boolean[] booleans = {enPassant, whiteRookLeft, whiteRookRight, blackRookLeft, blackRookRight, whiteKing, blackKing};
for (int k = 0; k < 7; k++) {
end += Boolean.toString(booleans[k]).charAt(0);
}
int[] integers = {pawnX, pawnY, enPassantX, enPassantY};
for (int n = 0; n < 4; n++) {
end += Integer.toString(integers[n]).charAt(0);
for (int n = 0; n < 2; n++) {
end += Integer.toString(secondPieceCoord[n]).charAt(0);
}
str += end;
str += "\n";
str += Integer.toString(turns);
return str;
}
@ -208,126 +279,63 @@ public class Board {
return false;
}
public boolean isPieceSelected() {
if (selectedX != -1 && selectedY != -1 /*&& board[selectedY][selectedX] != null*/) {
return true;
}
return false;
}
public boolean isRightPiece(int x, int y, boolean white) {
if (inBoard(x,y) && board[y][x].isWhite() != white) {
return false;
}
return true;
}
public boolean noPiece(int x, int y) {
if (inBoard(x,y) && board[y][x] == null) {
return true;
}
return false;
}
// PROCESS THE USER CLICK
public void userTouch(int x, int y) {
public void userTouch(int clickedX, int clickedY, Board board2) {
move = new Move(selectedX,selectedY,clickedX,clickedY);
// 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;
}
if (!noPiece(clickedX,clickedY) && isRightPiece(clickedX,clickedY,whiteTurn) && (!isPieceSelected() || !move.noMove())) {
// update coordinates
selectedX = clickedX;
selectedY = clickedY;
}
// 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);
else if (isPieceSelected()){
// if the new location is the same as before, de-selects the piece and no move happens
if (move.noMove() || board[this.y][this.x] == null) {
this.x = -1;
this.y = -1;
}
else if (board[y][x] != null && board[y][x].isWhite() == whiteTurn) {
// update coordinates
this.x = x;
this.y = y;
if (move.noMove()) {
selectedX = -1;
selectedY = -1;
}
// the new location is highlighted, meaning it is a legal displacement
else if (isHighlighted(x,y)) {
Piece piece = board[this.y][this.x];
// handling en passant
if (this.enPassant == true && piece.getType() == PieceType.Pawn && x == enPassantX && y == enPassantY) {
board[pawnY][pawnX] = null;
playMove(move);
this.states.add(toString());
}
// castling to the left
else if (this.castlingLeft && x == this.x-2) {
if (piece.isWhite()) {
// rook displacement (white left)
playMove(new Move(0,7,x+1,y));
}
else {
// rook displacement (black left)
playMove(new Move(0,0,x+1,y));
}
// king displacement
playMove(move);
this.states.add(toString());
}
// castling to the right
else if (this.castlingRight && x == this.x+2) {
if (piece.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);
this.states.add(toString());
}
// basic legal move
else {
// verify if the pawn goes two steps forward (to know if en passant will be possible for the opponent)
if (piece.getType() == PieceType.Pawn && (y == this.y+2 || y == this.y-2)) {
// sets that en passant can be done next turn
enPassant = true;
// coordinates of the pawn that can be taken
pawnX = x;
pawnY = y;
}
else {
enPassant = false;
pawnX = -1;
pawnY = -1;
}
// check if rooks or kings are beeing moved to enable (or not) castling later
playMove(move);
this.states.add(toString());
if (piece.getType() == PieceType.Rook) {
if (this.x == 0) {
if (piece.isWhite()) {
whiteRookLeft = true;
}
else {
blackRookLeft = true;
}
}
else if (this.x == 7) {
if (piece.isWhite()) {
whiteRookRight = true;
}
else {
blackRookRight = true;
}
}
}
else if (piece.getType() == PieceType.King) {
if (piece.isWhite()) {
whiteKing = true;
}
else {
blackKing = true;
}
}
else if (isHighlighted(clickedX,clickedY,board2)) {
enPassant = isPawnTwo(move);
if (enPassant) {
secondPieceCoord[0] = clickedX;
secondPieceCoord[1] = clickedY;
//move.setEnPassant(enPassant);
}
playMove(move);
turns += 1;
this.x = -1;
this.y = -1;
selectedX = -1;
selectedY = -1;
whiteTurn = !whiteTurn;
this.states.add(toString());
}
}
}
public boolean isSelected(int x, int y) {
if (this.x == x && this.y == y) {
if (selectedX == x && selectedY == y) {
return true;
}
return false;
@ -346,8 +354,9 @@ public class Board {
this.colNum = 8;
this.lineNum = 8;
this.board = new Piece[lineNum][colNum];
this.x = -1;
this.y = -1;
selectedX = -1;
selectedY = -1;
secondPieceCoord = new int[2];
String[] line;
boolean white;
@ -360,7 +369,7 @@ public class Board {
if (line[i].charAt(0) == 'W') {
white = true;
}
Piece piece = new Piece(white, PieceType.fromSummary(line[i].charAt(1)), i, j);
piece = new Piece(white, PieceType.fromSummary(line[i].charAt(1)), i, j, true);
board[j][i] = new Piece(piece);
}
}
@ -372,34 +381,25 @@ public class Board {
this.turns = Integer.parseInt(array[lineNum+1]);
states = new ArrayList<>();
states.add(toString());
}
/* 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) {
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();
this.enPassantX = legalMoves.getEnPassantX();
this.enPassantY = legalMoves.getEnPassantY();
public boolean isHighlighted(int x, int y, Board board2) {
if (isPieceSelected()) {
//boolean king = hasPieceMoved(PieceType.King, whiteTurn, true);
//boolean rookRight = hasPieceMoved(PieceType.Rook, whiteTurn, true);
//boolean rookLeft = hasPieceMoved(PieceType.Rook, whiteTurn, false);
Piece selectedPiece = board[selectedY][selectedX];
moveCalc = new MoveCalculator(board2);
ArrayList<int[]> moves = moveCalc.getMove(selectedPiece.getType(), selectedPiece.isWhite(), selectedX, selectedY);
//this.castlingLeft = moveCalc.getCastlingLeft();
castlingRight = moveCalc.getCastlingRight();
//this.enPassantX = moveCalc.getEnPassantX();
//this.enPassantY = moveCalc.getEnPassantY();
for (int i = 0; i < moves.size(); i++) {
if (x == moves.get(i)[0] && y == moves.get(i)[1]) {
return true;
@ -410,12 +410,12 @@ public class Board {
}
public void undoLastMove() {
if (this.turns > 0) {
states.remove(this.turns);
this.turns = turns - 1;
if (turns > 0) {
states.remove(turns);
turns = turns - 1;
//this.board = new Piece[lineNum][colNum];
this.x = -1;
this.y = -1;
selectedX = -1;
selectedY = -1;
String[] undo = states.get(turns).split("\n");
Board newBoard = new Board(undo);
@ -439,26 +439,34 @@ public class Board {
}
int[] integers = new int[4];
for (int n = 8; n < 12; n++) {
for (int n = 8; n < 10; n++) {
if (undo[lineNum].charAt(n) == '-') {
integers[n-8] = -1;
secondPieceCoord[n-8] = -1;
}
else {
integers[n-8] = Character.getNumericValue(undo[lineNum].charAt(n));
secondPieceCoord[n-8] = Character.getNumericValue(undo[lineNum].charAt(n));
}
}
this.enPassant = booleans[0];
this.whiteRookLeft = booleans[1];
this.whiteRookRight = booleans[2];
this.blackRookLeft = booleans[3];
this.blackRookRight = booleans[4];
this.whiteKing = booleans[5];
this.blackKing = booleans[6];
this.pawnX = integers[0];
this.pawnY = integers[1];
this.enPassantX = integers[2];
this.enPassantY = integers[3];
if (!noPiece(0,0)) {
board[0][0].setMoved(booleans[3]);
}
if (!noPiece(7,0)) {
board[0][7].setMoved(booleans[4]);
}
if (!noPiece(0,7)) {
board[7][0].setMoved(booleans[1]);
}
if (!noPiece(7,7)) {
board[7][7].setMoved(booleans[2]);
}
if (!noPiece(4,7)) {
board[7][4].setMoved(booleans[5]);
}
if (!noPiece(4,0)) {
board[0][4].setMoved(booleans[6]);
}
}
}
@ -467,7 +475,7 @@ public class Board {
Piece[][] newBoard = new Piece[lineNum][colNum];
for (int i = 0; i < colNum; i++) {
for (int j = 0; j < lineNum; j++) {
Piece piece = board.getPieceAt(i,j);
piece = board.getPieceAt(i,j);
if (piece != null) {
newBoard[j][i] = new Piece(piece);
}
@ -476,32 +484,29 @@ public class Board {
}
public Board(Piece[][] board) {
Piece[][] newBoard = new Piece[lineNum][colNum];
//Piece[][] newBoard = new Piece[lineNum][colNum];
for (int i = 0; i < colNum; i++) {
for (int j = 0; j < lineNum; j++) {
Piece piece = board[j][i];
piece = board[j][i];
if (piece != null) {
newBoard[j][i] = new Piece(piece);
this.board[j][i] = new Piece(piece);
}
}
}
}
public void playMove(Move move) {
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;
promotion(move.getToX(), move.getToY());
}
private void promotion(int x, int y) {
if (board[y][x] != null && board[y][x].getType() == PieceType.Pawn) {
boolean isWhite = board[y][x].isWhite(); // Declare 'isWhite' here
if ((isWhite && y == 0) || (!isWhite && y == 7)) {
board[y][x] = new Piece(isWhite, PieceType.Queen, x, y); // Now valid
}
}
isPawnTwo(move);
playMove = new MoveGenerator(board,move);
playMove.playMove(move, secondPieceCoord, castlingRight);
}
public boolean isPawnTwo(Move move) {
Piece pieceSelected = board[move.getFromY()][move.getFromX()];
if (pieceSelected.getType() == PieceType.Pawn && (move.getFromY() == move.getToY()+2 || move.getFromY() == move.getToY()-2)) {
return true;
}
return false;
}
}

View File

@ -3,20 +3,21 @@ package backend;
import java.util.ArrayList;
public class Check {
private Piece[][] board;
private Board board1;
private int colNum;
private int lineNum;
private int lineNum;
private int[][] knightMoves;
private int[][] kingMoves;
private int[][] whitePawn;
private int[][] blackPawn;
private int[][] directions;
private int[][] directions;
ArrayList<int[]> moves;
MoveCalculator calculator;
public Check(Piece[][] boardF) {
board = boardF;
public Check(Board boardF) {
board = boardF.getBoard();
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}};
@ -24,7 +25,7 @@ public class Check {
directions = new int[][] {{0, 1}, {0, -1}, {1, 0}, {-1, 0}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}};
lineNum = 8;
colNum = 8;
calculator = new MoveCalculator(board);
calculator = new MoveCalculator(board1);
}
// return the coordinates of the king of the color stated in parameter
@ -47,7 +48,7 @@ public class Check {
// return if the piece of coordinates x,y in parameter is in check or not
public boolean isCheck(Piece[][] board2, int x, int y, boolean white) {
int i;
int i;
int j;
// verify for knight or king displacements
@ -121,9 +122,65 @@ public class Check {
i += directions[p][0];
j += directions[p][1];
}
}
}
// if no true statement has been returned, the piece is not in check
return false;
/* TEST OF ANOTHER METHOD BUT DOESN'T WORK :/
calculator = new MoveCalculator(board1);
ArrayList<int[]> moves = new ArrayList<>();
int x2;
int y2;
// knight displacements
moves = calculator.getKnightMoves(moves, x, y, white);
for (int i = 0; i < moves.size(); i++) {
x2 = x+moves.get(i)[0];
y2 = y+moves.get(i)[1];
if (board1.inBoard(x2,y2) && !board1.noPiece(x2,y2) && board[y2][x2].getType() == PieceType.Knight && board[y2][x2].isWhite() == white) {
return true;
}
}
// king displacements
moves = calculator.getKingMoves(moves, x, y, white);
for (int i = 0; i < moves.size(); i++) {
x2 = x+moves.get(i)[0];
y2 = y+moves.get(i)[1];
if (board1.inBoard(x2,y2) && !board1.noPiece(x2,y2) && board[y2][x2].getType() == PieceType.King && board[y2][x2].isWhite() != white) {
return true;
}
}
// queen displacements
moves = calculator.getQueenMoves(moves, x, y, white);
for (int i = 0; i < moves.size(); i++) {
x2 = x+moves.get(i)[0];
y2 = y+moves.get(i)[1];
if (board1.inBoard(x2,y2) && !board1.noPiece(x2,y2) && board[y2][x2].getType() == PieceType.Queen && board[y2][x2].isWhite() != white) {
return true;
}
}
// rook displacements
moves = calculator.getRookMoves(moves, x, y, white);
for (int i = 0; i < moves.size(); i++) {
x2 = x+moves.get(i)[0];
y2 = y+moves.get(i)[1];
if (board1.inBoard(x2,y2) && !board1.noPiece(x2,y2) && board[y2][x2].getType() == PieceType.Rook && board[y2][x2].isWhite() != white) {
return true;
}
}
moves = calculator.specialMovesCalculator(moves, PieceType.Pawn, white, x, y);
for (int i = 0; i < moves.size(); i++) {
x2 = x+moves.get(i)[0];
y2 = y+moves.get(i)[1];
if (board1.inBoard(x2,y2) && !board1.noPiece(x2,y2) && board[y2][x2].getType() == PieceType.Pawn && board[y2][x2].isWhite() != white) {
return true;
}
}
return false;*/
}
// return if the king would be left in check if the move in parameter is played
@ -151,66 +208,17 @@ public class Check {
// return if there is a checkmate
public boolean isCheckmate(boolean turnWhite) {
MoveCalculator legalMoves = new MoveCalculator(board);
calculator = new MoveCalculator(board1);
ArrayList<int[]> moves;
int[] kingCoordinates = findKing(turnWhite);
if (isCheck(board, kingCoordinates[0], kingCoordinates[1], turnWhite)) {
Board board2 = new Board(board);
String state = board2.toString();
boolean[] booleans = new boolean[7];
for (int k = 1; k < 8; k++) {
if (state.charAt(k) == 'f') {
booleans[k-1] = false;
}
else {
booleans[k-1] = true;
}
}
int[] integers = new int[4];
for (int n = 8; n < 12; n++) {
if (state.charAt(n) == '-') {
integers[n-8] = -1;
}
else {
integers[n-8] = Character.getNumericValue(state.charAt(n));
}
}
boolean enPassant = booleans[0];
boolean whiteRookLeft = booleans[1];
boolean whiteRookRight = booleans[2];
boolean blackRookLeft = booleans[3];
boolean blackRookRight = booleans[4];
boolean whiteKing = booleans[5];
boolean blackKing = booleans[6];
int pawnX = integers[0];
int pawnY = integers[1];
boolean king = whiteKing;
boolean rookRight = whiteRookRight;
boolean rookLeft = whiteRookLeft;
for (int i = 0; i < colNum; i++) {
for (int j = 0; j < lineNum; j++) {
Piece piece = board[j][i];
if (piece != null && piece.isWhite() == turnWhite) {
if (turnWhite) {
king = whiteKing;
rookRight = whiteRookRight;
rookLeft = whiteRookLeft;
}
else {
king = blackKing;
rookRight = blackRookRight;
rookLeft = blackRookLeft;
}
PieceType type = piece.getType();
moves = legalMoves.getMove(type, turnWhite, i, j, king, rookRight, rookLeft, enPassant, pawnX, pawnY);
moves = calculator.getMove(type, turnWhite, i, j);
if (moves.size() != 0) {
return false;
}

View File

@ -61,7 +61,7 @@ public class Game extends Thread {
return;
}
if(!isAITurn()) {
board.userTouch(x, y);
board.userTouch(x, y, board);
}
}
@ -96,7 +96,7 @@ public class Game extends Thread {
}
public boolean isHighlighted(int x, int y) {
return board.isHighlighted(x, y);
return board.isHighlighted(x, y, board);
}
public void undoLastMove() {
@ -108,7 +108,7 @@ public class Game extends Thread {
}
public boolean isCheckmate() {
return board.isCheckmate();
return board.isCheckmate(board);
}
}

View File

@ -4,8 +4,10 @@ import java.util.ArrayList;
public class MoveCalculator {
private Piece[][] board;
private Board board1;
private int colNum;
private int lineNum;
private int[] secondPieceCoord;
private int[][] knightMoves;
private int[][] kingMoves;
private int[][] whitePawn;
@ -13,12 +15,11 @@ public class MoveCalculator {
private int[][] directions;
private boolean castlingRight;
private boolean castlingLeft;
private int enPassantX;
private int enPassantY;
ArrayList<int[]> moves;
public MoveCalculator(Piece[][] boardI) {
board = boardI;
public MoveCalculator(Board boardI) {
board1 = boardI;
board = board1.getBoard();
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}};
@ -28,19 +29,10 @@ public class MoveCalculator {
colNum = 8;
castlingRight = false;
castlingLeft = false;
enPassantX = -1;
enPassantY = -1;
secondPieceCoord = board1.getSecondPiece();
}
// GETTERS
public int getEnPassantX() {
return this.enPassantX;
}
public int getEnPassantY() {
return this.enPassantY;
}
public boolean getCastlingRight() {
return this.castlingRight;
}
@ -49,6 +41,11 @@ public class MoveCalculator {
return this.castlingLeft;
}
public void setSecondPiece(int x, int y) {
secondPieceCoord[0] = x;
secondPieceCoord[1] = y;
}
// CHECK IF THE COORDINATES ARE IN THE BOARD
public boolean inBoard(int x, int y) {
if (x > -1 && x < colNum && y > -1 && y < lineNum) {
@ -59,169 +56,224 @@ public class MoveCalculator {
// CALCULATE LEGAL MOVES
public ArrayList<int[]> getMove(PieceType type, boolean isWhite, int x, int y) {
// create an array list that will store the legal moves
moves = new ArrayList<>();
legalMovesCalculator(moves, type, isWhite, x, y);
specialMovesCalculator(moves, type, isWhite, x, y);
removeCheck(x, y, isWhite, type);
return moves;
}
public ArrayList<int[]> getRookMoves(ArrayList<int[]> moves, int x, int y, boolean isWhite) {
int i;
int j;
for (int n = 0; n < 4; n++) {
i = directions[n][0];
j = directions[n][1];
linearMoves(moves, x, y, i, j, isWhite);
}
return moves;
}
public ArrayList<int[]> getQueenMoves(ArrayList<int[]> moves, int x, int y, boolean isWhite) {
int i;
int j;
for (int n = 0; n < 8; n++) {
i = directions[n][0];
j = directions[n][1];
linearMoves(moves, x, y, i, j, isWhite);
}
return moves;
}
public ArrayList<int[]> getBishopMoves(ArrayList<int[]> moves, int x, int y, boolean isWhite) {
int i;
int j;
for (int n = 4; n < 8; n++) {
i = directions[n][0];
j = directions[n][1];
linearMoves(moves, x, y, i, j, isWhite);
}
return moves;
}
public ArrayList<int[]> getKingMoves(ArrayList<int[]> moves, int x, int y, boolean isWhite) {
int i;
int j;
for (int n = 0; n < 8; n++) {
i = x + kingMoves[n][0];
j = y + kingMoves[n][1];
if (inBoard(i,j)) {
moves.add(new int[] {i, j});
}
}
return moves;
}
public ArrayList<int[]> getKnightMoves(ArrayList<int[]> moves, int x, int y, boolean isWhite) {
int i;
int j;
for (int n = 0; n < 8; n++) {
i = x + knightMoves[n][0];
j = y + knightMoves[n][1];
if (inBoard(i,j)) {
moves.add(new int[] {i, j});
}
}
return moves;
}
public ArrayList<int[]> getPawnMoves(ArrayList<int[]> moves, int x, int y, boolean isWhite) {
int i;
int j;
int[][] pieceMoves;
if (isWhite == false) {
pieceMoves = blackPawn;
}
else {
pieceMoves = whitePawn;
}
i = x + pieceMoves[1][0];
j = y + pieceMoves[1][1];
// 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) && board[j][i] == null) {
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];
if (inBoard(i,j)) {
moves.add(new int[] {i, j});
}
}
}
return moves;
}
// 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;
public void linearMoves(ArrayList<int[]> moves, int x, int y, int directionX, int directionY, boolean white) {
int newX = x + directionX;
int newY = y + directionY;
boolean metPiece = false;
// continue until the end of the board or a piece is met
while (metPiece == false && inBoard(i,j)) {
moves.add(new int[]{i, j});
while (metPiece == false && inBoard(newX,newY)) {
moves.add(new int[]{newX, newY});
// if the location is not empty
if (board[j][i] != null) {
if (board[newY][newX] != null) {
metPiece = true;
}
i += x2;
j += y2;
newX += directionX;
newY += directionY;
}
}
public ArrayList<int[]> legalMovesCalculator(ArrayList<int[]> moves, PieceType type, boolean isWhite, int x, int y) {
// create an array list that will store the legal moves
int i;
int j;
int[][] pieceMoves;
// 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);
}
if (type == PieceType.Rook) {
getRookMoves(moves, x, y, 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);
}
else if (type == PieceType.Queen) {
getQueenMoves(moves, x, y, isWhite);
}
// the piece selected is the king
if (type == PieceType.King || type == PieceType.Knight) {
if (type == PieceType.Knight) {
pieceMoves = knightMoves;
}
else {
pieceMoves = kingMoves;
}
// iterates for the different possible moves
for (int n = 0; n < 8; n++) {
i = x + pieceMoves[n][0];
j = y + pieceMoves[n][1];
if (inBoard(i,j)) {
moves.add(new int[] {i, j});
}
}
else if (type == PieceType.King) {
getKingMoves(moves, x, y, isWhite);
}
// 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];
// 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) && board[j][i] == null) {
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];
if (inBoard(i,j)) {
moves.add(new int[] {i, j});
}
}
}
else if (type == PieceType.Bishop) {
getBishopMoves(moves, x, y, isWhite);
}
else if (type == PieceType.Knight) {
getKnightMoves(moves, x, y, isWhite);
}
else if (type == PieceType.Pawn) {
getPawnMoves(moves, x, y, isWhite);
}
return moves;
}
public ArrayList<int[]> specialMovesCalculator(ArrayList<int[]> moves, 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
Check check = new Check(this.board);
int i;
int j;
int[][] pieceMoves;
public ArrayList<int[]> specialMovesCalculator(ArrayList<int[]> moves, PieceType type, boolean isWhite, int x, int y) {
// the piece selected is the king
if (type == PieceType.King) {
// iterates for the different possible moves
for (int n = 8; n < kingMoves.length; n++) {
i = x + kingMoves[n][0];
j = y + kingMoves[n][1];
// verify if the coordinates are still in the board
if (inBoard(i,j)) {
if ((isWhite && y == 7) || (!isWhite && y == 0)) {
// 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 (board[j][i-1] == null && board[j][i] == null && check.isCheck(board,i,j,isWhite) == false && check.isCheck(board,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 (board[j][i+1] == null && board[j][i] == null && board[j][i-1] == null && check.isCheck(board,i,j,isWhite) == false && check.isCheck(board,i+1,j,isWhite) == false) {
moves.add(new int[] {i, j});
castlingLeft = true;
}
}
}
}
getCastling(moves, isWhite, x, y);
}
// the piece selected is a pawn
boolean enPassant = board1.getEnPassant();
if (type == PieceType.Pawn) {
getEnPassant(moves, isWhite, x, y, enPassant);
}
return moves;
}
public ArrayList<int[]> getEnPassant(ArrayList<int[]> moves, boolean isWhite, int x, int y, boolean enPassant) {
int i;
int j;
int[][] pieceMoves;
// select the right color
if (isWhite == false) {
pieceMoves = blackPawn;
}
else {
pieceMoves = whitePawn;
}
// 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];
// 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) && board[j][i] != null && board[j][i].isWhite() != isWhite) {
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) && board[j][i] == null && enPassant && i == secondPieceCoord[0] && y == secondPieceCoord[1]) {
moves.add(new int[] {i, j});
}
}
return moves;
}
// the piece selected is a pawn
if (type == PieceType.Pawn) {
// select the right color
if (isWhite == false) {
pieceMoves = blackPawn;
}
else {
pieceMoves = whitePawn;
}
// 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];
// 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) && board[j][i] != null && board[j][i].isWhite() != isWhite) {
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) && board[j][i] == null && enPassant == true && i == pawnX && y == pawnY) {
moves.add(new int[] {i, j});
// store the coordinates of the en passant move for later
enPassantX = i;
enPassantY = j;
public ArrayList<int[]> getCastling(ArrayList<int[]> moves, boolean isWhite, int x, int y) {
// create an array list that will store the legal moves
Check check = new Check(board1);
int i;
int j;
boolean king = board1.hasPieceMoved(PieceType.King, isWhite, true);
boolean rookRight = board1.hasPieceMoved(PieceType.Rook, isWhite, true);
boolean rookLeft = board1.hasPieceMoved(PieceType.Rook, isWhite, false);
for (int n = 8; n < kingMoves.length; n++) {
i = x + kingMoves[n][0];
j = y + kingMoves[n][1];
// verify if the coordinates are still in the board
if (inBoard(i,j)) {
if ((isWhite && y == 7) || (!isWhite && y == 0)) {
// 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.noPiece(i-1,j) && board1.noPiece(i,j) && check.isCheck(board,i,j,isWhite) == false && check.isCheck(board,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 (board[j][i+1] == null && board[j][i] == null && board[j][i-1] == null && check.isCheck(board,i,j,isWhite) == false && check.isCheck(board,i+1,j,isWhite) == false) {
moves.add(new int[] {i, j});
castlingLeft = true;
}
}
}
}
}
return moves;
}
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<>();
legalMovesCalculator(moves, type, isWhite, x, y);
specialMovesCalculator(moves, type, isWhite, x, y, king, rookRight, rookLeft, enPassant, pawnX, pawnY);
Check check = new Check(this.board);
public void removeCheck(int x, int y, boolean isWhite, PieceType type) {
Check check = new Check(board1);
int[] coordinates = check.findKing(isWhite);
int k = 0;
while (k < moves.size()) {
int i = moves.get(k)[0];
int j = moves.get(k)[1];
@ -244,6 +296,5 @@ public class MoveCalculator {
}
k += 1;
}
return moves;
}
}

View File

@ -0,0 +1,87 @@
package backend;
public class MoveGenerator {
Piece[][] board;
Move move;
public MoveGenerator(Piece[][] board, Move move) {
this.board = board;
this.move = move;
}
public void playMove(Move move, int[] secondPiece, boolean castlingRight) {
board[move.getFromY()][move.getFromX()].setMoved(true);
if (isEnPassant(move)) {
playEnPassant(move, secondPiece);
}
else if (isCastling(move)) {
playCastling(move, secondPiece, castlingRight);
}
else {
playDisplacement(move);
}
promotion(move.getToX(), move.getToY());
}
public void playDisplacement(Move move) {
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;
promotion(move.getToX(), move.getToY());
}
public void playCastling(Move move, int[] secondPiece, boolean right) {
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;
if (right) {
board[move.getFromY()][7].setX(move.getToX()-1);
board[move.getFromY()][7].setY(move.getToY());
board[move.getToY()][move.getToX()-1] = board[move.getFromY()][7];
board[move.getFromY()][7] = null;
}
else {
board[move.getFromY()][0].setX(move.getToX()+1);
board[move.getFromY()][0].setY(move.getToY());
board[move.getToY()][move.getToX()+1] = board[move.getFromY()][0];
board[move.getFromY()][0] = null;
}
}
public void playEnPassant(Move move, int[] secondPiece) {
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;
board[secondPiece[1]][secondPiece[0]] = null;
promotion(move.getToX(), move.getToY());
}
private void promotion(int x, int y) {
if (board[y][x] != null && board[y][x].getType() == PieceType.Pawn) {
boolean isWhite = board[y][x].isWhite(); // Declare 'isWhite' here
if ((isWhite && y == 0) || (!isWhite && y == 7)) {
board[y][x] = new Piece(isWhite, PieceType.Queen, x, y, false); // Now valid
}
}
}
public boolean isCastling(Move move) {
Piece piece = board[move.getFromY()][move.getFromX()];
if (piece.getType() == PieceType.King && (move.getFromX() == move.getToX()-2 || move.getFromX() == move.getToX()+2)) {
return true;
}
return false;
}
public boolean isEnPassant(Move move) {
Piece pieceSelected = board[move.getFromY()][move.getFromX()];
Piece pieceTo = board[move.getToY()][move.getToX()];
if (pieceSelected.getType() == PieceType.Pawn && (move.getFromX() == move.getToX()+1 || move.getFromX() == move.getToX()-1) && (move.getFromY() == move.getToY()+1 || move.getFromY() == move.getToY()-1) && pieceTo == null) {
return true;
}
return false;
}
}

View File

@ -8,12 +8,14 @@ public class Piece {
private int y;
private boolean isWhite;
private PieceType type;
private boolean hasMoved;
public Piece(boolean isWhite, PieceType type, int x, int y) {
public Piece(boolean isWhite, PieceType type, int x, int y, boolean hasMoved) {
this.isWhite = isWhite;
this.type = type;
this.x = x;
this.y = y;
this.hasMoved = hasMoved;
}
public int getX() {
@ -40,11 +42,20 @@ public class Piece {
return this.isWhite;
}
public boolean hasMoved() {
return this.hasMoved;
}
public void setMoved(boolean moved) {
this.hasMoved = moved;
}
public Piece(Piece piece) {
this.isWhite = piece.isWhite;
this.type = piece.type;
this.x = piece.x;
this.y = piece.y;
this.hasMoved = piece.hasMoved;
}