From 8077aaafdb8a88f92a089dc90de0e8702e2757b1 Mon Sep 17 00:00:00 2001 From: kske Date: Sun, 28 Jul 2019 13:51:10 +0200 Subject: [PATCH] Implemented en passant --- src/dev/kske/chess/board/Board.java | 15 +++++++++++++++ src/dev/kske/chess/board/Pawn.java | 19 ++++++++++++++++--- src/dev/kske/chess/game/Game.java | 4 ++-- 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/src/dev/kske/chess/board/Board.java b/src/dev/kske/chess/board/Board.java index c57064b..e1d3c2d 100644 --- a/src/dev/kske/chess/board/Board.java +++ b/src/dev/kske/chess/board/Board.java @@ -109,6 +109,11 @@ public class Board implements Cloneable { // TODO: Select promotion setDest(move, new Queen(piece.getColor(), this)); break; + case EN_PASSANT: + setDest(move, piece); + setPos(move, null); + boardArr[move.dest.x][move.dest.y - move.ySign] = null; + break; case CASTLING: // Move the king setDest(move, piece); @@ -160,6 +165,11 @@ public class Board implements Cloneable { setPos(move, new Pawn(getDest(move).getColor(), this)); setDest(move, capturedPiece); break; + case EN_PASSANT: + setPos(move, getDest(move)); + setDest(move, null); + boardArr[move.dest.x][move.dest.y - move.ySign] = new Pawn(getPos(move).getColor().opposite(), this); + break; case CASTLING: // Move the king setPos(move, getDest(move)); @@ -504,4 +514,9 @@ public class Board implements Cloneable { * @return The active color for the next move */ public Color getActiveColor() { return log.getActiveColor(); } + + /** + * @return The current en passant square, or null if there isn't any + */ + public Position getEnPassantSquare() { return log.getLast() == null ? null : log.getLast().enPassant; } } diff --git a/src/dev/kske/chess/board/Pawn.java b/src/dev/kske/chess/board/Pawn.java index 1411e31..596dc38 100644 --- a/src/dev/kske/chess/board/Pawn.java +++ b/src/dev/kske/chess/board/Pawn.java @@ -17,10 +17,10 @@ public class Pawn extends Piece { @Override public boolean isValidMove(Move move) { - // TODO: en passant boolean step = move.isVertical() && move.yDist == 1; boolean doubleStep = move.isVertical() && move.yDist == 2; boolean strafe = move.isDiagonal() && move.xDist == 1; + boolean enPassant = false; if (getColor() == Color.WHITE) doubleStep &= move.pos.y == 6; else doubleStep &= move.pos.y == 1; @@ -28,7 +28,14 @@ public class Pawn extends Piece { if (move.ySign == 1 && move.pos.y == 6 || move.ySign == -1 && move.pos.y == 1) move.type = Move.Type.PAWN_PROMOTION; - return (step ^ doubleStep ^ strafe) && move.ySign == (getColor() == Color.WHITE ? -1 : 1) && isFreePath(move); + // Mark the move as en passant if necessary + if (strafe && move.dest.equals(board.getEnPassantSquare())) { + enPassant = true; + move.type = Move.Type.EN_PASSANT; + } + + return enPassant || (step ^ doubleStep ^ strafe) && move.ySign == (getColor() == Color.WHITE ? -1 : 1) + && isFreePath(move); } @Override @@ -72,10 +79,16 @@ public class Pawn extends Piece { if (isFreePath(move)) moves.add(move); } - // Mark moves as pawn promotions if necessary + // Mark moves as pawn promotion if necessary if (sign == 1 && pos.y == 6 || sign == -1 && pos.y == 1) moves.parallelStream().forEach(m -> m.type = Move.Type.PAWN_PROMOTION); + // Add en passant move if necessary + if (board.getEnPassantSquare() != null) { + Move move = new Move(pos, board.getEnPassantSquare(), Move.Type.EN_PASSANT); + if (move.isDiagonal() && move.xDist == 1) moves.add(move); + } + return moves; } diff --git a/src/dev/kske/chess/game/Game.java b/src/dev/kske/chess/game/Game.java index 8f33977..e7552a1 100644 --- a/src/dev/kske/chess/game/Game.java +++ b/src/dev/kske/chess/game/Game.java @@ -86,7 +86,7 @@ public class Game { } public void reset() { - players.forEach((k, v) -> v.cancelMove()); + players.values().forEach(Player::cancelMove); board.initializeDefaultPositions(); boardComponent.repaint(); overlayComponent.clearDots(); @@ -94,7 +94,7 @@ public class Game { } /** - * Removed all connections between the game and the ui. + * Removed all connections between the game and the UI. */ public void disconnect() { players.values().forEach(Player::disconnect);