diff --git a/src/dev/kske/chess/board/Bishop.java b/src/dev/kske/chess/board/Bishop.java
index 4b2d8b0..9412a30 100644
--- a/src/dev/kske/chess/board/Bishop.java
+++ b/src/dev/kske/chess/board/Bishop.java
@@ -65,5 +65,5 @@ public class Bishop extends Piece {
}
@Override
- public Type getType() { return Type.BISHOP; }
+ public int getValue() { return 30; }
}
diff --git a/src/dev/kske/chess/board/Board.java b/src/dev/kske/chess/board/Board.java
index 60f0014..fbbf2bd 100644
--- a/src/dev/kske/chess/board/Board.java
+++ b/src/dev/kske/chess/board/Board.java
@@ -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: Chess
@@ -61,9 +60,6 @@ public class Board {
Piece piece = getPos(move);
if (piece == null || !piece.isValidMove(move)) return false;
else {
- // Set type after validation
- if (move.type == Move.Type.UNKNOWN) move.type = Move.Type.NORMAL;
-
// Move piece
move(move);
@@ -86,40 +82,11 @@ public class Board {
Piece piece = getPos(move);
Piece capturePiece = getDest(move);
- switch (move.type) {
- case PAWN_PROMOTION:
- setPos(move, null);
- // 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);
- setPos(move, null);
-
- // Move the rook
- Move rookMove = move.dest.x == 6 ? new Move(7, move.pos.y, 5, move.pos.y) // Kingside
- : new Move(0, move.pos.y, 3, move.pos.y); // Queenside
- setDest(rookMove, getPos(rookMove));
- setPos(rookMove, null);
- break;
- case UNKNOWN:
- System.err.printf("Move of unknown type %s found!%n", move);
- case NORMAL:
- setDest(move, piece);
- setPos(move, null);
- break;
- default:
- System.err.printf("Move %s of unimplemented type found!%n", move);
- }
+ // Execute the move
+ 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.dest);
+ if (piece instanceof King) kingPos.put(piece.getColor(), move.getDest());
// Update log
log.add(move, piece, capturePiece);
@@ -136,57 +103,75 @@ public class Board {
Pattern.compile(
"^(?[NBRQK])(?:(?[a-h])|(?[1-8])|(?[a-h][1-8]))?x?(?[a-h][1-8])(?:\\+{0,2}|\\#)$"));
patterns.put("pawnCapture",
- Pattern.compile("^(?[a-h])(?[1-8])?x(?[a-h][1-8])(?[NBRQK])?(?:\\+{0,2}|\\#)?$"));
- patterns.put("pawnPush", Pattern.compile("^(?[a-h][1-8])(?[NBRQK])?(?:\\+{0,2}|\\#)$"));
+ Pattern.compile("^(?[a-h])(?[1-8])?x(?[a-h][1-8])(?[NBRQ])?(?:\\+{0,2}|\\#)?$"));
+ patterns.put("pawnPush", Pattern.compile("^(?[a-h][1-8])(?[NBRQ])?(?:\\+{0,2}|\\#)$"));
patterns.put("castling", Pattern.compile("^(?O-O-O)|(?O-O)(?:\\+{0,2}|\\#)?$"));
patterns.forEach((patternName, pattern) -> {
Matcher m = pattern.matcher(sanMove);
if (m.find()) {
- Position pos = null, dest = null;
- Move.Type moveType = Move.Type.NORMAL;
+ Position pos = null, dest = null;
+ Move move = null;
switch (patternName) {
case "pieceMove":
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));
- char file;
- int rank;
+ 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"));
+
+ dest = Position.fromLAN(m.group("toSquare"));
pos = Position.fromLAN(String.format("%c%d", file, rank));
+
+ if (m.group("promotedTo") != null) {
+ try {
+ move = new PawnPromotion(pos, dest, Piece.fromFirstChar(m.group("promotedTo").charAt(0)));
+ } catch (NoSuchMethodException | SecurityException | IllegalArgumentException e) {
+ e.printStackTrace();
+ }
+ } else move = new Move(pos, dest);
break;
case "pawnPush":
dest = Position.fromLAN(m.group("toSquare"));
- // TODO: Pawn promotion
int step = log.getActiveColor() == Color.WHITE ? 1 : -1;
// One step forward
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);
+
+ if (m.group("promotedTo") != null) {
+ try {
+ move = new PawnPromotion(pos, dest, Piece.fromFirstChar(m.group("promotedTo").charAt(0)));
+ } catch (NoSuchMethodException | SecurityException | IllegalArgumentException e) {
+ e.printStackTrace();
+ }
+ } else move = new Move(pos, dest);
break;
case "castling":
pos = new Position(4, log.getActiveColor() == Color.WHITE ? 7 : 0);
dest = new Position(m.group("kingside") != null ? 6 : 2, pos.y);
- moveType = Move.Type.CASTLING;
+ move = new Castling(pos, dest);
break;
}
- move(new Move(pos, dest, moveType));
+ move(move);
return;
}
});
@@ -196,43 +181,14 @@ public class Board {
* Reverts the last move and removes it from the log.
*/
public void revert() {
- MoveNode moveNode = log.getLast();
- Move move = moveNode.move;
- Piece capturedPiece = moveNode.capturedPiece;
+ MoveNode moveNode = log.getLast();
+ Move move = moveNode.move;
- switch (move.type) {
- case PAWN_PROMOTION:
- 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));
- setDest(move, null);
-
- // Move the rook
- Move rookMove = move.dest.x == 6 ? new Move(5, move.pos.y, 7, move.pos.y) // Kingside
- : new Move(3, move.pos.y, 0, move.pos.y); // Queenside
- setDest(rookMove, getPos(rookMove));
- setPos(rookMove, null);
- break;
- case UNKNOWN:
- System.err.printf("Move of unknown type %s found!%n", move);
- case NORMAL:
- setPos(move, getDest(move));
- setDest(move, capturedPiece);
- break;
- default:
- System.err.printf("Move %s of unimplemented type found!%n", move);
- }
+ // Revert the move
+ 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.pos);
+ if (getPos(move) instanceof King) kingPos.put(getPos(move).getColor(), move.getPos());
// Update log
log.removeLast();
@@ -379,30 +335,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 file The file in which to search for the piece
+ * @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 rank The rank in which to search for the piece
+ * @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 '-';
}
@@ -410,14 +366,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 dest The destination that the piece is required to reach
+ * @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;
}
@@ -436,13 +392,13 @@ public class Board {
* @param move The move from which position to return a piece
* @return The piece at the position of the move
*/
- public Piece getPos(Move move) { return get(move.pos); }
+ public Piece getPos(Move move) { return get(move.getPos()); }
/**
* @param move The move from which destination to return a piece
* @return The piece at the destination of the move
*/
- public Piece getDest(Move move) { return get(move.dest); }
+ public Piece getDest(Move move) { return get(move.getDest()); }
/**
* Places a piece at the position of a move.
@@ -450,7 +406,7 @@ public class Board {
* @param move The move at which position to place the piece
* @param piece The piece to place
*/
- public void setPos(Move move, Piece piece) { set(move.pos, piece); }
+ public void setPos(Move move, Piece piece) { set(move.getPos(), piece); }
/**
* Places a piece at the destination of a move.
@@ -458,7 +414,7 @@ public class Board {
* @param move The move at which destination to place the piece
* @param piece The piece to place
*/
- public void setDest(Move move, Piece piece) { set(move.dest, piece); }
+ public void setDest(Move move, Piece piece) { set(move.getDest(), piece); }
/**
* @return The board array
diff --git a/src/dev/kske/chess/board/Castling.java b/src/dev/kske/chess/board/Castling.java
new file mode 100644
index 0000000..e631a24
--- /dev/null
+++ b/src/dev/kske/chess/board/Castling.java
@@ -0,0 +1,35 @@
+package dev.kske.chess.board;
+
+/**
+ * Project: Chess
+ * File: Castling.java
+ * Created: 2 Nov 2019
+ *
+ * @since Chess v0.5-alpha
+ * @author Kai S. K. Engelbart
+ */
+public class Castling extends Move {
+
+ private final Move rookMove;
+
+ public Castling(Position pos, Position dest) {
+ super(pos, dest);
+ rookMove = dest.x == 6 ? new Move(7, pos.y, 5, pos.y) : new Move(0, pos.y, 3, pos.y);
+ }
+
+ public Castling(int xPos, int yPos, int xDest, int yDest) { this(new Position(xPos, yPos), new Position(xDest, yDest)); }
+
+ @Override
+ public void execute(Board board) {
+ // Move the king and the rook
+ super.execute(board);
+ rookMove.execute(board);
+ }
+
+ @Override
+ public void revert(Board board, Piece capturedPiece) {
+ // Move the king and the rook
+ super.revert(board, capturedPiece);
+ rookMove.revert(board, null);
+ }
+}
diff --git a/src/dev/kske/chess/board/EnPassant.java b/src/dev/kske/chess/board/EnPassant.java
new file mode 100644
index 0000000..69c48d9
--- /dev/null
+++ b/src/dev/kske/chess/board/EnPassant.java
@@ -0,0 +1,35 @@
+package dev.kske.chess.board;
+
+/**
+ * Project: Chess
+ * File: EnPassant.java
+ * Created: 2 Nov 2019
+ *
+ * @since Chess v0.5-alpha
+ * @author Kai S. K. Engelbart
+ */
+public class EnPassant extends Move {
+
+ private final Position capturePos;
+
+ public EnPassant(Position pos, Position dest) {
+ super(pos, dest);
+ capturePos = new Position(dest.x, dest.y - ySign);
+ }
+
+ public EnPassant(int xPos, int yPos, int xDest, int yDest) { this(new Position(xPos, yPos), new Position(xDest, yDest)); }
+
+ @Override
+ public void execute(Board board) {
+ super.execute(board);
+ board.set(capturePos, null);
+ }
+
+ @Override
+ public void revert(Board board, Piece capturedPiece) {
+ super.revert(board, capturedPiece);
+ board.set(capturePos, new Pawn(board.get(pos).getColor().opposite(), board));
+ }
+
+ public Position getCapturePos() { return capturePos; }
+}
diff --git a/src/dev/kske/chess/board/FENString.java b/src/dev/kske/chess/board/FENString.java
index 0dbb3e5..8f27140 100644
--- a/src/dev/kske/chess/board/FENString.java
+++ b/src/dev/kske/chess/board/FENString.java
@@ -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);
}
}
diff --git a/src/dev/kske/chess/board/King.java b/src/dev/kske/chess/board/King.java
index a864171..6807bb3 100644
--- a/src/dev/kske/chess/board/King.java
+++ b/src/dev/kske/chess/board/King.java
@@ -17,18 +17,9 @@ public class King extends Piece {
@Override
public boolean isValidMove(Move move) {
- // Castling
- if (move.xDist == 2 && move.yDist == 0) {
- if (canCastleKingside()) {
- move.type = Move.Type.CASTLING;
- return true;
- }
- if (canCastleQueenside()) {
- move.type = Move.Type.CASTLING;
- return true;
- }
- }
- return move.xDist <= 1 && move.yDist <= 1 && checkDestination(move);
+ return (move.getxDist() == 2 && move.getyDist() == 0
+ && (move.getDest().x == 6 && canCastleKingside() || move.getDest().x == 2 && canCastleQueenside()))
+ || move.getxDist() <= 1 && move.getyDist() <= 1 && checkDestination(move);
}
@Override
@@ -42,8 +33,8 @@ public class King extends Piece {
}
// Castling
- if (canCastleKingside()) moves.add(new Move(pos, new Position(6, pos.y), Move.Type.CASTLING));
- if (canCastleQueenside()) moves.add(new Move(pos, new Position(2, pos.y), Move.Type.CASTLING));
+ if (canCastleKingside()) moves.add(new Castling(pos, new Position(6, pos.y)));
+ if (canCastleQueenside()) moves.add(new Castling(pos, new Position(2, pos.y)));
return moves;
}
@@ -72,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; }
+}
\ No newline at end of file
diff --git a/src/dev/kske/chess/board/Knight.java b/src/dev/kske/chess/board/Knight.java
index aba0499..9e54fd8 100644
--- a/src/dev/kske/chess/board/Knight.java
+++ b/src/dev/kske/chess/board/Knight.java
@@ -19,8 +19,8 @@ public class Knight extends Piece {
@Override
public boolean isValidMove(Move move) {
- return Math.abs(move.xDist - move.yDist) == 1
- && (move.xDist == 1 && move.yDist == 2 || move.xDist == 2 && move.yDist == 1) && checkDestination(move);
+ return Math.abs(move.getxDist() - move.getyDist()) == 1
+ && (move.getxDist() == 1 && move.getyDist() == 2 || move.getxDist() == 2 && move.getyDist() == 1) && checkDestination(move);
}
private void checkAndInsertMove(List moves, Position pos, int offsetX, int offsetY) {
@@ -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'; }
}
diff --git a/src/dev/kske/chess/board/Log.java b/src/dev/kske/chess/board/Log.java
index d7754ff..9d60002 100644
--- a/src/dev/kske/chess/board/Log.java
+++ b/src/dev/kske/chess/board/Log.java
@@ -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: Chess
@@ -78,14 +77,14 @@ public class Log implements Iterable {
* @param capturedPiece The piece captured with the move
*/
public void add(Move move, Piece piece, Piece capturedPiece) {
- enPassant = piece.getType() == Type.PAWN && move.yDist == 2 ? new Position(move.pos.x, move.pos.y + move.ySign) : 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.pos);
+ 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 {
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;
}
diff --git a/src/dev/kske/chess/board/Move.java b/src/dev/kske/chess/board/Move.java
index f1312f4..a03a78c 100644
--- a/src/dev/kske/chess/board/Move.java
+++ b/src/dev/kske/chess/board/Move.java
@@ -12,52 +12,58 @@ import java.util.Objects;
*/
public class Move {
- public final Position pos, dest;
- public final int xDist, yDist, xSign, ySign;
- public Type type;
+ protected final Position pos, dest;
+ protected final int xDist, yDist, xSign, ySign;
- public Move(Position pos, Position dest, Type type) {
+ public Move(Position pos, Position dest) {
this.pos = pos;
this.dest = dest;
- this.type = type;
xDist = Math.abs(dest.x - pos.x);
yDist = Math.abs(dest.y - pos.y);
xSign = (int) Math.signum(dest.x - pos.x);
ySign = (int) Math.signum(dest.y - pos.y);
}
- public Move(Position pos, Position dest) {
- this(pos, dest, Type.NORMAL);
+ public Move(int xPos, int yPos, int xDest, int yDest) { this(new Position(xPos, yPos), new Position(xDest, yDest)); }
+
+ public void execute(Board board) {
+ // Move the piece to the move's destination square and clean the old position
+ board.set(dest, board.get(pos));
+ board.set(pos, null);
}
- public Move(int xPos, int yPos, int xDest, int yDest) {
- this(new Position(xPos, yPos), new Position(xDest, yDest));
+ public void revert(Board board, Piece capturedPiece) {
+ // Move the piece to the move's position square and clean the destination
+ board.set(pos, board.get(dest));
+ board.set(dest, capturedPiece);
}
public static Move fromLAN(String move) {
- return new Move(Position.fromLAN(move.substring(0, 2)),
- Position.fromLAN(move.substring(2)));
+ Position pos = Position.fromLAN(move.substring(0, 2));
+ Position dest = Position.fromLAN(move.substring(2));
+ if (move.length() == 5) {
+ try {
+ return new PawnPromotion(pos, dest, Piece.fromFirstChar(move.charAt(4)));
+ } catch (NoSuchMethodException | SecurityException | IllegalArgumentException e) {
+ e.printStackTrace();
+ return null;
+ }
+ } else return new Move(pos, dest);
}
- public String toLAN() {
- return pos.toLAN() + dest.toLAN();
- }
+ public String toLAN() { return getPos().toLAN() + getDest().toLAN(); }
- public boolean isHorizontal() { return yDist == 0; }
+ public boolean isHorizontal() { return getyDist() == 0; }
- public boolean isVertical() { return xDist == 0; }
+ public boolean isVertical() { return getxDist() == 0; }
- public boolean isDiagonal() { return xDist == yDist; }
+ public boolean isDiagonal() { return getxDist() == getyDist(); }
@Override
- public String toString() {
- return String.format("%s -> %s", pos, dest);
- }
+ public String toString() { return toLAN(); }
@Override
- public int hashCode() {
- return Objects.hash(dest, pos, type, xDist, xSign, yDist, ySign);
- }
+ public int hashCode() { return Objects.hash(getDest(), getPos(), getxDist(), getxSign(), getyDist(), getySign()); }
@Override
public boolean equals(Object obj) {
@@ -65,11 +71,19 @@ public class Move {
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
Move other = (Move) obj;
- return Objects.equals(dest, other.dest) && Objects.equals(pos, other.pos) && type == other.type
- && xDist == other.xDist && xSign == other.xSign && yDist == other.yDist && ySign == other.ySign;
+ return Objects.equals(getDest(), other.getDest()) && Objects.equals(getPos(), other.getPos()) && getxDist() == other.getxDist()
+ && getxSign() == other.getxSign() && getyDist() == other.getyDist() && getySign() == other.getySign();
}
- public static enum Type {
- NORMAL, PAWN_PROMOTION, CASTLING, EN_PASSANT, UNKNOWN
- }
+ public Position getPos() { return pos; }
+
+ public Position getDest() { return dest; }
+
+ public int getxDist() { return xDist; }
+
+ public int getyDist() { return yDist; }
+
+ public int getxSign() { return xSign; }
+
+ public int getySign() { return ySign; }
}
diff --git a/src/dev/kske/chess/board/Pawn.java b/src/dev/kske/chess/board/Pawn.java
index b83a625..18e275e 100644
--- a/src/dev/kske/chess/board/Pawn.java
+++ b/src/dev/kske/chess/board/Pawn.java
@@ -13,87 +13,74 @@ import java.util.List;
*/
public class Pawn extends Piece {
- public Pawn(Color color, Board board) {
- super(color, board);
- }
+ 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;
+ boolean step = move.isVertical() && move.getyDist() == 1;
+ boolean doubleStep = move.isVertical() && move.getyDist() == 2;
+ boolean strafe = move.isDiagonal() && move.getxDist() == 1;
+ boolean enPassant = strafe && move.getDest().equals(board.getLog().getEnPassant());
+ if (getColor() == Color.WHITE) doubleStep &= move.getPos().y == 6;
+ else doubleStep &= move.getPos().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.getLog().getEnPassant())) {
- enPassant = true;
- move.type = Move.Type.EN_PASSANT;
- }
-
- return enPassant || (step ^ doubleStep ^ strafe) && move.ySign == (getColor() == Color.WHITE ? -1 : 1)
- && isFreePath(move);
+ return enPassant || (step ^ doubleStep ^ strafe) && move.getySign() == (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;
+ if (move.getyDist() == 2)
+ return board.getBoardArr()[move.getPos().x][move.getDest().y - move.getySign()] == null && board.getDest(move) == null;
// One step forward
- else if (move.xDist == 0) return board.getDest(move) == null;
+ else if (move.getxDist() == 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;
+ List moves = new ArrayList<>();
+ int sign = getColor() == Color.WHITE ? -1 : 1;
+ boolean pawnPromotion = sign == 1 && pos.y == 6 || sign == -1 && pos.y == 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);
- }
+ if (pos.x > 0) addMoveIfValid(moves, pos, new Position(pos.x - 1, pos.y + sign), pawnPromotion);
// 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);
- }
+ if (pos.x < 7) addMoveIfValid(moves, pos, new Position(pos.x + 1, pos.y + sign), pawnPromotion);
// 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);
- }
+ if (sign == 1 && pos.y < 7 || sign == -1 && pos.y > 0) addMoveIfValid(moves, pos, new Position(pos.x, pos.y + sign), pawnPromotion);
// 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);
+ if (sign == 1 && pos.y == 1 || sign == -1 && pos.y == 6) addMoveIfValid(moves, pos, new Position(pos.x, pos.y + 2 * sign), pawnPromotion);
// Add en passant move if necessary
if (board.getLog().getEnPassant() != null) {
- Move move = new Move(pos, board.getLog().getEnPassant(), Move.Type.EN_PASSANT);
- if (move.isDiagonal() && move.xDist == 1) moves.add(move);
+ Move move = new EnPassant(pos, board.getLog().getEnPassant());
+ if (move.isDiagonal() && move.getxDist() == 1) moves.add(move);
}
return moves;
}
+ private void addMoveIfValid(List moves, Position pos, Position dest, boolean pawnPromotion) {
+ Move move = new Move(pos, dest);
+ if (isFreePath(move)) {
+ if (pawnPromotion) {
+ try {
+ moves.add(new PawnPromotion(pos, dest, Queen.class));
+ moves.add(new PawnPromotion(pos, dest, Rook.class));
+ moves.add(new PawnPromotion(pos, dest, Knight.class));
+ moves.add(new PawnPromotion(pos, dest, Bishop.class));
+ } catch (NoSuchMethodException | SecurityException | IllegalArgumentException e) {
+ e.printStackTrace();
+ }
+ } else moves.add(move);
+ }
+ }
+
@Override
- public Type getType() { return Type.PAWN; }
+ public int getValue() { return 10; }
}
diff --git a/src/dev/kske/chess/board/PawnPromotion.java b/src/dev/kske/chess/board/PawnPromotion.java
new file mode 100644
index 0000000..91ddaac
--- /dev/null
+++ b/src/dev/kske/chess/board/PawnPromotion.java
@@ -0,0 +1,81 @@
+package dev.kske.chess.board;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Objects;
+
+import dev.kske.chess.board.Piece.Color;
+
+/**
+ * Project: Chess
+ * File: PawnPromotion.java
+ * Created: 2 Nov 2019
+ *
+ * @since Chess v0.5-alpha
+ * @author Kai S. K. Engelbart
+ */
+public class PawnPromotion extends Move {
+
+ private final Class extends Piece> promotionPieceClass;
+ private final Constructor extends Piece> promotionPieceConstructor;
+
+ public PawnPromotion(Position pos, Position dest, Class extends Piece> promotionPieceClass) throws NoSuchMethodException, SecurityException {
+ super(pos, dest);
+ this.promotionPieceClass = promotionPieceClass;
+
+ // Cache piece constructor
+ promotionPieceConstructor = promotionPieceClass.getDeclaredConstructor(Color.class, Board.class);
+ promotionPieceConstructor.setAccessible(true);
+ }
+
+ public PawnPromotion(int xPos, int yPos, int xDest, int yDest, Class extends Piece> promotionPiece)
+ throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException,
+ InstantiationException {
+ this(new Position(xPos, yPos), new Position(xDest, yDest), promotionPiece);
+ }
+
+ @Override
+ public void execute(Board board) {
+ try {
+ board.set(pos, promotionPieceConstructor.newInstance(board.get(pos).getColor(), board));
+ super.execute(board);
+ } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | SecurityException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public void revert(Board board, Piece capturedPiece) {
+ board.set(dest, new Pawn(board.get(dest).getColor(), board));
+ super.revert(board, capturedPiece);
+ }
+
+ @Override
+ public String toLAN() {
+ char promotionPieceChar = '-';
+ try {
+ promotionPieceChar = (char) promotionPieceClass.getMethod("firstChar").invoke(promotionPieceConstructor.newInstance(null, null));
+ } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException
+ | InstantiationException e) {
+ e.printStackTrace();
+ }
+ return pos.toLAN() + dest.toLAN() + promotionPieceChar;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = super.hashCode();
+ result = prime * result + Objects.hash(promotionPieceClass);
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) return true;
+ if (!super.equals(obj)) return false;
+ if (getClass() != obj.getClass()) return false;
+ PawnPromotion other = (PawnPromotion) obj;
+ return Objects.equals(promotionPieceClass, other.promotionPieceClass);
+ }
+}
diff --git a/src/dev/kske/chess/board/Piece.java b/src/dev/kske/chess/board/Piece.java
index 865fb9f..848dca5 100644
--- a/src/dev/kske/chess/board/Piece.java
+++ b/src/dev/kske/chess/board/Piece.java
@@ -44,8 +44,8 @@ public abstract class Piece implements Cloneable {
* @param move The move to check
*/
protected boolean isFreePath(Move move) {
- for (int i = move.pos.x + move.xSign, j = move.pos.y + move.ySign; i != move.dest.x
- || j != move.dest.y; i += move.xSign, j += move.ySign)
+ 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);
}
@@ -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 {
+ /**
+ * @return the standard value of this {@link Piece} that can be used for board
+ * evaluation
+ */
+ public abstract int getValue();
- KING, QUEEN, ROOK, KNIGHT, BISHOP, PAWN;
+ /**
+ * @return The first character of this {@link Piece} in algebraic notation and
+ * lower case
+ */
+ public char firstChar() { return Character.toLowerCase(toString().charAt(0)); }
- /**
- * @return The first character of this {@link Type} in algebraic notation and
- * lower case
- */
- public char firstChar() {
- return this == KNIGHT ? 'n' : Character.toLowerCase(this.toString().charAt(0));
- }
-
- public static Type fromFirstChar(char firstChar) {
- switch (Character.toLowerCase(firstChar)) {
- case 'k':
- return KING;
- case 'q':
- return QUEEN;
- case 'r':
- return ROOK;
- case 'n':
- return KNIGHT;
- case 'b':
- return BISHOP;
- case 'p':
- return PAWN;
- default:
- return null;
- }
+ 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; }
+
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; }
}
}
diff --git a/src/dev/kske/chess/board/Queen.java b/src/dev/kske/chess/board/Queen.java
index 3932b95..b2482ce 100644
--- a/src/dev/kske/chess/board/Queen.java
+++ b/src/dev/kske/chess/board/Queen.java
@@ -101,5 +101,5 @@ public class Queen extends Piece {
}
@Override
- public Type getType() { return Type.QUEEN; }
+ public int getValue() { return 90; }
}
diff --git a/src/dev/kske/chess/board/Rook.java b/src/dev/kske/chess/board/Rook.java
index 590e49e..b2efd5c 100644
--- a/src/dev/kske/chess/board/Rook.java
+++ b/src/dev/kske/chess/board/Rook.java
@@ -65,5 +65,5 @@ public class Rook extends Piece {
}
@Override
- public Type getType() { return Type.ROOK; }
+ public int getValue() { return 50; }
}
diff --git a/src/dev/kske/chess/game/NaturalPlayer.java b/src/dev/kske/chess/game/NaturalPlayer.java
index 8670a0e..864c4e5 100644
--- a/src/dev/kske/chess/game/NaturalPlayer.java
+++ b/src/dev/kske/chess/game/NaturalPlayer.java
@@ -5,9 +5,11 @@ import java.awt.event.MouseListener;
import java.util.List;
import java.util.stream.Collectors;
-import dev.kske.chess.board.Board;
+import javax.swing.JComboBox;
+import javax.swing.JOptionPane;
+
import dev.kske.chess.board.Move;
-import dev.kske.chess.board.Move.Type;
+import dev.kske.chess.board.Piece;
import dev.kske.chess.board.Piece.Color;
import dev.kske.chess.board.Position;
import dev.kske.chess.ui.OverlayComponent;
@@ -25,7 +27,8 @@ public class NaturalPlayer extends Player implements MouseListener {
private final OverlayComponent overlayComponent;
private boolean moveRequested;
- private Position pos;
+ private Piece selectedPiece;
+ private List possibleMoves;
public NaturalPlayer(Color color, OverlayComponent overlayComponent) {
super(color);
@@ -37,43 +40,63 @@ public class NaturalPlayer extends Player implements MouseListener {
}
@Override
- public void requestMove() {
- moveRequested = true;
- }
+ public void requestMove() { moveRequested = true; }
@Override
- public void cancelMove() {
- moveRequested = false;
- }
+ public void cancelMove() { moveRequested = false; }
@Override
- public void disconnect() {
- overlayComponent.removeMouseListener(this);
- }
+ public void disconnect() { overlayComponent.removeMouseListener(this); }
@Override
public void mousePressed(MouseEvent evt) {
if (!moveRequested) return;
- if (pos == null) {
- pos = new Position(evt.getPoint().x / overlayComponent.getTileSize(),
- evt.getPoint().y / overlayComponent.getTileSize());
+ if (selectedPiece == null) {
- Board board = new Board(this.board);
- if (board.get(pos) != null && board.get(pos).getColor() == color) {
- List positions = board.getMoves(pos)
- .stream()
- .map(move -> move.dest)
- .collect(Collectors.toList());
- overlayComponent.displayDots(positions);
- } else pos = null;
+ // Get selected Piece
+ final Position pos = new Position(evt.getPoint().x / overlayComponent.getTileSize(), evt.getPoint().y / overlayComponent.getTileSize());
+ selectedPiece = board.get(pos);
+
+ // Check if a piece was selected
+ if (selectedPiece != null) {
+
+ // Discard selection if the piece has the wrong color
+ if (selectedPiece.getColor() == color.opposite()) selectedPiece = null;
+ else {
+
+ // Generate all moves possible with the selected piece and display their
+ // destinations
+ possibleMoves = selectedPiece.getMoves(pos);
+ overlayComponent.displayDots(possibleMoves.stream().map(move -> move.getDest()).collect(Collectors.toList()));
+ }
+ }
} else {
- Position dest = new Position(evt.getPoint().x / overlayComponent.getTileSize(),
- evt.getPoint().y / overlayComponent.getTileSize());
+ Position dest = new Position(evt.getPoint().x / overlayComponent.getTileSize(), evt.getPoint().y / overlayComponent.getTileSize());
+ // Get all moves leading to the specified destination
+ List selectedMoves = possibleMoves.stream().filter(m -> m.getDest().equals(dest)).collect(Collectors.toList());
+ if (!selectedMoves.isEmpty()) {
+ Move move;
+
+ // Process pawn promotion if necessary
+ if (selectedMoves.size() > 1) {
+
+ // Let the user select a promotion piece
+ JComboBox comboBox = new JComboBox(selectedMoves.toArray(new Move[0]));
+ JOptionPane.showMessageDialog(overlayComponent, comboBox, "Select a promotion", JOptionPane.QUESTION_MESSAGE);
+
+ move = selectedMoves.get(comboBox.getSelectedIndex());
+ } else move = selectedMoves.get(0);
+
+ // Tell the game to execute the move
+ moveRequested = false;
+ game.onMove(NaturalPlayer.this, move);
+ }
+
+ // Discard the selection
overlayComponent.clearDots();
- moveRequested = false;
- game.onMove(NaturalPlayer.this, new Move(pos, dest, Type.UNKNOWN));
- pos = null;
+ selectedPiece = null;
+ possibleMoves = null;
}
}
diff --git a/src/dev/kske/chess/game/ai/MoveProcessor.java b/src/dev/kske/chess/game/ai/MoveProcessor.java
index 2c73ddd..112bc30 100644
--- a/src/dev/kske/chess/game/ai/MoveProcessor.java
+++ b/src/dev/kske/chess/game/ai/MoveProcessor.java
@@ -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: Chess
@@ -28,35 +34,35 @@ public class MoveProcessor implements Callable {
private Move bestMove;
- private static final Map positionScores;
+ private static final Map, 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 {
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;
}
diff --git a/src/dev/kske/chess/io/TextureUtil.java b/src/dev/kske/chess/io/TextureUtil.java
index 25ac288..79d251b 100644
--- a/src/dev/kske/chess/io/TextureUtil.java
+++ b/src/dev/kske/chess/io/TextureUtil.java
@@ -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);
}
diff --git a/src/dev/kske/chess/ui/OverlayComponent.java b/src/dev/kske/chess/ui/OverlayComponent.java
index b011281..cee5449 100644
--- a/src/dev/kske/chess/ui/OverlayComponent.java
+++ b/src/dev/kske/chess/ui/OverlayComponent.java
@@ -48,15 +48,15 @@ public class OverlayComponent extends JComponent {
// Draw an arrow representing the last move and mark its position and
// destination
if (arrow != null) {
- Point pos = new Point(arrow.pos.x * tileSize + tileSize / 2, arrow.pos.y * tileSize + tileSize / 2);
- Point dest = new Point(arrow.dest.x * tileSize + tileSize / 2, arrow.dest.y * tileSize + tileSize / 2);
+ Point pos = new Point(arrow.getPos().x * tileSize + tileSize / 2, arrow.getPos().y * tileSize + tileSize / 2);
+ Point dest = new Point(arrow.getDest().x * tileSize + tileSize / 2, arrow.getDest().y * tileSize + tileSize / 2);
Graphics2D g2d = (Graphics2D) g;
g2d.setStroke(new BasicStroke(3));
g2d.setColor(Color.yellow);
- g2d.drawRect(arrow.pos.x * tileSize, arrow.pos.y * tileSize, tileSize, tileSize);
- g2d.drawRect(arrow.dest.x * tileSize, arrow.dest.y * tileSize, tileSize, tileSize);
+ g2d.drawRect(arrow.getPos().x * tileSize, arrow.getPos().y * tileSize, tileSize, tileSize);
+ g2d.drawRect(arrow.getDest().x * tileSize, arrow.getDest().y * tileSize, tileSize, tileSize);
Shape arrowShape = createArrowShape(pos, dest);
g.setColor(new Color(255, 0, 0, 127));