From 4cf17ac98744355aa8388a78fd06f6a77c50705f Mon Sep 17 00:00:00 2001 From: User Date: Tue, 13 May 2025 14:44:29 +0200 Subject: [PATCH] en passant --- src/backend/Board.java | 71 ++++++++++++++++++++++++++++-------------- 1 file changed, 47 insertions(+), 24 deletions(-) diff --git a/src/backend/Board.java b/src/backend/Board.java index 7db3edb..c082f5e 100644 --- a/src/backend/Board.java +++ b/src/backend/Board.java @@ -13,6 +13,7 @@ public class Board { private int turnNumber = 0; private boolean turnWhite = true; private ArrayList highlightedSquares = new ArrayList<>(); + private int[] enPassantTarget = null; // [x,y] of the square behind the pawn that just moved two squares public Board(int colNum, int lineNum) { this.width = colNum; @@ -75,6 +76,7 @@ public class Board { board[x][y] = null; } } + enPassantTarget = null; } public String toString() { @@ -99,10 +101,12 @@ public class Board { } stringboard.append("\n"); stringboard.append("Turn: ").append(isTurnWhite() ? "White" : "Black"); + if (enPassantTarget != null) { + stringboard.append(" | En passant: ").append((char)('a' + enPassantTarget[0])).append(enPassantTarget[1] + 1); + } return stringboard.toString(); } - public ArrayList getPieces() { ArrayList pieces = new ArrayList<>(); for (int x = 0; x < width; x++) { @@ -113,10 +117,6 @@ public class Board { } } return pieces; - - - - } public boolean isSelected(int x, int y) { @@ -127,7 +127,6 @@ public class Board { return x >= 0 && x < width && y >= 0 && y < height; } - private ArrayList getValidMoves(Piece piece) { ArrayList moves = new ArrayList<>(); int x = piece.getX(); @@ -138,24 +137,38 @@ public class Board { int dir = piece.isWhite() ? 1 : -1; int startRow = piece.isWhite() ? 1 : 6; + // Normal forward moves int oneStep = y + dir; if (inBounds(x, oneStep) && board[x][oneStep] == null) { moves.add(new int[]{x, oneStep}); - // If on start row, try two steps forward + // Two-step move from starting position int twoStep = y + 2 * dir; - if (y == startRow && inBounds(x, twoStep) && board[x][twoStep] == null) { + if (y == startRow && inBounds(x, twoStep) && board[x][twoStep] == null && board[x][oneStep] == null) { moves.add(new int[]{x, twoStep}); } } - // Capture diagonals + // Capture moves (including en passant) for (int dx : new int[]{-1, 1}) { int nx = x + dx; int ny = y + dir; - if (inBounds(nx, ny) && board[nx][ny] != null && - board[nx][ny].isWhite() != piece.isWhite()) { - moves.add(new int[]{nx, ny}); + if (inBounds(nx, ny)) { + // Normal diagonal capture + if (board[nx][ny] != null && board[nx][ny].isWhite() != piece.isWhite()) { + moves.add(new int[]{nx, ny}); + } + // En passant capture + else if (board[nx][ny] == null && enPassantTarget != null && + nx == enPassantTarget[0] && ny == enPassantTarget[1]) { + // Check there's actually an opponent pawn to capture + int pawnY = piece.isWhite() ? ny - 1 : ny + 1; + if (inBounds(nx, pawnY) && board[nx][pawnY] != null && + board[nx][pawnY].getType() == PieceType.Pawn && + board[nx][pawnY].isWhite() != piece.isWhite()) { + moves.add(new int[]{nx, ny}); + } + } } } } @@ -176,7 +189,6 @@ public class Board { } } } - else if (type == PieceType.Bishop) { int[][] dirs = {{1,1}, {-1,1}, {-1,-1}, {1,-1}}; for (int[] d : dirs) { @@ -194,13 +206,11 @@ public class Board { } } } - else if (type == PieceType.Queen) { // Queen = Rook + Bishop moves.addAll(getValidMoves(new Piece(x, y, piece.isWhite(), PieceType.Rook))); moves.addAll(getValidMoves(new Piece(x, y, piece.isWhite(), PieceType.Bishop))); } - else if (type == PieceType.Knight) { int[][] jumps = { {2,1},{1,2},{-1,2},{-2,1}, @@ -215,7 +225,6 @@ public class Board { } } } - else if (type == PieceType.King) { int[][] dirs = { {1,0}, {-1,0}, {0,1}, {0,-1}, @@ -234,9 +243,6 @@ public class Board { return moves; } - - - public void userTouch(int x, int y) { if (x < 0 || x >= width || y < 0 || y >= height) return; @@ -248,7 +254,7 @@ public class Board { selectedX = x; selectedY = y; hasSelectedPiece = true; - highlightedSquares = getValidMoves(clicked); // ✅ Highlight legal moves + highlightedSquares = getValidMoves(clicked); } } else { // Check if clicked again on the same square to unselect @@ -260,12 +266,32 @@ public class Board { else if (isHighlighted(x, y)) { Piece selectedPiece = board[selectedX][selectedY]; + // Check if this is an en passant capture + boolean isEnPassant = selectedPiece.getType() == PieceType.Pawn && + x != selectedX && y != selectedY && + board[x][y] == null && + enPassantTarget != null && + x == enPassantTarget[0] && y == enPassantTarget[1]; + // Move piece board[x][y] = selectedPiece; board[selectedX][selectedY] = null; selectedPiece.setX(x); selectedPiece.setY(y); + // If en passant, remove the captured pawn + if (isEnPassant) { + int capturedPawnY = turnWhite ? y - 1 : y + 1; + board[x][capturedPawnY] = null; + } + + // Set en passant target if pawn moved two squares + enPassantTarget = null; + if (selectedPiece.getType() == PieceType.Pawn && + Math.abs(y - selectedY) == 2) { + enPassantTarget = new int[]{x, (selectedY + y) / 2}; + } + // Update turn turnWhite = !turnWhite; turnNumber++; @@ -282,8 +308,6 @@ public class Board { } } - - /* saving-loading feature */ public String[] toFileRep() { return null; @@ -293,7 +317,6 @@ public class Board { // TODO } - /* The following methods require more work */ public boolean isHighlighted(int x, int y) { for (int[] pos : highlightedSquares) { if (pos[0] == x && pos[1] == y) { @@ -308,7 +331,7 @@ public class Board { } public Board(Board board) { - // TODO helloyo + // TODO } public void playMove(Move move) {