Added castling, fixed some minor bugs
This commit is contained in:
parent
54e73f2b85
commit
40ef31dd1f
@ -50,7 +50,7 @@ public class Board implements Cloneable {
|
|||||||
new int[][] { new int[] { -2, -1, -1, -1, -1, -1, -1, 2 }, new int[] { -1, 0, 0, 0, 0, 0, 0, -1 },
|
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, 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, -2 } });
|
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(Type.PAWN,
|
||||||
new int[][] { new int[] { 0, 0, 0, 0, 0, 0, 0, 0 }, new int[] { 5, 5, 5, 5, 5, 5, 5, 5 },
|
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[] { 1, 1, 2, 3, 3, 2, 1, 1 }, new int[] { 0, 0, 1, 3, 3, 1, 0, 0 },
|
||||||
@ -75,6 +75,9 @@ public class Board implements Cloneable {
|
|||||||
Piece piece = getPos(move);
|
Piece piece = getPos(move);
|
||||||
if (piece == null || !piece.isValidMove(move)) return false;
|
if (piece == null || !piece.isValidMove(move)) return false;
|
||||||
else {
|
else {
|
||||||
|
// Set type after validation
|
||||||
|
if (move.type == Move.Type.UNKNOWN) move.type = Move.Type.NORMAL;
|
||||||
|
|
||||||
// Move piece
|
// Move piece
|
||||||
move(move);
|
move(move);
|
||||||
|
|
||||||
@ -104,13 +107,34 @@ public class Board implements Cloneable {
|
|||||||
// TODO: Select promotion
|
// TODO: Select promotion
|
||||||
setDest(move, new Queen(piece.getColor(), this));
|
setDest(move, new Queen(piece.getColor(), this));
|
||||||
break;
|
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
|
||||||
|
|
||||||
|
// Move the rook
|
||||||
|
setDest(rookMove, getPos(rookMove));
|
||||||
|
setPos(rookMove, null);
|
||||||
|
|
||||||
|
getDest(rookMove).incMoveCounter();
|
||||||
|
break;
|
||||||
case UNKNOWN:
|
case UNKNOWN:
|
||||||
System.err.printf("Unknown move %s found!%n", move);
|
System.err.printf("Move of unknown type %s found!%n", move);
|
||||||
case NORMAL:
|
case NORMAL:
|
||||||
setDest(move, piece);
|
setDest(move, piece);
|
||||||
setPos(move, null);
|
setPos(move, null);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
System.err.printf("Move %s of unimplemented type found!%n", move);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Increment move counter
|
||||||
|
getDest(move).incMoveCounter();
|
||||||
|
|
||||||
// Update the king's position if the moved piece is the king
|
// 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.getType() == Type.KING) kingPos.put(piece.getColor(), move.dest);
|
||||||
|
|
||||||
@ -127,19 +151,38 @@ public class Board implements Cloneable {
|
|||||||
Piece capturedPiece = loggedMove.capturedPiece;
|
Piece capturedPiece = loggedMove.capturedPiece;
|
||||||
|
|
||||||
switch (move.type) {
|
switch (move.type) {
|
||||||
case CASTLING:
|
|
||||||
case EN_PASSANT:
|
|
||||||
case PAWN_PROMOTION:
|
case PAWN_PROMOTION:
|
||||||
setPos(move, new Pawn(getDest(move).getColor(), this));
|
setPos(move, new Pawn(getDest(move).getColor(), this));
|
||||||
setDest(move, capturedPiece);
|
setDest(move, capturedPiece);
|
||||||
break;
|
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
|
||||||
|
|
||||||
|
// Move the rook
|
||||||
|
setDest(rookMove, getPos(rookMove));
|
||||||
|
setPos(rookMove, null);
|
||||||
|
|
||||||
|
getDest(rookMove).decMoveCounter();
|
||||||
|
break;
|
||||||
case UNKNOWN:
|
case UNKNOWN:
|
||||||
System.err.printf("Unknown move %s found!%n", move);
|
System.err.printf("Move of unknown type %s found!%n", move);
|
||||||
case NORMAL:
|
case NORMAL:
|
||||||
setPos(move, getDest(move));
|
setPos(move, getDest(move));
|
||||||
setDest(move, capturedPiece);
|
setDest(move, capturedPiece);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
System.err.printf("Move %s of unimplemented type found!%n", move);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Decrement move counter
|
||||||
|
getPos(move).decMoveCounter();
|
||||||
|
|
||||||
// Update the king's position if the moved piece is the king
|
// 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).getType() == Type.KING) kingPos.put(getPos(move).getColor(), move.pos);
|
||||||
|
|
||||||
|
@ -17,7 +17,26 @@ public class King extends Piece {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isValidMove(Move move) {
|
public boolean isValidMove(Move move) {
|
||||||
return move.xDist <= 1 && move.yDist <= 1 && isFreePath(move);
|
// Castling
|
||||||
|
if (getMoveCounter() == 0 && move.xDist == 2 && move.yDist == 0) {
|
||||||
|
|
||||||
|
// Kingside
|
||||||
|
if (board.getBoardArr()[7][move.pos.y] != null && board.getBoardArr()[7][move.pos.y].getType() == Type.ROOK
|
||||||
|
&& isFreePath(new Move(new Position(5, move.pos.y), new Position(7, move.pos.y)))) {
|
||||||
|
move.type = Move.Type.CASTLING;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Queenside
|
||||||
|
if (board.getBoardArr()[0][move.pos.y] != null && board.getBoardArr()[0][move.pos.y].getType() == Type.ROOK
|
||||||
|
&& isFreePath(new Move(new Position(1, move.pos.y), new Position(4, move.pos.y)))) {
|
||||||
|
move.type = Move.Type.CASTLING;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return move.xDist <= 1 && move.yDist <= 1 && checkDestination(move);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -29,9 +48,33 @@ public class King extends Piece {
|
|||||||
Move move = new Move(pos, new Position(i, j));
|
Move move = new Move(pos, new Position(i, j));
|
||||||
if (board.getDest(move) == null || board.getDest(move).getColor() != getColor()) moves.add(move);
|
if (board.getDest(move) == null || board.getDest(move).getColor() != getColor()) moves.add(move);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Castling
|
||||||
|
// TODO: Check attacked squares in between
|
||||||
|
// TODO: Castling out of check?
|
||||||
|
if (getMoveCounter() == 0) {
|
||||||
|
|
||||||
|
// Kingside
|
||||||
|
if (board.getBoardArr()[7][pos.y] != null && board.getBoardArr()[7][pos.y].getType() == Type.ROOK
|
||||||
|
&& isFreePath(new Move(new Position(5, pos.y), new Position(7, pos.y))))
|
||||||
|
moves.add(new Move(pos, new Position(6, pos.y), Move.Type.CASTLING));
|
||||||
|
|
||||||
|
// Queenside
|
||||||
|
if (board.getBoardArr()[0][pos.y] != null && board.getBoardArr()[0][pos.y].getType() == Type.ROOK
|
||||||
|
&& isFreePath(new Move(new Position(1, pos.y), new Position(4, pos.y))))
|
||||||
|
moves.add(new Move(pos, new Position(2, pos.y), Move.Type.CASTLING));
|
||||||
|
}
|
||||||
|
|
||||||
return moves;
|
return moves;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isFreePath(Move move) {
|
||||||
|
for (int i = move.pos.x, j = move.pos.y; i != move.dest.x || j != move.dest.y; i += move.xSign, j += move.ySign)
|
||||||
|
if (board.getBoardArr()[i][j] != null) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Type getType() { return Type.KING; }
|
public Type getType() { return Type.KING; }
|
||||||
}
|
}
|
||||||
|
@ -11,8 +11,9 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public abstract class Piece implements Cloneable {
|
public abstract class Piece implements Cloneable {
|
||||||
|
|
||||||
protected Color color;
|
private final Color color;
|
||||||
protected Board board;
|
protected Board board;
|
||||||
|
private int moveCounter;
|
||||||
|
|
||||||
public Piece(Color color, Board board) {
|
public Piece(Color color, Board board) {
|
||||||
this.color = color;
|
this.color = color;
|
||||||
@ -24,8 +25,7 @@ public abstract class Piece implements Cloneable {
|
|||||||
for (Iterator<Move> iterator = moves.iterator(); iterator.hasNext();) {
|
for (Iterator<Move> iterator = moves.iterator(); iterator.hasNext();) {
|
||||||
Move move = iterator.next();
|
Move move = iterator.next();
|
||||||
board.move(move);
|
board.move(move);
|
||||||
if (board.checkCheck(getColor()))
|
if (board.checkCheck(getColor())) iterator.remove();
|
||||||
iterator.remove();
|
|
||||||
board.revert();
|
board.revert();
|
||||||
}
|
}
|
||||||
return moves;
|
return moves;
|
||||||
@ -66,6 +66,16 @@ public abstract class Piece implements Cloneable {
|
|||||||
|
|
||||||
public Color getColor() { return color; }
|
public Color getColor() { return color; }
|
||||||
|
|
||||||
|
public int getMoveCounter() { return moveCounter; }
|
||||||
|
|
||||||
|
public void incMoveCounter() {
|
||||||
|
++moveCounter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void decMoveCounter() {
|
||||||
|
--moveCounter;
|
||||||
|
}
|
||||||
|
|
||||||
public static enum Type {
|
public static enum Type {
|
||||||
KING, QUEEN, ROOK, KNIGHT, BISHOP, PAWN
|
KING, QUEEN, ROOK, KNIGHT, BISHOP, PAWN
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import java.util.stream.Collectors;
|
|||||||
|
|
||||||
import dev.kske.chess.board.Board;
|
import dev.kske.chess.board.Board;
|
||||||
import dev.kske.chess.board.Move;
|
import dev.kske.chess.board.Move;
|
||||||
|
import dev.kske.chess.board.Move.Type;
|
||||||
import dev.kske.chess.board.Piece.Color;
|
import dev.kske.chess.board.Piece.Color;
|
||||||
import dev.kske.chess.board.Position;
|
import dev.kske.chess.board.Position;
|
||||||
import dev.kske.chess.ui.OverlayComponent;
|
import dev.kske.chess.ui.OverlayComponent;
|
||||||
@ -49,7 +50,7 @@ public class NaturalPlayer extends Player {
|
|||||||
|
|
||||||
overlayComponent.clearDots();
|
overlayComponent.clearDots();
|
||||||
moveRequested = false;
|
moveRequested = false;
|
||||||
game.onMove(NaturalPlayer.this, new Move(pos, dest));
|
game.onMove(NaturalPlayer.this, new Move(pos, dest, Type.UNKNOWN));
|
||||||
pos = null;
|
pos = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,5 +79,7 @@ public class GameModeDialog extends JDialog {
|
|||||||
dispose();
|
dispose();
|
||||||
});
|
});
|
||||||
getContentPane().add(btnAI2);
|
getContentPane().add(btnAI2);
|
||||||
|
|
||||||
|
setLocationRelativeTo(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,6 +64,7 @@ public class MainWindow {
|
|||||||
btnRestart.addActionListener((evt) -> System.err.println("Resetting not implemented!"));
|
btnRestart.addActionListener((evt) -> System.err.println("Resetting not implemented!"));
|
||||||
toolPanel.add(btnRestart);
|
toolPanel.add(btnRestart);
|
||||||
mframe.pack();
|
mframe.pack();
|
||||||
|
mframe.setLocationRelativeTo(null);
|
||||||
|
|
||||||
// Display dialog for game mode selection
|
// Display dialog for game mode selection
|
||||||
new GameModeDialog(boardPane).setVisible(true);
|
new GameModeDialog(boardPane).setVisible(true);
|
||||||
|
Reference in New Issue
Block a user