package dev.kske.chess.board; import java.util.Iterator; import java.util.List; import java.util.Objects; /** * Represents a piece on a board with a color.
*
* Project: Chess
* File: Piece.java
* Created: 01.07.2019
* * @since Chess v0.1-alpha * @author Kai S. K. Engelbart */ public abstract class Piece implements Cloneable { private final Color color; protected Board board; /** * Initializes a piece. * * @param color the color of this piece * @param board the board on which this piece is placed */ public Piece(Color color, Board board) { this.color = color; this.board = board; } /** * Generated a list of legal moves this piece can make. * * @param pos the position of this piece * @return a list of legal moves this piece can make */ public List getMoves(Position pos) { List moves = getPseudolegalMoves(pos); for (Iterator iterator = moves.iterator(); iterator.hasNext();) { Move move = iterator.next(); board.move(move); if (board.checkCheck(getColor())) iterator.remove(); board.revert(); } return moves; } /** * Generates a list of pseudo legal moves this piece can make. * * @param pos the position of this piece * @return a list of pseudo legal moves this piece can make */ protected abstract List getPseudolegalMoves(Position pos); /** * Checks, if a given move is valid. * * @param move the move to check * @return {@code true} if the move is valid */ public abstract boolean isValidMove(Move move); /** * Checks, if the squares between the position and the destination of a move * are * free. * * @param move The move to check * @return {@true} if the path is free */ protected boolean isFreePath(Move move) { for ( int i = move.getPos().x + move.getxSign(), j = move.getPos().y + move.getySign(); i != move.getDest().x || j != move.getDest().y; i += move.getxSign(), j += move.getySign() ) if (board.getBoardArr()[i][j] != null) return false; return checkDestination(move); } /** * Checks if the destination of a move is empty or a piece from the opposing * team * * @param move The move to check * @return {@code false} if the move's destination is from the same team */ protected final boolean checkDestination(Move move) { return board.getDest(move) == null || board.getDest(move).getColor() != getColor(); } @Override public Object clone() { Piece piece = null; try { piece = (Piece) super.clone(); } catch (CloneNotSupportedException ex) { ex.printStackTrace(); } return piece; } @Override public String toString() { return String.format("%s[color=%s]", getClass().getSimpleName(), color); } @Override public int hashCode() { return Objects.hash(color); } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Piece other = (Piece) obj; return color == other.color; } /** * @return the standard value of this {@link Piece} that can be used for * board * evaluation */ public abstract int getValue(); /** * @return The first character of this {@link Piece} in algebraic notation * and * lower case */ public char firstChar() { return Character.toLowerCase(getClass().getSimpleName().charAt(0)); } /** * @param firstChar the first character of a piece's name * @return the class of the piece associated with that character or * {@code null} * if no piece is associated with the given character */ public static Class fromFirstChar(char firstChar) { switch (Character.toLowerCase(firstChar)) { case 'k': return King.class; case 'q': return Queen.class; case 'r': return Rook.class; case 'n': return Knight.class; case 'b': return Bishop.class; case 'p': return Pawn.class; default: return null; } } /** * @return the {@link Color} of this {@link Piece} */ public Color getColor() { return color; } /** * Project: Chess
* File: Piece.java
* Created: 01.07.2019
* * @author Kai S. K. Engelbart * @since Chess v0.1-alpha */ public enum Color { /** * Represents the color of the white pieces on a board. */ WHITE, /** * Represents the color of the black pieces on a board. */ BLACK; /** * @param c the first character of a color's name * @return {@code WHITE} if the character is {@code w} or {@code W}, * else * {@code BLACK} */ public static Color fromFirstChar(char c) { return Character.toLowerCase(c) == 'w' ? WHITE : BLACK; } /** * @return the first character (lower case) of this color */ public char firstChar() { return this == WHITE ? 'w' : 'b'; } /** * @return the opposite of this color */ public Color opposite() { return this == WHITE ? BLACK : WHITE; } } }