From 9e031f4000e1349cc8e1337d41540af8d84e9875 Mon Sep 17 00:00:00 2001 From: kske Date: Sat, 6 Jul 2019 12:42:21 +0200 Subject: [PATCH] Fixed bugs in move generation, prepared checkmate recognition --- src/dev/kske/chess/Board.java | 25 ++++++++++++++----------- src/dev/kske/chess/BoardPanel.java | 3 +++ src/dev/kske/chess/event/GameEvent.java | 2 +- src/dev/kske/chess/piece/King.java | 5 +---- src/dev/kske/chess/piece/Knight.java | 2 +- src/dev/kske/chess/piece/Pawn.java | 2 +- src/dev/kske/chess/piece/Piece.java | 3 ++- 7 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/dev/kske/chess/Board.java b/src/dev/kske/chess/Board.java index 494ac72..9fa33b9 100644 --- a/src/dev/kske/chess/Board.java +++ b/src/dev/kske/chess/Board.java @@ -55,15 +55,15 @@ public class Board { Piece capturePiece = move(move); // Revert move if it caused a check for its team - if (checkCheck(piece.getColor())) { + if (checkCheck(piece.getColor()) != GameEventType.NONE) { revert(move, capturePiece); return false; } - // TODO: detecting checkmate - // Check for check on the opposite team - Color oppositeColor = piece.getColor() == Color.WHITE ? Color.BLACK : Color.WHITE; - if (checkCheck(oppositeColor)) notifyListeners(new GameEvent(this, GameEventType.CHECK, oppositeColor)); + // Detect check on the opposite team + Color oppositeColor = piece.getColor().opposite(); + GameEventType eventType = checkCheck(oppositeColor); + if (eventType != GameEventType.NONE) notifyListeners(new GameEvent(this, eventType, oppositeColor)); return true; } @@ -121,13 +121,16 @@ public class Board { return get(pos).getMoves(pos); } - public boolean checkCheck(Color color) { + public GameEventType checkCheck(Color color) { for (int i = 0; i < 8; i++) - for (int j = 0; j < 8; j++) - if (boardArr[i][j] != null && boardArr[i][j].getColor() != color - && boardArr[i][j].isValidMove(new Move(new Position(i, j), kingPos.get(color)))) - return true; - return false; + for (int j = 0; j < 8; j++) { + Position pos = new Position(i, j); + if (get(pos) != null && get(pos).getColor() != color + && get(pos).isValidMove(new Move(pos, kingPos.get(color)))) + return GameEventType.CHECK; + //return getMoves(kingPos.get(color)).isEmpty() ? GameEventType.CHECKMATE : GameEventType.CHECK; + } + return GameEventType.NONE; } public void registerGameEventListener(GameEventListener listener) { diff --git a/src/dev/kske/chess/BoardPanel.java b/src/dev/kske/chess/BoardPanel.java index f9fd49f..d61e08a 100644 --- a/src/dev/kske/chess/BoardPanel.java +++ b/src/dev/kske/chess/BoardPanel.java @@ -123,6 +123,9 @@ public class BoardPanel extends JPanel implements GameEventListener { case CHECK: JOptionPane.showMessageDialog(this, evt.getColor().toString() + " in check!"); break; + case CHECKMATE: + JOptionPane.showMessageDialog(this, evt.getColor().toString() + " in checkmate!"); + break; } } diff --git a/src/dev/kske/chess/event/GameEvent.java b/src/dev/kske/chess/event/GameEvent.java index 21eb20d..516ab79 100644 --- a/src/dev/kske/chess/event/GameEvent.java +++ b/src/dev/kske/chess/event/GameEvent.java @@ -33,6 +33,6 @@ public class GameEvent extends EventObject { public Color getColor() { return color; } public static enum GameEventType { - CHECK, CHECKMATE + CHECK, CHECKMATE, STALEMENT, NONE; } } diff --git a/src/dev/kske/chess/piece/King.java b/src/dev/kske/chess/piece/King.java index 18428a9..7c1493e 100644 --- a/src/dev/kske/chess/piece/King.java +++ b/src/dev/kske/chess/piece/King.java @@ -31,10 +31,7 @@ public class King extends Piece { for (int j = Math.max(0, pos.y - 1); j < Math.min(8, pos.y + 2); j++) if (i != pos.x || j != pos.y) { 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) break; - } + if (board.getDest(move) == null || board.getDest(move).getColor() != getColor()) moves.add(move); } return moves; } diff --git a/src/dev/kske/chess/piece/Knight.java b/src/dev/kske/chess/piece/Knight.java index ed94f36..b14c404 100644 --- a/src/dev/kske/chess/piece/Knight.java +++ b/src/dev/kske/chess/piece/Knight.java @@ -21,7 +21,7 @@ public class Knight extends Piece { @Override public boolean isValidMove(Move move) { - return Math.abs(move.xDist - move.yDist) == 1 && move.xDist != 0 && move.yDist != 0 && isFreePath(move); + return Math.abs(move.xDist - move.yDist) == 1 && (move.xDist == 1 || move.yDist == 1) && isFreePath(move); } private void checkAndInsertMove(List moves, Position pos, int offsetX, int offsetY) { diff --git a/src/dev/kske/chess/piece/Pawn.java b/src/dev/kske/chess/piece/Pawn.java index 43b6c8e..9201f06 100644 --- a/src/dev/kske/chess/piece/Pawn.java +++ b/src/dev/kske/chess/piece/Pawn.java @@ -34,7 +34,7 @@ public class Pawn extends Piece { protected boolean isFreePath(Move move) { // Two steps forward if (move.yDist == 2) - return board.getBoardArr()[move.pos.x][move.dest.y - move.ySign] == null && checkDestination(move); + return board.getBoardArr()[move.pos.x][move.dest.y - move.ySign] == null && board.getDest(move) == null; // One step forward else if (move.xDist == 0) return board.getDest(move) == null; // Capture move diff --git a/src/dev/kske/chess/piece/Piece.java b/src/dev/kske/chess/piece/Piece.java index 6aacc4c..7e6bcc5 100644 --- a/src/dev/kske/chess/piece/Piece.java +++ b/src/dev/kske/chess/piece/Piece.java @@ -6,6 +6,7 @@ import java.util.List; import dev.kske.chess.Board; import dev.kske.chess.Move; import dev.kske.chess.Position; +import dev.kske.chess.event.GameEvent.GameEventType; /** * Project: Chess
@@ -28,7 +29,7 @@ public abstract class Piece { for (Iterator iterator = moves.iterator(); iterator.hasNext();) { Move move = iterator.next(); Piece capturePiece = board.move(move); - if (board.checkCheck(getColor())) + if (board.checkCheck(getColor()) != GameEventType.NONE) iterator.remove(); board.revert(move, capturePiece); }