package backend; import java.util.ArrayList; import java.lang.Math; public class Board { private int colNum; private int lineNum; private ArrayList pieces; // coordinates of the square used private int x; private int y; private int turnNumber; private boolean lastTurnPawnTwo;//for en passant private int xTwo; private int yTwo; private boolean enPassant; private boolean kingWMoved; private boolean kingBMoved; private boolean rookLWMoved; private boolean rookRWMoved; private boolean rookLBMoved; private boolean rookRBMoved; private boolean castling; private boolean castlingDone; private ArrayList previousBoard; private ArrayList altPieces; private boolean isChecked; public Board(int colNum, int lineNum) { this.kingWMoved = false; this.kingBMoved = false; this.rookLWMoved = false; this.rookRWMoved = false; this.rookLBMoved = false; this.rookRBMoved = false; this.castling = false; this.castlingDone = false; this.colNum = colNum; this.lineNum = lineNum; pieces = new ArrayList<>(); x = -1; y = -1; turnNumber= 0; enPassant = false; lastTurnPawnTwo = false; previousBoard = new ArrayList<>(); } //test public int getWidth() { return colNum; //The width is represented by the columns } public int getHeight() { return lineNum;//The height is represented by the lines } public int getTurnNumber() { return turnNumber;//returns the turn number } public boolean isTurnWhite() { //check if it is the white player's turn boolean turnWhite = false; if (this.turnNumber % 2 == 0) { turnWhite = true; } return turnWhite; } public void setPiece(boolean isWhite, PieceType type, int x, int y) { Piece newPiece = new Piece(isWhite,type,x,y); pieces.add(newPiece); } public void populateBoard() { ArrayList basePieces = new ArrayList<>(); for(int i = 0; i getPieces() { return pieces; } public void userTouch(int x, int y) { boolean positionOccupied = this.positionOccupied(x, y) ; // verify if the square is occupied // if ((this.x == -1 ) && (positionOccupied == true)){ // set coordinates of the piece to play this.x = x; this.y = y; } else { if((this.x == x) && (this.y == y)) { // reset since square is already selected this.x = -1; this.y = -1; } else { // we know we already have a piece so we move it to another position boolean highlights = isHighlighted(x,y); if( this.positionOccupied(x, y) == true && highlights) { if (pieces.get(whatPiece(x,y)).isWhite() != pieces.get(whatPiece(this.x,this.y)).isWhite()) {//check if we do not move to a position occupied by a piece of the same color this.pieces.remove(whatPiece(x,y)); //if there is a piece at the position we want to move we remove it from the array list } else {//castling if (castling == true) { if (pieces.get(whatPiece(x,y)).getX()==7 || pieces.get(whatPiece(this.x,this.y)).getX()==7) {//that means we are dealing with the right rooks for castling if (pieces.get(whatPiece(this.x,this.y)).isWhite()==true){ kingWMoved = true; } else { kingBMoved = true; } pieces.get(whatPiece(7,y)).setX(5); pieces.get(whatPiece(4,y)).setX(6); this.x=-1; this.y=-1; this.turnNumber +=1; castlingDone=true; }//TEST else {//that means we are dealing with the right rooks for castling if (pieces.get(whatPiece(x,y)).isWhite()==true){ kingWMoved = true; } else { kingBMoved = true; } pieces.get(whatPiece(0,y)).setX(3); pieces.get(whatPiece(4,y)).setX(2); this.x=-1; this.y=-1; this.turnNumber +=1; castlingDone=true; } } } } if(((this.positionOccupied(x, y) == false || pieces.get(whatPiece(x,y)).isWhite() != pieces.get(whatPiece(this.x,this.y)).isWhite())) && (highlights) && castlingDone==false) {//moves the piece only if the position selected is not occupied by a piece of the same color if (enPassant) { this.pieces.remove(whatPiece(xTwo,yTwo)); enPassant = false; } if (pieces.get(whatPiece(this.x, this.y)).getX() == 0 && pieces.get(whatPiece(this.x, this.y)).getY() == 7) { rookLWMoved = true; } if (pieces.get(whatPiece(this.x, this.y)).getX() == 7 && pieces.get(whatPiece(this.x, this.y)).getY() == 7) { rookRWMoved = true; } if (pieces.get(whatPiece(this.x, this.y)).getX() == 0 && pieces.get(whatPiece(this.x, this.y)).getY() == 0) { rookLBMoved = true; } if (pieces.get(whatPiece(this.x, this.y)).getX() == 7 && pieces.get(whatPiece(this.x, this.y)).getY() == 0) { rookRBMoved = true; } if (pieces.get(whatPiece(this.x, this.y)).getX() == 4 && pieces.get(whatPiece(this.x, this.y)).getY() == 7) { kingWMoved = true; } if (pieces.get(whatPiece(this.x, this.y)).getX() == 4 && pieces.get(whatPiece(this.x, this.y)).getY() == 0) { kingBMoved = true; } int indexPiece = this.whatPiece(this.x, this.y); if (pieces.get(indexPiece).getType() == PieceType.Pawn && Math.abs(this.y-y)==2) {//save the number of the turn at which a pawn moved by two lastTurnPawnTwo = true; xTwo = x; yTwo = y; } else { lastTurnPawnTwo = false; } pieces.get(indexPiece).setX(x); pieces.get(indexPiece).setY(y); this.turnNumber +=1; } // we now reset our parameters this.x=-1; this.y=-1; castlingDone=false; previousBoard.add(this.toString()); // we add 1 to the number of turned played } } } public boolean isSelected(int x, int y) { boolean selection = false; if ((this.x == x) && (this.y == y)){ selection = true; } return selection; } /* saving-loading feature :*/ public String[] toFileRep() { String[] saveFile = new String[10]; // creation of the string array which will be the one returned String actualBoard = this.toString(); int nbLine = 0; saveFile[0] = ""; for(int i = 0; i<200 ;i++) { // there are in total 200 strings in the if (actualBoard.charAt(i) == '\n') { nbLine+=1; saveFile[nbLine]= ""; } else { saveFile[nbLine] += actualBoard.charAt(i); } } saveFile[8]=""; saveFile[8] += this.turnNumber; saveFile[9]=""; if (this.lastTurnPawnTwo == false) { saveFile[9]+= "0"; } else { saveFile[9]+= "1"; } saveFile[9] += xTwo; saveFile[9] += yTwo; if (this.enPassant == false) { saveFile[9]+="0"; } else { saveFile[9]+= "1"; } return saveFile; } public Board(String[] array) { this.colNum = 8; this.lineNum = 8; x = -1; y = -1; pieces = new ArrayList<>(); for(int i=0; i<8;i++) { // this will be the Y coordinate for(int j=0; j<8;j++) { // this will be the X coordinate if(array[i].charAt(j*3) != ' ') { Piece newPiece = new Piece(true,PieceType.Pawn,0,0); if(array[i].charAt(j*3)=='B') { newPiece.setIsWhite(false); } else { newPiece.setIsWhite(true); } newPiece.setType(PieceType.fromSummary(array[i].charAt((j*3)+1))); newPiece.setX(j); newPiece.setY(i); pieces.add(newPiece); } } } turnNumber = Integer.parseInt(array[8]); System.out.println(turnNumber); int turn = this.getTurnNumber(); System.out.println(turn); if(array[9].charAt(0)==0) { lastTurnPawnTwo = false; } else { lastTurnPawnTwo = true; } xTwo = Character.getNumericValue(array[9].charAt(1)); yTwo = Character.getNumericValue(array[9].charAt(2)); if(array[9].charAt(3)==0) { enPassant = false; } else { enPassant = true; } enPassant = false; kingWMoved = false; kingBMoved = false; rookLWMoved = false; rookRWMoved = false; rookLBMoved = false; rookRBMoved = false; castling = false; castlingDone = false; } /* The following methods require more work ! */ // COUCOU LES COPAINS SI VOUS ARRIVEZ A OPTIMISER LA SUITE CA SERAIT COOL public ArrayList> highlightBishop(){ //creates a table of the x and y coordinates to highlight for the bishop boolean spotOccupied = false; ArrayList> toHighlight = new ArrayList<> (); toHighlight.add(new ArrayList<>()); // ArrayList that will contain the x coordinates toHighlight.add(new ArrayList<>()); // ArrayList that will contain the y coordinates int i = 0; while (spotOccupied == false) { //left top diagonal if ((x-i-1 >= 0) && (y-i-1 >= 0)) { //check if we are still in the board toHighlight.get(0).add(this.x-i-1); toHighlight.get(1).add(this.y-i-1); if (positionOccupied(this.x-i-1,this.y-i-1)) { //if we reach a position already occupied, stops highlighting the diagonal spotOccupied = true; } } else { spotOccupied = true; } i += 1; } spotOccupied = false; i = 0; while (spotOccupied == false) { //left bottom diagonal if ((x-i-1 >= 0) && (y+1+i <= 7)) { toHighlight.get(0).add(this.x-i-1); toHighlight.get(1).add(this.y+i+1); if (positionOccupied(this.x-i-1,this.y+i+1)) { spotOccupied = true; } } else { spotOccupied = true; } i += 1; } spotOccupied = false; i = 0; while (spotOccupied == false) { //right bottom diagonal if ((x+1+i <= 7) && (y+1+i <= 7)) { toHighlight.get(0).add(this.x+i+1); toHighlight.get(1).add(this.y+i+1); if (positionOccupied(this.x+i+1,this.y+i+1)) { spotOccupied = true; } } else { spotOccupied = true; } i += 1; } spotOccupied = false; i = 0; while (spotOccupied == false) { //right top diagonal if ((y-i-1 >= 0) && (x+1+i <= 7)) { toHighlight.get(0).add(this.x+i+1); toHighlight.get(1).add(this.y-i-1); if (positionOccupied(this.x+i+1,this.y-i-1)) { spotOccupied = true; } } else { spotOccupied = true; } i += 1; } return toHighlight; } public ArrayList> highlightQueen(){ //list of positions to highlight for the queens ArrayList> toHighlight = highlightBishop(); ArrayList> toHighlight2 = highlightRook(); toHighlight.get(0).addAll(toHighlight2.get(0)); //combine the x coordinates toHighlight.get(1).addAll(toHighlight2.get(1)); //combine the y coordinates return toHighlight; } public ArrayList> highlightRook(){ //list of positions to highlight for the rooks boolean spotOccupied = false; ArrayList> toHighlight = new ArrayList<> (); toHighlight.add(new ArrayList<>()); toHighlight.add(new ArrayList<>()); int i = 0; while (spotOccupied == false) { //horizontal top line if (y-i-1 >= 0) { // check if we are still in the board (works the same as the bishop) toHighlight.get(0).add(this.x); toHighlight.get(1).add(this.y-i-1); if (positionOccupied(this.x,this.y-i-1)) { spotOccupied = true; } } else { spotOccupied = true; } i += 1; } spotOccupied = false; i = 0; while (spotOccupied == false) { //horizontal bottom line if (y+i+1 <= 7) { toHighlight.get(0).add(this.x); toHighlight.get(1).add(this.y+i+1); if (positionOccupied(this.x,this.y+i+1)) { spotOccupied = true; } } else { spotOccupied = true; } i += 1; } spotOccupied = false; i = 0; while (spotOccupied == false) { //vertical left line if (x-i-1 >= 0) { toHighlight.get(0).add(this.x-i-1); toHighlight.get(1).add(this.y); if (positionOccupied(this.x-i-1,this.y)) { spotOccupied = true; } } else { spotOccupied = true; } i += 1; } spotOccupied = false; i = 0; while (spotOccupied == false) { //vertical right line if (x+i+1 <= 7) { toHighlight.get(0).add(this.x+i+1); toHighlight.get(1).add(this.y); if (positionOccupied(this.x+i+1,this.y)) { spotOccupied = true; } } else { spotOccupied = true; } i += 1; } return toHighlight; } public boolean isHighlighted(int x, int y) { //not at all optimized, if you have ideas go ahead boolean highlight = false; if (positionOccupied(this.x,this.y)) { //check if we have selected a position with a piece int indexPieceSelect = whatPiece(this.x,this.y); if (pieces.get(indexPieceSelect).getType() == PieceType.Pawn) {//highlight for pawns if (pieces.get(indexPieceSelect).isWhite()) {//white pawns if (lastTurnPawnTwo) {//en passant if(yTwo == this.y && Math.abs(xTwo - this.x) == 1 && x == xTwo && y == this.y - 1) { highlight = true; enPassant = true; } } if(y == this.y-1) { if((x == this.x) && (positionOccupied(x,y)==false)) {//advance one case highlight = true; } if((Math.abs(x-this.x) == 1) && (positionOccupied(x,y)) && pieces.get(whatPiece(x,y)).isWhite() != pieces.get(indexPieceSelect).isWhite()) {//highlight the piece in diagonal, if existing and of another color highlight = true; } } if((y == this.y-2) && (this.y == 6) && (x == this.x) && (positionOccupied(this.x,this.y-1))==false) {//move by two if not moved and if no piece in front highlight = true; } } if (pieces.get(indexPieceSelect).isWhite() == false) {//black pawns if(y == this.y+1) { if (lastTurnPawnTwo) {//en passant if(yTwo == this.y && Math.abs(xTwo - this.x) == 1 && x == xTwo && y == this.y+1) { highlight = true; enPassant = true; } } if((x == this.x) && (positionOccupied(x,y)==false)) { highlight = true; } if((Math.abs(x-this.x) == 1) && (positionOccupied(x,y)) && pieces.get(whatPiece(x,y)).isWhite() != pieces.get(indexPieceSelect).isWhite()) { highlight = true; } } if((y == this.y+2) && (this.y == 1) && (x == this.x) && (positionOccupied(this.x,this.y+1) == false)) { highlight = true; } } } if (pieces.get(indexPieceSelect).getType() == PieceType.King) { //highlight for Kings THIS IS NOT OPTIMISED BC OF WHATPIECE (SAME FOR ALL FOLLOWING PIECES) if(positionOccupied(x,y) == false) { if((Math.abs(x-this.x) <= 1) && (Math.abs(y-this.y) <= 1)) { //consider all cases at distance one from the king if ((Math.abs(x-this.x) != 0) || (Math.abs(y-this.y) != 0)) { //check if we are not considering the place where the king is highlight = true; } } } else { if(pieces.get(whatPiece(x,y)).isWhite() != pieces.get(indexPieceSelect).isWhite()){ if((Math.abs(x-this.x) <= 1) && (Math.abs(y-this.y) <= 1)) { //consider all cases at distance one from the king if ((Math.abs(x-this.x) != 0) || (Math.abs(y-this.y) != 0)) { //check if we are not considering the place where the king is highlight = true; } } } //check if the castling is possible, if yes highlight the rook(s) int nbOccupied = 0; boolean occupiedLeftLine = true; boolean occupiedRightLine = true; for(int i = 3; i > 0; i--) { if (positionOccupied(i,pieces.get(indexPieceSelect).getY()) == true) { nbOccupied = nbOccupied + 1; } if (nbOccupied == 0) { occupiedLeftLine=false; } } if (occupiedLeftLine == false) {//check if the castling is possible with the rooks on the left if (kingWMoved == false && rookLWMoved == false && x==0 && y==7 && pieces.get(whatPiece(0,7)).isWhite() == pieces.get(indexPieceSelect).isWhite()) { highlight = true; castling = true; } if (kingBMoved == false && rookLBMoved == false && x==0 && y==0 && pieces.get(whatPiece(0,0)).isWhite() == pieces.get(indexPieceSelect).isWhite()) { highlight = true; castling = true; // } //else { //castling = false; } } nbOccupied = 0; for(int i = 5; i < 7; i++) { if (positionOccupied(i,pieces.get(indexPieceSelect).getY()) == true) { nbOccupied = nbOccupied + 1; } if (nbOccupied == 0) { occupiedRightLine=false; } } if (occupiedRightLine == false) {//check if the castling is possible with the rooks on the right if (kingWMoved == false && rookRWMoved == false && x==7 && y==7 && pieces.get(whatPiece(7,7)).isWhite() == pieces.get(indexPieceSelect).isWhite()) { highlight = true; castling = true; } if (kingBMoved == false && rookRBMoved == false && x==7 && y==0 && pieces.get(whatPiece(7,0)).isWhite() == pieces.get(indexPieceSelect).isWhite()) { highlight = true; castling = true; } // else { // castling = false; //} } nbOccupied = 0; } /*altPieces = pieces; //create a copy of pieces that we will modify to check if the movement leaves the king in check if (highlight) { altPieces.get(whatPiece(this.x,this.y)).setX(x); altPieces.get(whatPiece(this.x,this.y)).setY(y); }*/ } if (pieces.get(indexPieceSelect).getType() == PieceType.Knight) { //highlight for knights if(positionOccupied(x,y) == false) { if (((Math.abs(x-this.x) == 1) && (Math.abs(y-this.y) == 2)) || ((Math.abs(x-this.x) == 2) && (Math.abs(y-this.y) == 1))) {//consider all positions at 2 by 1 from the knight highlight = true; } } else { if(pieces.get(whatPiece(x,y)).isWhite() != pieces.get(indexPieceSelect).isWhite()){ if (((Math.abs(x-this.x) == 1) && (Math.abs(y-this.y) == 2)) || ((Math.abs(x-this.x) == 2) && (Math.abs(y-this.y) == 1))) {//consider all positions at 2 by 1 from the knight highlight = true; } } } } if (pieces.get(indexPieceSelect).getType() == PieceType.Bishop) { //highlight for bishops int numHighlight = highlightBishop().get(0).size(); for(int i = 0; i < numHighlight; i++) { if ((x == highlightBishop().get(0).get(i)) && (y == highlightBishop().get(1).get(i))) {//check if the considered x and y are in the list of positions that should be highlighted if(positionOccupied(x,y) == false) { highlight = true; } else { if(pieces.get(whatPiece(x,y)).isWhite() != pieces.get(indexPieceSelect).isWhite()) { highlight = true; } } } } } if (pieces.get(indexPieceSelect).getType() == PieceType.Queen) { //highlight for Queens int numHighlight = highlightQueen().get(0).size(); for(int i = 0; i < numHighlight; i++) { if ((x == highlightQueen().get(0).get(i)) && (y == highlightQueen().get(1).get(i))) {//check if the considered x and y are in the list of positions that should be highlighted if(positionOccupied(x,y) == false) { highlight = true; } else { if(pieces.get(whatPiece(x,y)).isWhite() != pieces.get(indexPieceSelect).isWhite()) { highlight = true; } } } } } if (pieces.get(indexPieceSelect).getType() == PieceType.Rook) { //highlight for rooks int numHighlight = highlightRook().get(0).size(); for(int i = 0; i < numHighlight; i++) { if ((x == highlightRook().get(0).get(i)) && (y == highlightRook().get(1).get(i))) {//check if the considered x and y are in the list of positions that should be highlighted if(positionOccupied(x,y) == false) { highlight = true; } else { if(pieces.get(whatPiece(x,y)).isWhite() != pieces.get(indexPieceSelect).isWhite()) { highlight = true; } //check if the castling is possible, if yes highlight the king if (pieces.get(indexPieceSelect).isWhite() == true) {//check if castling is possible for the white if (kingWMoved == false && rookLWMoved == false && x==4 && y==7 && pieces.get(indexPieceSelect).getX()==0 && pieces.get(indexPieceSelect).getY()==7) { highlight = true; castling = true; } if (kingWMoved == false && rookRWMoved == false && x==4 && y==7 && pieces.get(indexPieceSelect).getX()==7 && pieces.get(indexPieceSelect).getY()==7) { highlight = true; castling = true; } else { castling = false; } } if (pieces.get(indexPieceSelect).isWhite() == false) {//check if castling is possible for the black if (kingBMoved == false && rookLBMoved == false && x==4 && y==0 && pieces.get(indexPieceSelect).getX()==0 && pieces.get(indexPieceSelect).getY()==0) { highlight = true; castling = true; } if (kingBMoved == false && rookRBMoved == false && x==4 && y==0 && pieces.get(indexPieceSelect).getX()==7 && pieces.get(indexPieceSelect).getY()==0) { highlight = true; castling = true; } else { castling = false; } } } } } } } return highlight; } public void undoLastMove() { if(turnNumber == 0) { String lastBoard = previousBoard.get(turnNumber); // we have a String but we need a String[] in order to use the constructer String[] oldBoard = new String[10]; boolean complete = false; int indexLine=0; int indexColumn=0; for(int i=0; i<10; i++) { oldBoard[i] = ""; } while (complete == false) { if (lastBoard.charAt(indexColumn) == '\n') { indexLine+=1; if (indexLine == 10) { complete= true; } } else { oldBoard[indexLine] += lastBoard.charAt(indexColumn); } indexColumn+=1; } Board undo = new Board(oldBoard); this.pieces = undo.pieces; this.xTwo=undo.xTwo; this.yTwo=undo.yTwo; this.enPassant=undo.enPassant; this.lastTurnPawnTwo=undo.lastTurnPawnTwo; } if (turnNumber != 0 ) { turnNumber -= 1; String lastBoard = previousBoard.get(turnNumber); // we have a String but we need a String[] in order to use the constructer String[] oldBoard = new String[10]; boolean complete = false; int indexLine=0; int indexColumn=0; for(int i=0; i<10; i++) { oldBoard[i] = ""; } while (complete == false) { if (lastBoard.charAt(indexColumn) == '\n') { indexLine+=1; if (indexLine == 10) { complete= true; } } else { oldBoard[indexLine] += lastBoard.charAt(indexColumn); } indexColumn+=1; } Board undo = new Board(oldBoard); this.pieces = undo.pieces; this.xTwo=undo.xTwo; this.yTwo=undo.yTwo; this.enPassant=undo.enPassant; this.lastTurnPawnTwo=undo.lastTurnPawnTwo; previousBoard.remove(turnNumber+1); } } public Board(Board board) { //TODO } public void playMove(Move move) { //TODO } }