package backend; import java.util.ArrayList; public class Board { private int selectedX = -1; private int selectedY = -1; private int turnNumber = 0; public int width; public int height; private Piece[][] board; private ArrayList highlightedPositions = new ArrayList<>(); private int[] lastPawnDoubleMove = null; // Added for en passant tracking public Board(int colNum, int lineNum) { this.width = colNum; this.height = lineNum; this.board = new Piece[width][height]; clearConsole(); System.out.println(toString()); } public int getWidth() { return width; } public int getHeight() { return height; } public void setPiece(boolean isWhite, PieceType type, int x, int y) { board[x][y] = new Piece(x, y, type, isWhite); } public boolean isTurnWhite() { return turnNumber % 2 == 0; } public int getTurnNumber() { return turnNumber; } public void incrementTurn() { turnNumber++; } public void populateBoard() { // Black setPiece(false, PieceType.Rook, 0, 0); setPiece(false, PieceType.Knight, 1, 0); setPiece(false, PieceType.Bishop, 2, 0); setPiece(false, PieceType.Queen, 3, 0); setPiece(false, PieceType.King, 4, 0); setPiece(false, PieceType.Bishop, 5, 0); setPiece(false, PieceType.Knight, 6, 0); setPiece(false, PieceType.Rook, 7, 0); // Black pawns for (int i = 0; i < 8; i++) { setPiece(false, PieceType.Pawn, i, 1); } // White pawns for (int i = 0; i < 8; i++) { setPiece(true, PieceType.Pawn, i, 6); } // White setPiece(true, PieceType.Rook, 0, 7); setPiece(true, PieceType.Knight, 1, 7); setPiece(true, PieceType.Bishop, 2, 7); setPiece(true, PieceType.Queen, 3, 7); setPiece(true, PieceType.King, 4, 7); setPiece(true, PieceType.Bishop, 5, 7); setPiece(true, PieceType.Knight, 6, 7); setPiece(true, PieceType.Rook, 7, 7); } public void cleanBoard() { for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { board[x][y] = null; } } } public Piece getPiece(int x, int y) { if (!isInBounds(x, y)) return null; return board[x][y]; } private void clearConsole() { for (int i = 0; i < 50; i++) { System.out.println(); } } public boolean isEnPassantTarget(int x, int y) { if (lastPawnDoubleMove == null) return false; if (lastPawnDoubleMove[2] != turnNumber - 1) return false; return (lastPawnDoubleMove[0] == x && lastPawnDoubleMove[1] == y); } public void userTouch(int x, int y) { if (selectedX == -1 && selectedY == -1) { if (board[x][y] != null && board[x][y].isWhite() == isTurnWhite()) { selectedX = x; selectedY = y; highlightedPositions = getValidMoves(board[x][y]); } } else { if (x == selectedX && y == selectedY) { selectedX = -1; selectedY = -1; highlightedPositions.clear(); } else { boolean valid = false; for (int[] pos : highlightedPositions) { if (pos[0] == x && pos[1] == y) { valid = true; break; } } if (valid) { Piece pieceToMove = board[selectedX][selectedY]; // Check for en passant capture if (pieceToMove.getType() == PieceType.Pawn && x != selectedX && board[x][y] == null) { board[x][selectedY] = null; // Capture the pawn } // Handle castling if(pieceToMove.getType() == PieceType.King && Math.abs(x - selectedX)==2) { y = selectedY; if (x == 6) { board[5][y] = board[7][y]; board[7][y] = null; board[5][y].setMoved(true); board[5][y].setX(5); board[5][y].setY(y); } else if (x == 2) { board[3][y] = board[0][y]; board[0][y] = null; board[3][y].setMoved(true); board[3][y].setX(3); board[3][y].setY(y); } } // Track pawn double move for en passant if (pieceToMove.getType() == PieceType.Pawn && Math.abs(y - selectedY) == 2) { lastPawnDoubleMove = new int[]{x, y, turnNumber}; } else { lastPawnDoubleMove = null; } // Move the piece board[x][y] = new Piece(x, y, pieceToMove.getType(), pieceToMove.isWhite()); board[x][y].setMoved(true); board[selectedX][selectedY] = null; incrementTurn(); clearConsole(); } selectedX = -1; selectedY = -1; highlightedPositions.clear(); System.out.println(toString()); } } } public boolean isSelected(int x, int y) { return (x == selectedX && y == selectedY); } public boolean isHighlighted(int x, int y) { for (int[] pos : highlightedPositions) { if (pos[0] == x && pos[1] == y) { return true; } } return false; } public boolean isInBounds(int x, int y) { return x >= 0 && x < width && y >= 0 && y < height; } private ArrayList getValidMoves(Piece piece) { return piece.getValidMoves(this); } public ArrayList getPieces() { ArrayList pieces = new ArrayList<>(); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { if (board[x][y] != null) { pieces.add(board[x][y]); } } } return pieces; } public String toString() { StringBuilder str = new StringBuilder(); str.append(" A B C D E F G H\n"); for (int y = 0; y < height; y++) { str.append(8 - y).append(" "); for (int x = 0; x < width; x++) { if (board[x][y] == null) { str.append("- "); } else { Piece piece = board[x][y]; char pieceChar; switch (piece.getType()) { case King: pieceChar = 'K'; break; case Queen: pieceChar = 'Q'; break; case Bishop: pieceChar = 'B'; break; case Knight: pieceChar = 'N'; break; case Rook: pieceChar = 'R'; break; case Pawn: pieceChar = 'P'; break; default: pieceChar = '?'; break; } if (!piece.isWhite()) { pieceChar = Character.toLowerCase(pieceChar); } str.append(pieceChar).append(" "); } } str.append("\n"); } str.append("Turn ").append(getTurnNumber()).append(": "); str.append(isTurnWhite() ? "White" : "Black"); return str.toString(); } public String[] toFileRep() { String[] rep = new String[height + 1]; for (int y = 0; y < height; y++) { StringBuilder line = new StringBuilder(); for (int x = 0; x < width; x++) { if (board[x][y] == null) { line.append("-"); } else { Piece piece = board[x][y]; String pieceChar = piece.getType().getSummary(); if (!piece.isWhite()) { pieceChar = pieceChar.toLowerCase(); } line.append(pieceChar); } if (x < width - 1) { line.append(","); } } rep[y] = line.toString(); } rep[height] = isTurnWhite() ? "W" : "B"; return rep; } public Board(String[] fileRepresentation) { this.height = fileRepresentation.length - 1; this.width = fileRepresentation[0].split(",").length; this.board = new Piece[width][height]; this.selectedX = -1; this.selectedY = -1; this.highlightedPositions = new ArrayList<>(); for (int y = 0; y < height; y++) { String[] squares = fileRepresentation[y].split(","); for (int x = 0; x < width; x++) { String squareData = squares[x]; if (squareData.equals("-")) { continue; } char pieceChar = squareData.charAt(0); boolean isWhite = Character.isUpperCase(pieceChar); if (!isWhite) { pieceChar = Character.toUpperCase(pieceChar); } PieceType type = PieceType.fromSummary(pieceChar); setPiece(isWhite, type, x, y); } } String turnInfo = fileRepresentation[height]; this.turnNumber = turnInfo.equals("W") ? 0 : 1; clearConsole(); System.out.println(toString()); } public void undoLastMove() { // TODO } public void playMove(Move move) { // TODO } public Board(Board board) { // TODO } }