From e50739c8342bebc7651b077d8330b94bf86b53ad Mon Sep 17 00:00:00 2001 From: jefei Date: Sat, 17 May 2025 14:10:28 +0200 Subject: [PATCH] Check and Checkmate Detection but not fully optimized --- src/backend/Board.java | 92 +++++++++++++++++++++++ src/backend/Game.java | 3 + src/windowInterface/JPanelChessBoard.java | 17 +++++ src/windowInterface/MyInterface.java | 1 + 4 files changed, 113 insertions(+) diff --git a/src/backend/Board.java b/src/backend/Board.java index 648d84a..60b4055 100644 --- a/src/backend/Board.java +++ b/src/backend/Board.java @@ -4,6 +4,9 @@ import java.util.ArrayList; import java.util.Stack; public class Board { + private int checkedKingX = -1; + private int checkedKingY = -1; + private boolean checkmateFlag = false; private Piece lastDoubleStepPawn = null; private int width; private int height; @@ -23,6 +26,9 @@ private boolean whiteQueensideRookMoved = false; private boolean blackKingsideRookMoved = false; private boolean blackQueensideRookMoved = false; +public int getCheckedKingX() { return checkedKingX; } +public int getCheckedKingY() { return checkedKingY; } +public boolean isCheckmateFlag() { return checkmateFlag; } public String[] toFileRep() { String[] lines = new String[height + 1]; @@ -309,9 +315,30 @@ public void userTouch(int x, int y) { turnWhite = !turnWhite; hasSelection = false; System.out.println(this); + // 🧠 CHECK & CHECKMATE logic + checkedKingX = -1; + checkedKingY = -1; + checkmateFlag = false; + + boolean opponentInCheck = isInCheck(turnWhite); + if (opponentInCheck) { + Piece king = getKing(turnWhite); + if (king != null) { + checkedKingX = king.getX(); + checkedKingY = king.getY(); + System.out.println("⚠️ " + (turnWhite ? "White" : "Black") + " king is in check!"); + } + } + + if (isCheckmate(turnWhite)) { + checkmateFlag = true; + System.out.println("♟️ " + (!turnWhite ? "White" : "Black") + " wins by checkmate!"); + } + } } + public boolean isSelected(int x, int y) { // return true if the exact square is currently picked up return hasSelection && selectedX == x && selectedY == y; @@ -651,4 +678,69 @@ public void selectPiece(int x, int y) { selectedX = x; selectedY = y; } +public boolean isInCheck(boolean white) { + // Step 1: Locate the king + Piece king = null; + for (Piece p : Pieces) { + if (p.getType() == PieceType.King && p.isWhite() == white) { + king = p; + break; + } + } + if (king == null) return false; + + int kingX = king.getX(); + int kingY = king.getY(); + + // Step 2: Check all enemy pieces to see if they can hit king + for (Piece p : Pieces) { + if (p.isWhite() != white) { + Board temp = new Board(this); + temp.selectPiece(p.getX(), p.getY()); + temp.hasSelection = true; + + for (int tx = 0; tx < width; tx++) { + for (int ty = 0; ty < height; ty++) { + if (temp.isHighlighted(tx, ty) && tx == kingX && ty == kingY) { + return true; + } + } + } + } + } + + return false; } + + +public boolean isCheckmate(boolean white) { + if (!isInCheck(white)) return false; + + for (Piece p : Pieces) { + if (p.isWhite() == white) { + Board copy = new Board(this); + copy.selectPiece(p.getX(), p.getY()); + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + if (copy.isHighlighted(x, y)) { + Board trial = new Board(this); + trial.selectPiece(p.getX(), p.getY()); + trial.userTouch(x, y); + if (!trial.isInCheck(white)) { + return false; + } + } + } + } + } + } + return true; +} +public Piece getKing(boolean white) { + for (Piece p : Pieces) { + if (p.getType() == PieceType.King && p.isWhite() == white) return p; + } + return null; +} + +} \ No newline at end of file diff --git a/src/backend/Game.java b/src/backend/Game.java index 41ca541..89e8621 100644 --- a/src/backend/Game.java +++ b/src/backend/Game.java @@ -114,5 +114,8 @@ public class Game extends Thread { public void toggleAI(boolean isWhite) { this.activationAIFlags[isWhite?1:0] = !this.activationAIFlags[isWhite?1:0]; } + public Board getBoard() { + return this.board; + } } diff --git a/src/windowInterface/JPanelChessBoard.java b/src/windowInterface/JPanelChessBoard.java index 1368e37..2e6e376 100644 --- a/src/windowInterface/JPanelChessBoard.java +++ b/src/windowInterface/JPanelChessBoard.java @@ -112,6 +112,23 @@ public class JPanelChessBoard extends JPanel { if(isHighlight) { g.setColor(Color.yellow); } + // 🔴 Highlight the checked/checkmated king + if (myGame != null) { + backend.Board board = myGame.getBoard(); + int checkX = board.getCheckedKingX(); + int checkY = board.getCheckedKingY(); + + if (checkX != -1 && checkY != -1) { + g.setColor(board.isCheckmateFlag() ? Color.RED : Color.ORANGE); + g.fillRect( + Math.round(checkX * cellWidth), + Math.round(checkY * cellHeight), + Math.round(cellWidth), + Math.round(cellHeight) + ); + } + } + if((x+y)%2==1 || isSelect || isHighlight) { g.fillRect( Math.round(x*cellWidth), diff --git a/src/windowInterface/MyInterface.java b/src/windowInterface/MyInterface.java index 513842a..6328f0a 100644 --- a/src/windowInterface/MyInterface.java +++ b/src/windowInterface/MyInterface.java @@ -162,6 +162,7 @@ public class MyInterface extends JFrame { public void clicButtonStart() { this.instantiateSimu(); game.setDefaultSetup(); + } public void clickButtonAdder() {