En passant
This commit is contained in:
parent
d1b1bdcd19
commit
cdbba67bc5
|
|
@ -18,15 +18,18 @@ public class Board {
|
||||||
|
|
||||||
private Stack<Move> moveHistory = new Stack<>();
|
private Stack<Move> moveHistory = new Stack<>();
|
||||||
|
|
||||||
|
// EN PASSANT
|
||||||
|
private Integer enPassantX = null;
|
||||||
|
private Integer enPassantY = null;
|
||||||
|
|
||||||
public Board(int colNum, int lineNum) {
|
public Board(int colNum, int lineNum) {
|
||||||
this.width = colNum;
|
this.width = colNum;
|
||||||
this.height = lineNum;
|
this.height = lineNum;
|
||||||
this.pieces = new ArrayList<>();
|
this.pieces = new ArrayList<>();
|
||||||
|
this.enPassantX = null;
|
||||||
|
this.enPassantY = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructeur de copie : clone l'état du plateau
|
|
||||||
*/
|
|
||||||
public Board(Board other) {
|
public Board(Board other) {
|
||||||
this.width = other.width;
|
this.width = other.width;
|
||||||
this.height = other.height;
|
this.height = other.height;
|
||||||
|
|
@ -42,6 +45,8 @@ public class Board {
|
||||||
this.highlightedPositions = new ArrayList<>(other.highlightedPositions);
|
this.highlightedPositions = new ArrayList<>(other.highlightedPositions);
|
||||||
this.moveHistory = new Stack<>();
|
this.moveHistory = new Stack<>();
|
||||||
this.moveHistory.addAll(other.moveHistory);
|
this.moveHistory.addAll(other.moveHistory);
|
||||||
|
this.enPassantX = other.enPassantX;
|
||||||
|
this.enPassantY = other.enPassantY;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Board(String[] array) {
|
public Board(String[] array) {
|
||||||
|
|
@ -59,6 +64,8 @@ public class Board {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
turnIsWhite = array[8].equalsIgnoreCase("W");
|
turnIsWhite = array[8].equalsIgnoreCase("W");
|
||||||
|
this.enPassantX = null;
|
||||||
|
this.enPassantY = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getWidth() { return width; }
|
public int getWidth() { return width; }
|
||||||
|
|
@ -66,6 +73,8 @@ public class Board {
|
||||||
public int getTurnNumber() { return turnNumber; }
|
public int getTurnNumber() { return turnNumber; }
|
||||||
public boolean isTurnWhite() { return turnIsWhite; }
|
public boolean isTurnWhite() { return turnIsWhite; }
|
||||||
public boolean isGameOver() { return gameOver; }
|
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) {
|
public void setPiece(boolean isWhite, PieceType type, int x, int y) {
|
||||||
pieces.removeIf(p -> p.getX() == x && p.getY() == 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.Knight, 6, 0);
|
||||||
setPiece(false, PieceType.Rook, 7, 0);
|
setPiece(false, PieceType.Rook, 7, 0);
|
||||||
for (int x = 0; x < 8; x++) setPiece(false, PieceType.Pawn, x, 1);
|
for (int x = 0; x < 8; x++) setPiece(false, PieceType.Pawn, x, 1);
|
||||||
|
this.enPassantX = null;
|
||||||
|
this.enPassantY = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cleanBoard() {
|
public void cleanBoard() {
|
||||||
|
|
@ -102,6 +113,8 @@ public class Board {
|
||||||
highlightedPositions.clear();
|
highlightedPositions.clear();
|
||||||
moveHistory.clear();
|
moveHistory.clear();
|
||||||
gameOver = false;
|
gameOver = false;
|
||||||
|
enPassantX = null;
|
||||||
|
enPassantY = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArrayList<Piece> getPieces() { return pieces; }
|
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() == selectedX && p.getY() == selectedY);
|
||||||
simulation.pieces.removeIf(p -> p.getX() == x && p.getY() == y);
|
simulation.pieces.removeIf(p -> p.getX() == x && p.getY() == y);
|
||||||
simulation.pieces.add(new Piece(
|
simulation.pieces.add(new Piece(
|
||||||
selectedPiece.isWhite(),
|
selectedPiece.isWhite(),
|
||||||
selectedPiece.getType(),
|
selectedPiece.getType(),
|
||||||
x, y
|
x, y
|
||||||
));
|
));
|
||||||
|
|
||||||
if (!simulation.isKingInCheck(turnIsWhite)) {
|
if (!simulation.isKingInCheck(turnIsWhite)) {
|
||||||
Piece target = getPieceAt(x, y);
|
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
|
// Si on cible le roi adverse, c'est un cas de mat -> terminer la partie
|
||||||
if (target != null && target.getType() == PieceType.King) {
|
if (target != null && target.getType() == PieceType.King) {
|
||||||
gameOver = true;
|
gameOver = true;
|
||||||
// On ne modifie pas le plateau (le roi n'est pas capturé)
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sinon capturer la pièce normale
|
// Capture normale
|
||||||
if (target != null) {
|
if (!enPassantMove && target != null) {
|
||||||
pieces.removeIf(p -> p.getX() == x && p.getY() == y);
|
pieces.removeIf(p -> p.getX() == x && p.getY() == y);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Déplacer la pièce sélectionnée
|
// Déplacer la pièce sélectionnée
|
||||||
pieces.removeIf(p -> p.getX() == selectedX && p.getY() == selectedY);
|
pieces.removeIf(p -> p.getX() == selectedX && p.getY() == selectedY);
|
||||||
pieces.add(new Piece(
|
pieces.add(new Piece(
|
||||||
selectedPiece.isWhite(),
|
selectedPiece.isWhite(),
|
||||||
selectedPiece.getType(),
|
selectedPiece.getType(),
|
||||||
x, y
|
x, y
|
||||||
));
|
));
|
||||||
|
|
||||||
// Historique
|
// EN PASSANT : Maj de la case en passant
|
||||||
Move move = new Move(selectedPiece, selectedX, selectedY, x, y, target);
|
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);
|
moveHistory.push(move);
|
||||||
|
|
||||||
// Changer de tour
|
// Changer de tour
|
||||||
|
|
@ -183,9 +221,9 @@ public class Board {
|
||||||
Move lastMove = moveHistory.pop();
|
Move lastMove = moveHistory.pop();
|
||||||
pieces.removeIf(p -> p.getX() == lastMove.getToX() && p.getY() == lastMove.getToY());
|
pieces.removeIf(p -> p.getX() == lastMove.getToX() && p.getY() == lastMove.getToY());
|
||||||
pieces.add(new Piece(
|
pieces.add(new Piece(
|
||||||
lastMove.getMovedPiece().isWhite(),
|
lastMove.getMovedPiece().isWhite(),
|
||||||
lastMove.getMovedPiece().getType(),
|
lastMove.getMovedPiece().getType(),
|
||||||
lastMove.getFromX(), lastMove.getFromY()
|
lastMove.getFromX(), lastMove.getFromY()
|
||||||
));
|
));
|
||||||
if (lastMove.getCapturedPiece() != null) {
|
if (lastMove.getCapturedPiece() != null) {
|
||||||
pieces.add(lastMove.getCapturedPiece());
|
pieces.add(lastMove.getCapturedPiece());
|
||||||
|
|
@ -196,13 +234,11 @@ public class Board {
|
||||||
selectedY = null;
|
selectedY = null;
|
||||||
highlightedPositions.clear();
|
highlightedPositions.clear();
|
||||||
gameOver = false;
|
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) {
|
public boolean isCheckmate(boolean forWhite) {
|
||||||
if (!isKingInCheck(forWhite)) return false;
|
if (!isKingInCheck(forWhite)) return false;
|
||||||
for (Piece piece : pieces) {
|
for (Piece piece : pieces) {
|
||||||
|
|
@ -223,14 +259,12 @@ public class Board {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Vérifie si le roi de couleur isWhite est en échec.
|
|
||||||
*/
|
|
||||||
public boolean isKingInCheck(boolean isWhite) {
|
public boolean isKingInCheck(boolean isWhite) {
|
||||||
Piece king = null;
|
Piece king = null;
|
||||||
for (Piece p : pieces) {
|
for (Piece p : pieces) {
|
||||||
if (p.getType() == PieceType.King && p.isWhite() == isWhite) {
|
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
|
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});
|
moves.add(new int[]{x, twoStepY});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Capture à gauche
|
||||||
if (inBounds(x - 1, oneStepY)) {
|
if (inBounds(x - 1, oneStepY)) {
|
||||||
Piece left = getPieceAt(x - 1, oneStepY);
|
Piece left = getPieceAt(x - 1, oneStepY);
|
||||||
if (left != null && left.isWhite() != isWhite)
|
if (left != null && left.isWhite() != isWhite)
|
||||||
moves.add(new int[]{x - 1, oneStepY});
|
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)) {
|
if (inBounds(x + 1, oneStepY)) {
|
||||||
Piece right = getPieceAt(x + 1, oneStepY);
|
Piece right = getPieceAt(x + 1, oneStepY);
|
||||||
if (right != null && right.isWhite() != isWhite)
|
if (right != null && right.isWhite() != isWhite)
|
||||||
moves.add(new int[]{x + 1, oneStepY});
|
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;
|
break;
|
||||||
case Rook:
|
case Rook:
|
||||||
|
|
@ -407,22 +459,38 @@ public class Board {
|
||||||
public void playMove(Move move) {
|
public void playMove(Move move) {
|
||||||
if (move == null || gameOver) return;
|
if (move == null || gameOver) return;
|
||||||
Piece captured = getPieceAt(move.getToX(), move.getToY());
|
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
|
// Si tentative de capturer le roi, fin de partie
|
||||||
if (captured != null && captured.getType() == PieceType.King) {
|
if (captured != null && captured.getType() == PieceType.King) {
|
||||||
gameOver = true;
|
gameOver = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Capture normale
|
// 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());
|
pieces.removeIf(p -> p.getX() == move.getToX() && p.getY() == move.getToY());
|
||||||
}
|
}
|
||||||
// Déplacement
|
// Déplacement
|
||||||
pieces.removeIf(p -> p.getX() == move.getFromX() && p.getY() == move.getFromY());
|
pieces.removeIf(p -> p.getX() == move.getFromX() && p.getY() == move.getFromY());
|
||||||
pieces.add(new Piece(
|
pieces.add(new Piece(
|
||||||
move.getMovedPiece().isWhite(),
|
move.getMovedPiece().isWhite(),
|
||||||
move.getMovedPiece().getType(),
|
move.getMovedPiece().getType(),
|
||||||
move.getToX(), move.getToY()
|
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);
|
moveHistory.push(move);
|
||||||
turnNumber++;
|
turnNumber++;
|
||||||
turnIsWhite = !turnIsWhite;
|
turnIsWhite = !turnIsWhite;
|
||||||
|
|
@ -430,7 +498,6 @@ public class Board {
|
||||||
selectedY = null;
|
selectedY = null;
|
||||||
highlightedPositions.clear();
|
highlightedPositions.clear();
|
||||||
|
|
||||||
// Vérifier échec et mat
|
|
||||||
if (isCheckmate(turnIsWhite)) {
|
if (isCheckmate(turnIsWhite)) {
|
||||||
gameOver = true;
|
gameOver = true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,9 @@ public class Move {
|
||||||
private int toX, toY;
|
private int toX, toY;
|
||||||
private Piece capturedPiece;
|
private Piece capturedPiece;
|
||||||
|
|
||||||
|
|
||||||
|
private boolean isEnPassant = false;
|
||||||
|
|
||||||
public Move(Piece movedPiece, int fromX, int fromY, int toX, int toY, Piece capturedPiece) {
|
public Move(Piece movedPiece, int fromX, int fromY, int toX, int toY, Piece capturedPiece) {
|
||||||
this.movedPiece = movedPiece;
|
this.movedPiece = movedPiece;
|
||||||
this.fromX = fromX;
|
this.fromX = fromX;
|
||||||
|
|
@ -15,6 +18,16 @@ public class Move {
|
||||||
this.capturedPiece = capturedPiece;
|
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() {
|
public Piece getMovedPiece() {
|
||||||
return movedPiece;
|
return movedPiece;
|
||||||
}
|
}
|
||||||
|
|
@ -38,4 +51,13 @@ public class Move {
|
||||||
public Piece getCapturedPiece() {
|
public Piece getCapturedPiece() {
|
||||||
return capturedPiece;
|
return capturedPiece;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public boolean isEnPassant() {
|
||||||
|
return isEnPassant;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnPassant(boolean enPassant) {
|
||||||
|
this.isEnPassant = enPassant;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue