en-passant

This commit is contained in:
romca 2025-05-19 13:17:43 +02:00
parent e518dc3d3c
commit 2d3b816551
4 changed files with 116 additions and 5 deletions

View File

@ -1 +0,0 @@
/backend/

View File

@ -11,6 +11,8 @@ public class Board {
private boolean isWhiteTurn;
private ArrayList<Piece> pieces;
private Set<Position> highlightedPositions = new HashSet<>();
private Position lastMovedPiecePosition = null;
private boolean lastMoveWasDoublePawnMove = false;
private static class Position {
int x;
int y;
@ -109,8 +111,6 @@ 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() {
@ -179,15 +179,41 @@ 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++;
isWhiteTurn = !isWhiteTurn;
@ -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<Position> validMoves, int x, int y, boolean isWhite) {
@ -596,3 +706,5 @@ public class Board {
}
}