package dev.kske.chess.board; import java.util.ArrayList; import java.util.List; /** * Project: Chess
* File: Pawn.java
* Created: 01.07.2019
* Author: Kai S. K. Engelbart */ public class Pawn extends Piece { public Pawn(Color color, Board board) { super(color, board); } @Override public boolean isValidMove(Move move) { 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; // Mark move as pawn promotion if necessary if (move.ySign == 1 && move.pos.y == 6 || move.ySign == -1 && move.pos.y == 1) move.type = Move.Type.PAWN_PROMOTION; // 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 protected boolean isFreePath(Move move) { // Two steps forward if (move.yDist == 2) return board.getBoardArr()[move.pos.x][move.dest.y - move.ySign] == null && board.getDest(move) == null; // One step forward else if (move.xDist == 0) return board.getDest(move) == null; // Capture move else return board.getDest(move) != null && board.getDest(move).getColor() != getColor(); } @Override protected List getPseudolegalMoves(Position pos) { List moves = new ArrayList<>(); int sign = getColor() == Color.WHITE ? -1 : 1; // Strafe left if (pos.x > 0) { Move move = new Move(pos, new Position(pos.x - 1, pos.y + sign)); if (isFreePath(move)) moves.add(move); } // Strafe right if (pos.x < 7) { Move move = new Move(pos, new Position(pos.x + 1, pos.y + sign)); if (isFreePath(move)) moves.add(move); } // Step forward if (sign == 1 && pos.y < 7 || sign == -1 && pos.y > 0) { Move move = new Move(pos, new Position(pos.x, pos.y + sign)); if (isFreePath(move)) moves.add(move); } // Double step forward if (sign == 1 && pos.y == 1 || sign == -1 && pos.y == 6) { Move move = new Move(pos, new Position(pos.x, pos.y + 2 * sign)); if (isFreePath(move)) moves.add(move); } // 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; } @Override public Type getType() { return Type.PAWN; } }