En passant

This commit is contained in:
clement 2025-05-19 18:01:03 +02:00
parent d1b1bdcd19
commit cdbba67bc5
2 changed files with 119 additions and 30 deletions

View File

@ -18,15 +18,18 @@ public class Board {
private Stack<Move> moveHistory = new Stack<>();
// EN PASSANT
private Integer enPassantX = null;
private Integer enPassantY = null;
public Board(int colNum, int lineNum) {
this.width = colNum;
this.height = lineNum;
this.pieces = new ArrayList<>();
this.enPassantX = null;
this.enPassantY = null;
}
/**
* Constructeur de copie : clone l'état du plateau
*/
public Board(Board other) {
this.width = other.width;
this.height = other.height;
@ -42,6 +45,8 @@ public class Board {
this.highlightedPositions = new ArrayList<>(other.highlightedPositions);
this.moveHistory = new Stack<>();
this.moveHistory.addAll(other.moveHistory);
this.enPassantX = other.enPassantX;
this.enPassantY = other.enPassantY;
}
public Board(String[] array) {
@ -59,6 +64,8 @@ public class Board {
}
}
turnIsWhite = array[8].equalsIgnoreCase("W");
this.enPassantX = null;
this.enPassantY = null;
}
public int getWidth() { return width; }
@ -66,6 +73,8 @@ public class Board {
public int getTurnNumber() { return turnNumber; }
public boolean isTurnWhite() { return turnIsWhite; }
public boolean isGameOver() { return gameOver; }
public Integer getEnPassantX() { return enPassantX; }
public Integer getEnPassantY() { return enPassantY; }
public void setPiece(boolean isWhite, PieceType type, int x, int y) {
pieces.removeIf(p -> p.getX() == x && p.getY() == y);
@ -93,6 +102,8 @@ public class Board {
setPiece(false, PieceType.Knight, 6, 0);
setPiece(false, PieceType.Rook, 7, 0);
for (int x = 0; x < 8; x++) setPiece(false, PieceType.Pawn, x, 1);
this.enPassantX = null;
this.enPassantY = null;
}
public void cleanBoard() {
@ -102,6 +113,8 @@ public class Board {
highlightedPositions.clear();
moveHistory.clear();
gameOver = false;
enPassantX = null;
enPassantY = null;
}
public ArrayList<Piece> getPieces() { return pieces; }
@ -130,34 +143,59 @@ public class Board {
simulation.pieces.removeIf(p -> p.getX() == selectedX && p.getY() == selectedY);
simulation.pieces.removeIf(p -> p.getX() == x && p.getY() == y);
simulation.pieces.add(new Piece(
selectedPiece.isWhite(),
selectedPiece.getType(),
x, y
selectedPiece.isWhite(),
selectedPiece.getType(),
x, y
));
if (!simulation.isKingInCheck(turnIsWhite)) {
Piece target = getPieceAt(x, y);
// EN PASSANT (avant la capture normale)
boolean enPassantMove = false;
if (selectedPiece.getType() == PieceType.Pawn
&& getEnPassantX() != null && getEnPassantY() != null
&& x == getEnPassantX() && y == getEnPassantY()
&& target == null
&& selectedX != x) {
// On va prendre en passant
enPassantMove = true;
int capturedY = turnIsWhite ? y + 1 : y - 1;
pieces.removeIf(p -> p.getX() == x && p.getY() == capturedY);
target = getPieceAt(x, capturedY); // Pour le move history
}
// Si on cible le roi adverse, c'est un cas de mat -> terminer la partie
if (target != null && target.getType() == PieceType.King) {
gameOver = true;
// On ne modifie pas le plateau (le roi n'est pas capturé)
return;
}
// Sinon capturer la pièce normale
if (target != null) {
// Capture normale
if (!enPassantMove && target != null) {
pieces.removeIf(p -> p.getX() == x && p.getY() == y);
}
// Déplacer la pièce sélectionnée
pieces.removeIf(p -> p.getX() == selectedX && p.getY() == selectedY);
pieces.add(new Piece(
selectedPiece.isWhite(),
selectedPiece.getType(),
x, y
selectedPiece.isWhite(),
selectedPiece.getType(),
x, y
));
// Historique
Move move = new Move(selectedPiece, selectedX, selectedY, x, y, target);
// EN PASSANT : Maj de la case en passant
if (selectedPiece.getType() == PieceType.Pawn && Math.abs(y - selectedY) == 2) {
enPassantX = x;
enPassantY = (y + selectedY) / 2; // Case traversée
} else {
enPassantX = null;
enPassantY = null;
}
// Move history (on précise enPassant ou non)
Move move = new Move(selectedPiece, selectedX, selectedY, x, y, target,
enPassantMove);
moveHistory.push(move);
// Changer de tour
@ -183,9 +221,9 @@ public class Board {
Move lastMove = moveHistory.pop();
pieces.removeIf(p -> p.getX() == lastMove.getToX() && p.getY() == lastMove.getToY());
pieces.add(new Piece(
lastMove.getMovedPiece().isWhite(),
lastMove.getMovedPiece().getType(),
lastMove.getFromX(), lastMove.getFromY()
lastMove.getMovedPiece().isWhite(),
lastMove.getMovedPiece().getType(),
lastMove.getFromX(), lastMove.getFromY()
));
if (lastMove.getCapturedPiece() != null) {
pieces.add(lastMove.getCapturedPiece());
@ -196,13 +234,11 @@ public class Board {
selectedY = null;
highlightedPositions.clear();
gameOver = false;
enPassantX = null;
enPassantY = null;
}
}
/**
* Détermine si le joueur forWhite est en échec et mat.
* @param forWhite couleur du joueur
*/
public boolean isCheckmate(boolean forWhite) {
if (!isKingInCheck(forWhite)) return false;
for (Piece piece : pieces) {
@ -223,14 +259,12 @@ public class Board {
return true;
}
/**
* Vérifie si le roi de couleur isWhite est en échec.
*/
public boolean isKingInCheck(boolean isWhite) {
Piece king = null;
for (Piece p : pieces) {
if (p.getType() == PieceType.King && p.isWhite() == isWhite) {
king = p; break;
king = p;
break;
}
}
if (king == null) return true; // pas de roi => considérer comme échec
@ -280,15 +314,33 @@ public class Board {
moves.add(new int[]{x, twoStepY});
}
}
// Capture à gauche
if (inBounds(x - 1, oneStepY)) {
Piece left = getPieceAt(x - 1, oneStepY);
if (left != null && left.isWhite() != isWhite)
moves.add(new int[]{x - 1, oneStepY});
// EN PASSANT GAUCHE
if (getEnPassantX() != null && getEnPassantY() != null &&
x - 1 == getEnPassantX() && oneStepY == getEnPassantY() &&
getPieceAt(x - 1, y) != null &&
getPieceAt(x - 1, y).getType() == PieceType.Pawn &&
getPieceAt(x - 1, y).isWhite() != isWhite) {
moves.add(new int[]{x - 1, oneStepY});
}
}
// Capture à droite
if (inBounds(x + 1, oneStepY)) {
Piece right = getPieceAt(x + 1, oneStepY);
if (right != null && right.isWhite() != isWhite)
moves.add(new int[]{x + 1, oneStepY});
// EN PASSANT DROITE
if (getEnPassantX() != null && getEnPassantY() != null &&
x + 1 == getEnPassantX() && oneStepY == getEnPassantY() &&
getPieceAt(x + 1, y) != null &&
getPieceAt(x + 1, y).getType() == PieceType.Pawn &&
getPieceAt(x + 1, y).isWhite() != isWhite) {
moves.add(new int[]{x + 1, oneStepY});
}
}
break;
case Rook:
@ -407,22 +459,38 @@ public class Board {
public void playMove(Move move) {
if (move == null || gameOver) return;
Piece captured = getPieceAt(move.getToX(), move.getToY());
// EN PASSANT (avant la capture normale)
if (move.getMovedPiece().getType() == PieceType.Pawn
&& move.isEnPassant()) {
int capturedY = move.getMovedPiece().isWhite() ? move.getToY() + 1 : move.getToY() - 1;
pieces.removeIf(p -> p.getX() == move.getToX() && p.getY() == capturedY);
}
// Si tentative de capturer le roi, fin de partie
if (captured != null && captured.getType() == PieceType.King) {
gameOver = true;
return;
}
// Capture normale
if (captured != null) {
if (!(move.getMovedPiece().getType() == PieceType.Pawn && move.isEnPassant()) && captured != null) {
pieces.removeIf(p -> p.getX() == move.getToX() && p.getY() == move.getToY());
}
// Déplacement
pieces.removeIf(p -> p.getX() == move.getFromX() && p.getY() == move.getFromY());
pieces.add(new Piece(
move.getMovedPiece().isWhite(),
move.getMovedPiece().getType(),
move.getToX(), move.getToY()
move.getMovedPiece().isWhite(),
move.getMovedPiece().getType(),
move.getToX(), move.getToY()
));
// EN PASSANT : Maj de la case en passant
if (move.getMovedPiece().getType() == PieceType.Pawn && Math.abs(move.getToY() - move.getFromY()) == 2) {
enPassantX = move.getToX();
enPassantY = (move.getToY() + move.getFromY()) / 2;
} else {
enPassantX = null;
enPassantY = null;
}
moveHistory.push(move);
turnNumber++;
turnIsWhite = !turnIsWhite;
@ -430,7 +498,6 @@ public class Board {
selectedY = null;
highlightedPositions.clear();
// Vérifier échec et mat
if (isCheckmate(turnIsWhite)) {
gameOver = true;
}

View File

@ -6,6 +6,9 @@ public class Move {
private int toX, toY;
private Piece capturedPiece;
private boolean isEnPassant = false;
public Move(Piece movedPiece, int fromX, int fromY, int toX, int toY, Piece capturedPiece) {
this.movedPiece = movedPiece;
this.fromX = fromX;
@ -15,6 +18,16 @@ public class Move {
this.capturedPiece = capturedPiece;
}
public Move(Piece movedPiece, int fromX, int fromY, int toX, int toY, Piece capturedPiece, boolean isEnPassant) {
this.movedPiece = movedPiece;
this.fromX = fromX;
this.fromY = fromY;
this.toX = toX;
this.toY = toY;
this.capturedPiece = capturedPiece;
this.isEnPassant = isEnPassant;
}
public Piece getMovedPiece() {
return movedPiece;
}
@ -38,4 +51,13 @@ public class Move {
public Piece getCapturedPiece() {
return capturedPiece;
}
public boolean isEnPassant() {
return isEnPassant;
}
public void setEnPassant(boolean enPassant) {
this.isEnPassant = enPassant;
}
}