Removed Type enumeration from Piece class
This commit is contained in:
parent
2821f30dbe
commit
17677e6858
@ -65,5 +65,5 @@ public class Bishop extends Piece {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getType() { return Type.BISHOP; }
|
||||
public int getValue() { return 30; }
|
||||
}
|
||||
|
@ -10,7 +10,6 @@ import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import dev.kske.chess.board.Piece.Color;
|
||||
import dev.kske.chess.board.Piece.Type;
|
||||
|
||||
/**
|
||||
* Project: <strong>Chess</strong><br>
|
||||
@ -87,7 +86,7 @@ public class Board {
|
||||
move.execute(this);
|
||||
|
||||
// Update the king's position if the moved piece is the king
|
||||
if (piece.getType() == Type.KING) kingPos.put(piece.getColor(), move.getDest());
|
||||
if (piece instanceof King) kingPos.put(piece.getColor(), move.getDest());
|
||||
|
||||
// Update log
|
||||
log.add(move, piece, capturePiece);
|
||||
@ -118,29 +117,30 @@ public class Board {
|
||||
dest = Position.fromLAN(m.group("toSquare"));
|
||||
if (m.group("fromSquare") != null) pos = Position.fromLAN(m.group("fromSquare"));
|
||||
else {
|
||||
Type type = Type.fromFirstChar(m.group("pieceType").charAt(0));
|
||||
Class<? extends Piece> pieceClass = Piece.fromFirstChar(m.group("pieceType").charAt(0));
|
||||
char file;
|
||||
int rank;
|
||||
if (m.group("fromFile") != null) {
|
||||
file = m.group("fromFile").charAt(0);
|
||||
rank = get(type, file);
|
||||
rank = get(pieceClass, file);
|
||||
pos = Position.fromLAN(String.format("%c%d", file, rank));
|
||||
} else if (m.group("fromRank") != null) {
|
||||
rank = Integer.parseInt(m.group("fromRank").substring(0, 1));
|
||||
file = get(type, rank);
|
||||
file = get(pieceClass, rank);
|
||||
pos = Position.fromLAN(String.format("%c%d", file, rank));
|
||||
} else pos = get(type, dest);
|
||||
} else pos = get(pieceClass, dest);
|
||||
}
|
||||
move = new Move(pos, dest);
|
||||
break;
|
||||
case "pawnCapture":
|
||||
dest = Position.fromLAN(m.group("toSquare"));
|
||||
char file = m.group("fromFile").charAt(0);
|
||||
int rank = m.group("fromRank") == null ? get(Type.PAWN, file) : Integer.parseInt(m.group("fromRank"));
|
||||
int rank = m.group("fromRank") == null ? get(Pawn.class, file) : Integer.parseInt(m.group("fromRank"));
|
||||
pos = Position.fromLAN(String.format("%c%d", file, rank));
|
||||
if (m.group("promotedTo") != null) {
|
||||
|
||||
}
|
||||
move = new Move(pos, dest);
|
||||
break;
|
||||
case "pawnPush":
|
||||
dest = Position.fromLAN(m.group("toSquare"));
|
||||
@ -151,6 +151,7 @@ public class Board {
|
||||
if (boardArr[dest.x][dest.y + step] != null) pos = new Position(dest.x, dest.y + step);
|
||||
// Double step forward
|
||||
else pos = new Position(dest.x, dest.y + 2 * step);
|
||||
move = new Move(pos, dest);
|
||||
break;
|
||||
case "castling":
|
||||
pos = new Position(4, log.getActiveColor() == Color.WHITE ? 7 : 0);
|
||||
@ -175,7 +176,7 @@ public class Board {
|
||||
move.revert(this, moveNode.capturedPiece);
|
||||
|
||||
// Update the king's position if the moved piece is the king
|
||||
if (getPos(move).getType() == Type.KING) kingPos.put(getPos(move).getColor(), move.getPos());
|
||||
if (getPos(move) instanceof King) kingPos.put(getPos(move).getColor(), move.getPos());
|
||||
|
||||
// Update log
|
||||
log.removeLast();
|
||||
@ -322,30 +323,30 @@ public class Board {
|
||||
/**
|
||||
* Searches for a {@link Piece} inside a file (A - H).
|
||||
*
|
||||
* @param type The {@link Type} of the piece to search for
|
||||
* @param pieceClass The class of the piece to search for
|
||||
* @param file The file in which to search for the piece
|
||||
* @return The rank (1 - 8) of the first piece with the specified type and
|
||||
* current color in the file, or {@code -1} if there isn't any
|
||||
*/
|
||||
public int get(Type type, char file) {
|
||||
public int get(Class<? extends Piece> pieceClass, char file) {
|
||||
int x = file - 97;
|
||||
for (int i = 0; i < 8; i++)
|
||||
if (boardArr[x][i] != null && boardArr[x][i].getType() == type && boardArr[x][i].getColor() == log.getActiveColor()) return 8 - i;
|
||||
if (boardArr[x][i] != null && boardArr[x][i].getClass() == pieceClass && boardArr[x][i].getColor() == log.getActiveColor()) return 8 - i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for a {@link Piece} inside a rank (1 - 8).
|
||||
*
|
||||
* @param type The {@link Type} of the piece to search for
|
||||
* @param pieceClass The class of the piece to search for
|
||||
* @param rank The rank in which to search for the piece
|
||||
* @return The file (A - H) of the first piece with the specified type and
|
||||
* current color in the file, or {@code -} if there isn't any
|
||||
*/
|
||||
public char get(Type type, int rank) {
|
||||
public char get(Class<? extends Piece> pieceClass, int rank) {
|
||||
int y = rank - 1;
|
||||
for (int i = 0; i < 8; i++)
|
||||
if (boardArr[i][y] != null && boardArr[i][y].getType() == type && boardArr[i][y].getColor() == log.getActiveColor())
|
||||
if (boardArr[i][y] != null && boardArr[i][y].getClass() == pieceClass && boardArr[i][y].getColor() == log.getActiveColor())
|
||||
return (char) (i + 97);
|
||||
return '-';
|
||||
}
|
||||
@ -353,14 +354,14 @@ public class Board {
|
||||
/**
|
||||
* Searches for a {@link Piece} that can move to a {@link Position}.
|
||||
*
|
||||
* @param type The {@link Type} of the piece to search for
|
||||
* @param pieceClass The class of the piece to search for
|
||||
* @param dest The destination that the piece is required to reach
|
||||
* @return The position of a piece that can move to the specified destination
|
||||
*/
|
||||
public Position get(Type type, Position dest) {
|
||||
public Position get(Class<? extends Piece> pieceClass, Position dest) {
|
||||
for (int i = 0; i < 8; i++)
|
||||
for (int j = 0; j < 8; j++)
|
||||
if (boardArr[i][j] != null && boardArr[i][j].getType() == type && boardArr[i][j].getColor() == log.getActiveColor()) {
|
||||
if (boardArr[i][j] != null && boardArr[i][j].getClass() == pieceClass && boardArr[i][j].getColor() == log.getActiveColor()) {
|
||||
Position pos = new Position(i, j);
|
||||
if (boardArr[i][j].isValidMove(new Move(pos, dest))) return pos;
|
||||
}
|
||||
|
@ -164,7 +164,7 @@ public class FENString {
|
||||
}
|
||||
|
||||
// Write piece character
|
||||
char p = piece.getType().firstChar();
|
||||
char p = piece.firstChar();
|
||||
sb.append(piece.getColor() == Color.WHITE ? Character.toUpperCase(p) : p);
|
||||
}
|
||||
}
|
||||
|
@ -63,10 +63,10 @@ public class King extends Piece {
|
||||
|
||||
private boolean canCastle(Position kingPos, Position freeDest, Position rookPos, Position jumpPos) {
|
||||
Piece rook = board.get(rookPos);
|
||||
return rook != null && rook.getType() == Type.ROOK && isFreePath(new Move(kingPos, freeDest))
|
||||
&& !board.isAttacked(kingPos, getColor().opposite()) && !board.isAttacked(jumpPos, getColor().opposite());
|
||||
return rook != null && rook instanceof Rook && isFreePath(new Move(kingPos, freeDest)) && !board.isAttacked(kingPos, getColor().opposite())
|
||||
&& !board.isAttacked(jumpPos, getColor().opposite());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getType() { return Type.KING; }
|
||||
public int getValue() { return 0; }
|
||||
}
|
@ -45,5 +45,8 @@ public class Knight extends Piece {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getType() { return Type.KNIGHT; }
|
||||
public int getValue() { return 35; }
|
||||
|
||||
@Override
|
||||
public char firstChar() { return 'n'; }
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ import java.util.Iterator;
|
||||
import java.util.Objects;
|
||||
|
||||
import dev.kske.chess.board.Piece.Color;
|
||||
import dev.kske.chess.board.Piece.Type;
|
||||
|
||||
/**
|
||||
* Project: <strong>Chess</strong><br>
|
||||
@ -78,14 +77,14 @@ public class Log implements Iterable<MoveNode> {
|
||||
* @param capturedPiece The piece captured with the move
|
||||
*/
|
||||
public void add(Move move, Piece piece, Piece capturedPiece) {
|
||||
enPassant = piece.getType() == Type.PAWN && move.getyDist() == 2 ? new Position(move.getPos().x, move.getPos().y + move.getySign()) : null;
|
||||
enPassant = piece instanceof Pawn && move.getyDist() == 2 ? new Position(move.getPos().x, move.getPos().y + move.getySign()) : null;
|
||||
if (activeColor == Color.BLACK) ++fullmoveNumber;
|
||||
if (piece.getType() == Type.PAWN || capturedPiece != null) halfmoveClock = 0;
|
||||
if (piece instanceof Pawn || capturedPiece != null) halfmoveClock = 0;
|
||||
else++halfmoveClock;
|
||||
activeColor = activeColor.opposite();
|
||||
|
||||
// Disable castling rights if a king or a rook has been moved
|
||||
if (piece.getType() == Type.KING || piece.getType() == Type.ROOK) disableCastlingRights(piece, move.getPos());
|
||||
if (piece instanceof King || piece instanceof Rook) disableCastlingRights(piece, move.getPos());
|
||||
|
||||
final MoveNode leaf = new MoveNode(move, capturedPiece, castlingRights.clone(), enPassant, activeColor, fullmoveNumber, halfmoveClock);
|
||||
|
||||
@ -170,11 +169,11 @@ public class Log implements Iterable<MoveNode> {
|
||||
|
||||
private void disableCastlingRights(Piece piece, Position initialPosition) {
|
||||
// Kingside
|
||||
if (piece.getType() == Type.KING || piece.getType() == Type.ROOK && initialPosition.x == 7)
|
||||
if (piece instanceof King || piece instanceof Rook && initialPosition.x == 7)
|
||||
castlingRights[piece.getColor() == Color.WHITE ? MoveNode.WHITE_KINGSIDE : MoveNode.BLACK_KINGSIDE] = false;
|
||||
|
||||
// Queenside
|
||||
if (piece.getType() == Type.KING || piece.getType() == Type.ROOK && initialPosition.x == 0)
|
||||
if (piece instanceof King || piece instanceof Rook && initialPosition.x == 0)
|
||||
castlingRights[piece.getColor() == Color.WHITE ? MoveNode.WHITE_QUEENSIDE : MoveNode.BLACK_QUEENSIDE] = false;
|
||||
}
|
||||
|
||||
|
@ -82,5 +82,5 @@ public class Pawn extends Piece {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getType() { return Type.PAWN; }
|
||||
public int getValue() { return 10; }
|
||||
}
|
||||
|
@ -57,9 +57,7 @@ public abstract class Piece implements Cloneable {
|
||||
* @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();
|
||||
}
|
||||
protected final boolean checkDestination(Move move) { return board.getDest(move) == null || board.getDest(move).getColor() != getColor(); }
|
||||
|
||||
@Override
|
||||
public Object clone() {
|
||||
@ -72,14 +70,11 @@ public abstract class Piece implements Cloneable {
|
||||
return piece;
|
||||
}
|
||||
|
||||
public abstract Type getType();
|
||||
|
||||
public Color getColor() { return color; }
|
||||
@Override
|
||||
public String toString() { return getClass().getSimpleName(); }
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(color);
|
||||
}
|
||||
public int hashCode() { return Objects.hash(color); }
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
@ -90,52 +85,50 @@ public abstract class Piece implements Cloneable {
|
||||
return color == other.color;
|
||||
}
|
||||
|
||||
public static enum Type {
|
||||
|
||||
KING, QUEEN, ROOK, KNIGHT, BISHOP, PAWN;
|
||||
/**
|
||||
* @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 Type} in algebraic notation and
|
||||
* @return The first character of this {@link Piece} in algebraic notation and
|
||||
* lower case
|
||||
*/
|
||||
public char firstChar() {
|
||||
return this == KNIGHT ? 'n' : Character.toLowerCase(this.toString().charAt(0));
|
||||
}
|
||||
public char firstChar() { return Character.toLowerCase(toString().charAt(0)); }
|
||||
|
||||
public static Type fromFirstChar(char firstChar) {
|
||||
public static Class<? extends Piece> fromFirstChar(char firstChar) {
|
||||
switch (Character.toLowerCase(firstChar)) {
|
||||
case 'k':
|
||||
return KING;
|
||||
return King.class;
|
||||
case 'q':
|
||||
return QUEEN;
|
||||
return Queen.class;
|
||||
case 'r':
|
||||
return ROOK;
|
||||
return Rook.class;
|
||||
case 'n':
|
||||
return KNIGHT;
|
||||
return Knight.class;
|
||||
case 'b':
|
||||
return BISHOP;
|
||||
return Bishop.class;
|
||||
case 'p':
|
||||
return PAWN;
|
||||
return Pawn.class;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the {@link Color} of this {@link Piece}
|
||||
*/
|
||||
public Color getColor() { return color; }
|
||||
|
||||
public static enum Color {
|
||||
|
||||
WHITE, BLACK;
|
||||
|
||||
public static Color fromFirstChar(char c) {
|
||||
return Character.toLowerCase(c) == 'w' ? WHITE : BLACK;
|
||||
}
|
||||
public static Color fromFirstChar(char c) { return Character.toLowerCase(c) == 'w' ? WHITE : BLACK; }
|
||||
|
||||
public char firstChar() {
|
||||
return this == WHITE ? 'w' : 'b';
|
||||
}
|
||||
public char firstChar() { return this == WHITE ? 'w' : 'b'; }
|
||||
|
||||
public Color opposite() {
|
||||
return this == WHITE ? BLACK : WHITE;
|
||||
}
|
||||
public Color opposite() { return this == WHITE ? BLACK : WHITE; }
|
||||
}
|
||||
}
|
||||
|
@ -101,5 +101,5 @@ public class Queen extends Piece {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getType() { return Type.QUEEN; }
|
||||
public int getValue() { return 90; }
|
||||
}
|
||||
|
@ -65,5 +65,5 @@ public class Rook extends Piece {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getType() { return Type.ROOK; }
|
||||
public int getValue() { return 50; }
|
||||
}
|
||||
|
@ -5,10 +5,16 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import dev.kske.chess.board.Bishop;
|
||||
import dev.kske.chess.board.Board;
|
||||
import dev.kske.chess.board.King;
|
||||
import dev.kske.chess.board.Knight;
|
||||
import dev.kske.chess.board.Move;
|
||||
import dev.kske.chess.board.Pawn;
|
||||
import dev.kske.chess.board.Piece;
|
||||
import dev.kske.chess.board.Piece.Color;
|
||||
import dev.kske.chess.board.Piece.Type;
|
||||
import dev.kske.chess.board.Queen;
|
||||
import dev.kske.chess.board.Rook;
|
||||
|
||||
/**
|
||||
* Project: <strong>Chess</strong><br>
|
||||
@ -28,35 +34,35 @@ public class MoveProcessor implements Callable<ProcessingResult> {
|
||||
|
||||
private Move bestMove;
|
||||
|
||||
private static final Map<Type, int[][]> positionScores;
|
||||
private static final Map<Class<? extends Piece>, int[][]> positionScores;
|
||||
|
||||
static {
|
||||
positionScores = new HashMap<>();
|
||||
positionScores.put(Type.KING,
|
||||
positionScores.put(King.class,
|
||||
new int[][] { new int[] { -3, -4, -4, -5, -5, -4, -4, -3 }, new int[] { -3, -4, -4, -5, -4, -4, -4, -3 },
|
||||
new int[] { -3, -4, -4, -5, -4, -4, -4, -3 }, new int[] { -3, -4, -4, -5, -4, -4, -4, -3 },
|
||||
new int[] { -2, -3, -3, -2, -2, -2, -2, -1 }, new int[] { -1, -2, -2, -2, -2, -2, -2, -1 },
|
||||
new int[] { 2, 2, 0, 0, 0, 0, 2, 2 }, new int[] { 2, 3, 1, 0, 0, 1, 3, 2 } });
|
||||
positionScores.put(Type.QUEEN,
|
||||
positionScores.put(Queen.class,
|
||||
new int[][] { new int[] { -2, -1, -1, -1, -1, -1, -1, -2 }, new int[] { -1, 0, 0, 0, 0, 0, 0, -1 },
|
||||
new int[] { -1, 0, 1, 1, 1, 1, 0, -1 }, new int[] { -1, 0, 1, 1, 1, 1, 0, -1 }, new int[] { 0, 0, 1, 1, 1, 1, 0, -1 },
|
||||
new int[] { -1, 1, 1, 1, 1, 1, 0, -1 }, new int[] { -1, 0, 1, 0, 0, 0, 0, -1 },
|
||||
new int[] { -2, -1, -1, -1, -1, -1, -1, -2 } });
|
||||
positionScores.put(Type.ROOK,
|
||||
positionScores.put(Rook.class,
|
||||
new int[][] { new int[] { 0, 0, 0, 0, 0, 0, 0, 0 }, new int[] { 1, 1, 1, 1, 1, 1, 1, 1 }, new int[] { -1, 0, 0, 0, 0, 0, 0, -1 },
|
||||
new int[] { -1, 0, 0, 0, 0, 0, 0, -1 }, new int[] { -1, 0, 0, 0, 0, 0, 0, -1 }, new int[] { -1, 0, 0, 0, 0, 0, 0, -1 },
|
||||
new int[] { -1, 0, 0, 0, 0, 0, 0, -1 }, new int[] { 0, 0, 0, 1, 1, 0, 0, 0 } });
|
||||
positionScores.put(Type.KNIGHT,
|
||||
positionScores.put(Knight.class,
|
||||
new int[][] { new int[] { -5, -4, -3, -3, -3, -3, -4, -5 }, new int[] { -4, -2, 0, 0, 0, 0, -2, -4 },
|
||||
new int[] { -3, 0, 1, 2, 2, 1, 0, -3 }, new int[] { -3, 1, 2, 2, 2, 2, 1, -3 }, new int[] { -3, 0, 2, 2, 2, 2, 0, -1 },
|
||||
new int[] { -3, 1, 1, 2, 2, 1, 1, -3 }, new int[] { -4, -2, 0, 1, 1, 0, -2, -4 },
|
||||
new int[] { -5, -4, -3, -3, -3, -3, -4, -5 } });
|
||||
positionScores.put(Type.BISHOP,
|
||||
positionScores.put(Bishop.class,
|
||||
new int[][] { new int[] { -2, -1, -1, -1, -1, -1, -1, 2 }, new int[] { -1, 0, 0, 0, 0, 0, 0, -1 },
|
||||
new int[] { -1, 0, 1, 1, 1, 1, 0, -1 }, new int[] { -1, 1, 1, 1, 1, 1, 1, -1 }, new int[] { -1, 0, 1, 1, 1, 1, 0, -1 },
|
||||
new int[] { -1, 1, 1, 1, 1, 1, 1, -1 }, new int[] { -1, 1, 0, 0, 0, 0, 1, -1 },
|
||||
new int[] { -2, -1, -1, -1, -1, -1, -1, -2 } });
|
||||
positionScores.put(Type.PAWN,
|
||||
positionScores.put(Pawn.class,
|
||||
new int[][] { new int[] { 0, 0, 0, 0, 0, 0, 0, 0 }, new int[] { 5, 5, 5, 5, 5, 5, 5, 5 }, new int[] { 1, 1, 2, 3, 3, 2, 1, 1 },
|
||||
new int[] { 0, 0, 1, 3, 3, 1, 0, 0 }, new int[] { 0, 0, 0, 2, 2, 0, 0, 0 }, new int[] { 0, 0, -1, 0, 0, -1, 0, 0 },
|
||||
new int[] { 0, 1, 1, -2, -2, 1, 1, 0 }, new int[] { 0, 0, 0, 0, 0, 0, 0, 0 } });
|
||||
@ -108,25 +114,9 @@ public class MoveProcessor implements Callable<ProcessingResult> {
|
||||
for (int i = 0; i < 8; i++)
|
||||
for (int j = 0; j < 8; j++)
|
||||
if (board.getBoardArr()[i][j] != null && board.getBoardArr()[i][j].getColor() == color) {
|
||||
switch (board.getBoardArr()[i][j].getType()) {
|
||||
case QUEEN:
|
||||
score += 90;
|
||||
break;
|
||||
case ROOK:
|
||||
score += 50;
|
||||
break;
|
||||
case KNIGHT:
|
||||
score += 30;
|
||||
break;
|
||||
case BISHOP:
|
||||
score += 30;
|
||||
break;
|
||||
case PAWN:
|
||||
score += 10;
|
||||
break;
|
||||
}
|
||||
if (positionScores.containsKey(board.getBoardArr()[i][j].getType()))
|
||||
score += positionScores.get(board.getBoardArr()[i][j].getType())[i][color == Color.WHITE ? j : 7 - j];
|
||||
score += board.getBoardArr()[i][j].getValue();
|
||||
if (positionScores.containsKey(board.getBoardArr()[i][j].getClass()))
|
||||
score += positionScores.get(board.getBoardArr()[i][j].getClass())[i][color == Color.WHITE ? j : 7 - j];
|
||||
}
|
||||
return score;
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ public class TextureUtil {
|
||||
* @return The fitting texture
|
||||
*/
|
||||
public static Image getPieceTexture(Piece piece) {
|
||||
String key = piece.getType().toString().toLowerCase() + "_" + piece.getColor().toString().toLowerCase();
|
||||
String key = piece.toString().toLowerCase() + "_" + piece.getColor().toString().toLowerCase();
|
||||
return scaledTextures.get(key);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user