en passant rule

This commit is contained in:
2025-04-05 19:20:41 +02:00
parent 2ec7be27ca
commit d94f7d733b
9 changed files with 108 additions and 38 deletions

View File

@@ -25,6 +25,7 @@ public class ChessBoard {
}
private final Cell[][] cells;
private Move lastVirtualMove;
private Move lastMove;
private Piece lastEjectedPiece;
@@ -35,35 +36,38 @@ public class ChessBoard {
this.cells[i][j] = new Cell();
}
}
this.lastVirtualMove = null;
this.lastMove = null;
this.lastEjectedPiece = null;
}
public void applyMove(Move move) {
assert move.isValid() : "Invalid move !";
Piece deadPiece = pieceAt(move.getFinish());
Piece deadPiece = pieceAt(move.getDeadPieceCoords());
if (deadPiece != null) {
this.lastEjectedPiece = deadPiece;
} else {
this.lastEjectedPiece = null;
}
Piece movingPiece = pieceAt(move.getStart());
pieceComes(movingPiece, move.getFinish());
pieceLeaves(move.getDeadPieceCoords());
pieceLeaves(move.getStart());
pieceComes(movingPiece, move.getFinish());
movingPiece.move();
this.lastMove = move;
this.lastVirtualMove = move;
}
public void undoLastMove() {
assert this.lastMove != null: "Can't undo at the beginning!";
assert this.lastVirtualMove != null: "Can't undo at the beginning!";
undoMove(this.lastMove, this.lastEjectedPiece);
undoMove(this.lastVirtualMove, this.lastEjectedPiece);
}
public void undoMove(Move move, Piece deadPiece) {
Piece movingPiece = pieceAt(move.getFinish());
pieceComes(movingPiece, move.getStart());
pieceComes(deadPiece, move.getFinish());
pieceLeaves(move.getFinish());
pieceComes(deadPiece, move.getDeadPieceCoords());
movingPiece.unMove();
}
@@ -177,4 +181,12 @@ public class ChessBoard {
return result;
}
public Move getLastMove() {
return this.lastMove;
}
public void setLastMove(Move lastMove) {
this.lastMove = lastMove;
}
}

View File

@@ -4,6 +4,7 @@ import java.util.EmptyStackException;
import java.util.Stack;
import chess.controller.PlayerCommand;
import chess.controller.commands.MoveCommand;
import chess.model.visitor.PawnIdentifier;
public class Game {
@@ -99,4 +100,14 @@ public class Game {
}
}
public void updateLastMove() {
if (this.movesHistory.isEmpty())
return;
PlayerCommand last = this.movesHistory.getLast();
if (last instanceof MoveCommand move) {
this.board.setLastMove(move.getMove());
}
}
}

View File

@@ -3,10 +3,12 @@ package chess.model;
public class Move {
private final Coordinate start;
private final Coordinate finish;
private Coordinate deadPieceCoords;
public Move(Coordinate start, Coordinate finish) {
this.start = start;
this.finish = finish;
this.deadPieceCoords = finish;
}
public boolean isValid() {
@@ -39,4 +41,16 @@ public class Move {
return 0;
}
public Coordinate getMiddle() {
return Coordinate.fromIndex((getStart().toIndex() + getFinish().toIndex()) / 2);
}
public void setDeadPieceCoords(Coordinate deadCoords) {
this.deadPieceCoords = deadCoords;
}
public Coordinate getDeadPieceCoords() {
return deadPieceCoords;
}
}

View File

@@ -35,31 +35,27 @@ public class PiecePathChecker implements PieceVisitor<Boolean> {
@Override
public Boolean visitPiece(Bishop bishop) {
if (!new PermissiveRuleChecker(this.move).isValidFor(bishop))
return false;
return testPath(bishop.getColor());
return basicCheck(bishop);
}
@Override
public Boolean visitPiece(King king) {
if (!new PermissiveRuleChecker(this.move).isValidFor(king))
return false;
Piece destPiece = board.pieceAt(this.move.getFinish());
if (destPiece == null)
return true;
return destPiece.getColor() != king.getColor();
return destCheck(king);
}
@Override
public Boolean visitPiece(Knight knight) {
if (!new PermissiveRuleChecker(this.move).isValidFor(knight))
return false;
return destCheck(knight);
}
Piece destPiece = board.pieceAt(this.move.getFinish());
if (destPiece == null)
return true;
return destPiece.getColor() != knight.getColor();
@Override
public Boolean visitPiece(Queen queen) {
return basicCheck(queen);
}
@Override
public Boolean visitPiece(Rook rook) {
return basicCheck(rook);
}
@Override
@@ -74,6 +70,9 @@ public class PiecePathChecker implements PieceVisitor<Boolean> {
assert moveDirection == Direction.FrontLeft || moveDirection == Direction.FrontRight;
if (checkEnPassant())
return true;
Piece destPiece = this.board.pieceAt(this.move.getFinish());
if (destPiece == null)
return false;
@@ -81,18 +80,44 @@ public class PiecePathChecker implements PieceVisitor<Boolean> {
return destPiece.getColor() != pawn.getColor();
}
@Override
public Boolean visitPiece(Queen queen) {
if (!new PermissiveRuleChecker(this.move).isValidFor(queen))
private boolean checkEnPassant() {
Move lastMove = this.board.getLastMove();
if (lastMove == null)
return false;
return testPath(queen.getColor());
Piece pieceToEat = this.board.pieceAt(lastMove.getFinish());
if (pieceToEat == null)
return false;
Piece pawn = this.board.pieceAt(this.move.getStart());
if (pieceToEat.getColor() == pawn.getColor())
return false;
if (lastMove.getMiddle().equals(this.move.getFinish())
&& new PawnIdentifier(pieceToEat.getColor()).isPawn(pieceToEat)) {
this.move.setDeadPieceCoords(lastMove.getFinish());
return true;
}
return false;
}
@Override
public Boolean visitPiece(Rook rook) {
if (!new PermissiveRuleChecker(this.move).isValidFor(rook))
private boolean destCheck(Piece piece) {
if (!new PermissiveRuleChecker(this.move).isValidFor(piece))
return false;
return testPath(rook.getColor());
Piece destPiece = board.pieceAt(this.move.getFinish());
if (destPiece == null)
return true;
return destPiece.getColor() != piece.getColor();
}
private boolean basicCheck(Piece piece) {
if (!new PermissiveRuleChecker(this.move).isValidFor(piece))
return false;
return testPath(piece.getColor());
}
private boolean testPath(Color color) {