diff --git a/OOP_1A2_Project/bin/.gitignore b/OOP_1A2_Project/bin/.gitignore deleted file mode 100644 index 6d0c385..0000000 --- a/OOP_1A2_Project/bin/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/backend/ diff --git a/OOP_1A2_Project/bin/backend/Board$Position.class b/OOP_1A2_Project/bin/backend/Board$Position.class index 0e1c77c..63e1cab 100644 Binary files a/OOP_1A2_Project/bin/backend/Board$Position.class and b/OOP_1A2_Project/bin/backend/Board$Position.class differ diff --git a/OOP_1A2_Project/bin/backend/Board.class b/OOP_1A2_Project/bin/backend/Board.class index 8baa6a7..15d678c 100644 Binary files a/OOP_1A2_Project/bin/backend/Board.class and b/OOP_1A2_Project/bin/backend/Board.class differ diff --git a/OOP_1A2_Project/src/backend/Board.java b/OOP_1A2_Project/src/backend/Board.java index 0659d99..85a77dd 100644 --- a/OOP_1A2_Project/src/backend/Board.java +++ b/OOP_1A2_Project/src/backend/Board.java @@ -11,6 +11,8 @@ public class Board { private boolean isWhiteTurn; private ArrayList pieces; private Set highlightedPositions = new HashSet<>(); + private Position lastMovedPiecePosition = null; + private boolean lastMoveWasDoublePawnMove = false; private static class Position { int x; int y; @@ -109,9 +111,7 @@ public class Board { pieces.add(new Piece(5, 7, bishop, true)); pieces.add(new Piece(6, 7, knight, true)); pieces.add(new Piece(7, 7, rook, true)); - - - } + } public void cleanBoard() { pieces.clear(); @@ -179,14 +179,40 @@ public class Board { if (selectedPiece != null) { // Check if the destination is a valid move if (isHighlighted(x, y)) { + + // Check if this is an en passant capture + boolean isEnPassant = isEnPassantCapture(selectedPiece, x, y); + // Remove captured piece (if any) Piece toRemove = getPieceAt(x, y); if (toRemove != null) { pieces.remove(toRemove); } + + // Handle en passant capture (remove the captured pawn) + if (isEnPassant) { + int capturedPawnY = selectedPiece.isWhite() ? y + 1 : y - 1; + Piece capturedPawn = getPieceAt(x, capturedPawnY); + if (capturedPawn != null) { + pieces.remove(capturedPawn); + } + } + + // Track if this move is a double pawn move + boolean isDoublePawnMove = selectedPiece.getType() == PieceType.Pawn && + Math.abs(y - selectedPiece.getY()) == 2; // Move piece selectedPiece.moveTo(x, y); + + // Update en passant tracking + if (isDoublePawnMove) { + lastMovedPiecePosition = new Position(x, y); + lastMoveWasDoublePawnMove = true; + } else { + lastMovedPiecePosition = null; + lastMoveWasDoublePawnMove = false; + } // Advance turn turnNumber++; @@ -207,6 +233,31 @@ public class Board { } } + // Add this method to check if a move is an en passant capture: + private boolean isEnPassantCapture(Piece piece, int targetX, int targetY) { + if (piece.getType() != PieceType.Pawn) return false; + if (!lastMoveWasDoublePawnMove) return false; + if (lastMovedPiecePosition == null) return false; + + // Check if we're capturing diagonally to an empty square + if (getPieceAt(targetX, targetY) != null) return false; + + // Check if the target is diagonally adjacent + if (Math.abs(targetX - piece.getX()) != 1) return false; + if (Math.abs(targetY - piece.getY()) != 1) return false; + + // Check if there's an opponent pawn next to us that just moved two squares + int adjacentPawnY = piece.getY(); + Piece adjacentPawn = getPieceAt(targetX, adjacentPawnY); + + if (adjacentPawn == null) return false; + if (adjacentPawn.getType() != PieceType.Pawn) return false; + if (adjacentPawn.isWhite() == piece.isWhite()) return false; + + // Check if this adjacent pawn is the one that just moved two squares + return lastMovedPiecePosition.x == targetX && lastMovedPiecePosition.y == adjacentPawnY; + } + public boolean isSelected(int x, int y) { // Check if the selected coordinates match the given x and y if (selectedX != null && selectedY != null) { @@ -217,7 +268,7 @@ public class Board { /* saving-loading feature :*/ public String[] toFileRep() { - String[] fileRep = new String[height + 1]; + String[] fileRep = new String[height + 2]; String boardStr = toString(); @@ -233,6 +284,13 @@ public class Board { fileRep[height] = (isWhiteTurn ? "W" : "B") + "," + turnNumber; + // Save en passant state + String enPassantInfo = lastMoveWasDoublePawnMove ? "1" : "0"; + if (lastMovedPiecePosition != null) { + enPassantInfo += "," + lastMovedPiecePosition.x + "," + lastMovedPiecePosition.y; + } + fileRep[height + 1] = enPassantInfo; + return fileRep; } @@ -244,6 +302,8 @@ public class Board { if (array == null || array.length < 9) { this.turnNumber = 0; this.isWhiteTurn = true; + this.lastMoveWasDoublePawnMove = false; + this.lastMovedPiecePosition = null; populateBoard(); return; } @@ -291,6 +351,34 @@ public class Board { this.turnNumber = 0; this.isWhiteTurn = true; } + + // Load en passant state + if (array.length > height + 1) { + String enPassantInfo = array[height + 1]; + String[] enPassantData = enPassantInfo.split(","); + + if (enPassantData.length > 0) { + this.lastMoveWasDoublePawnMove = enPassantData[0].trim().equals("1"); + } else { + this.lastMoveWasDoublePawnMove = false; + } + + if (enPassantData.length >= 3) { + try { + int x = Integer.parseInt(enPassantData[1].trim()); + int y = Integer.parseInt(enPassantData[2].trim()); + this.lastMovedPiecePosition = new Position(x, y); + } catch (NumberFormatException e) { + this.lastMovedPiecePosition = null; + } + } else { + this.lastMovedPiecePosition = null; + } + } else { + this.lastMoveWasDoublePawnMove = false; + this.lastMovedPiecePosition = null; + } + } public boolean isHighlighted(int x, int y) { return highlightedPositions.contains(new Position(x, y)); @@ -320,6 +408,10 @@ public class Board { // Copy highlighted positions this.highlightedPositions = new HashSet<>(); this.highlightedPositions.addAll(board.highlightedPositions); + + // Copy en passant state + this.lastMovedPiecePosition = board.lastMovedPiecePosition; + this.lastMoveWasDoublePawnMove = board.lastMoveWasDoublePawnMove; } // Add these methods after userTouch or before isHighlighted @@ -388,11 +480,29 @@ public class Board { if (targetPiece != null && targetPiece.isWhite() != isWhite) { validMoves.add(new Position(newX, newY)); } + // En passant capture + else if (targetPiece == null && canCaptureEnPassant(x, y, newX, newY, isWhite)) { + validMoves.add(new Position(newX, newY)); } } } } + } + // Add this helper method for en passant validation: + private boolean canCaptureEnPassant(int fromX, int fromY, int toX, int toY, boolean isWhite) { + if (!lastMoveWasDoublePawnMove) return false; + if (lastMovedPiecePosition == null) return false; + + // Check if there's an opponent pawn adjacent to us + Piece adjacentPawn = getPieceAt(toX, fromY); + if (adjacentPawn == null) return false; + if (adjacentPawn.getType() != PieceType.Pawn) return false; + if (adjacentPawn.isWhite() == isWhite) return false; + + // Check if this is the pawn that just moved two squares + return lastMovedPiecePosition.x == toX && lastMovedPiecePosition.y == fromY; + } // Add valid rook moves private void addRookMoves(Set validMoves, int x, int y, boolean isWhite) { @@ -596,3 +706,5 @@ public class Board { } } + +