This repository has been archived on 2021-02-18. You can view files and clone it, but cannot push or open issues or pull requests.
chess/src/main/java/dev/kske/chess/board/Piece.java

224 lines
5.2 KiB
Java

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.<br>
* <br>
* Project: <strong>Chess</strong><br>
* File: <strong>Piece.java</strong><br>
* Created: <strong>01.07.2019</strong><br>
*
* @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<Move> getMoves(Position pos) {
List<Move> moves = getPseudolegalMoves(pos);
for (Iterator<Move> 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<Move> 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<? extends Piece> 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: <strong>Chess</strong><br>
* File: <strong>Piece.java</strong><br>
* Created: <strong>01.07.2019</strong><br>
*
* @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;
}
}
}