diff --git a/OOP_1A2_Project/bin/backend/Board.class b/OOP_1A2_Project/bin/backend/Board.class index adae89b..2d54873 100644 Binary files a/OOP_1A2_Project/bin/backend/Board.class and b/OOP_1A2_Project/bin/backend/Board.class differ diff --git a/OOP_1A2_Project/bin/backend/Move.class b/OOP_1A2_Project/bin/backend/Move.class index ca34db1..78e9639 100644 Binary files a/OOP_1A2_Project/bin/backend/Move.class and b/OOP_1A2_Project/bin/backend/Move.class differ diff --git a/OOP_1A2_Project/src/backend/Board.java b/OOP_1A2_Project/src/backend/Board.java index 5d43dda..42ad2c5 100644 --- a/OOP_1A2_Project/src/backend/Board.java +++ b/OOP_1A2_Project/src/backend/Board.java @@ -21,6 +21,7 @@ public class Board { private Move lastMove = null; private Enpassant enpassantHandler; + private CastlingHandler castlingHandler; public Board(int colNum, int lineNum) { this.width = colNum; @@ -33,6 +34,7 @@ public class Board { this.sound = new Sound(); this.lastMove = null; this.enpassantHandler = new Enpassant(this); + this.castlingHandler = new CastlingHandler(this); } public int getWidth() { @@ -186,17 +188,24 @@ public class Board { if (isHighlighted(x, y)) { saveCurrentState(); - Move move = new Move(selectedX, selectedY, x, y, this); - if (move.isValid()) { - move.execute(); - this.lastMove = move; - + CastlingHandler.CastlingMove castlingMove = castlingHandler.getCastlingMove(selectedX, selectedY, x, y); + if (castlingMove != null && castlingHandler.isCastlingValid(castlingMove)) { + castlingHandler.executeCastling(castlingMove); + this.lastMove = new Move(selectedX, selectedY, x, y, this); sound.playMoveSound(); - - if (move.putsOpponentInCheckmate()) { - System.out.println("Checkmate! " + (isWhiteTurn ? "Black" : "White") + " wins!"); - } else if (move.putsOpponentInCheck()) { - System.out.println("Check!"); + } else { + Move move = new Move(selectedX, selectedY, x, y, this); + if (move.isValid()) { + move.execute(); + this.lastMove = move; + + sound.playMoveSound(); + + if (move.putsOpponentInCheckmate()) { + System.out.println("Checkmate! " + (isWhiteTurn ? "Black" : "White") + " wins!"); + } else if (move.putsOpponentInCheck()) { + System.out.println("Check!"); + } } } @@ -252,6 +261,7 @@ public class Board { this.sound = new Sound(); this.lastMove = null; this.enpassantHandler = new Enpassant(this); + this.castlingHandler = new CastlingHandler(this); for (int y = 0; y < height; y++) { if (y >= array.length) { @@ -334,6 +344,7 @@ public class Board { this.sound = new Sound(); this.enpassantHandler = new Enpassant(this); + this.castlingHandler = new CastlingHandler(this); } private void clearHighlights() { @@ -367,6 +378,13 @@ public class Board { } } + if (selectedPiece.getType() == PieceType.King) { + List castlingMoves = castlingHandler.getCastlingPositions(selectedPiece); + for (CastlingHandler.Position castlingPos : castlingMoves) { + convertedMoves.add(new Position(castlingPos.x, castlingPos.y)); + } + } + highlightedPositions.clear(); highlightedPositions.addAll(convertedMoves); } @@ -439,6 +457,14 @@ public class Board { return enpassantHandler; } + public CastlingHandler getCastlingHandler() { + return castlingHandler; + } + + public List getBoardHistory() { + return new ArrayList<>(boardHistory); + } + public class Position { public int x; public int y; diff --git a/OOP_1A2_Project/src/backend/CastlingHandler.java b/OOP_1A2_Project/src/backend/CastlingHandler.java index be80eae..49657cb 100644 --- a/OOP_1A2_Project/src/backend/CastlingHandler.java +++ b/OOP_1A2_Project/src/backend/CastlingHandler.java @@ -11,9 +11,9 @@ public class CastlingHandler { } public class CastlingMove { - public final int kingFromX, kingFromY, kingToX, kingToY; - public final int rookFromX, rookFromY, rookToX, rookToY; - public final boolean isKingside; + public int kingFromX, kingFromY, kingToX, kingToY; + public int rookFromX, rookFromY, rookToX, rookToY; + public boolean isKingside; public CastlingMove(int kingFromX, int kingFromY, int kingToX, int kingToY, int rookFromX, int rookFromY, int rookToX, int rookToY, @@ -28,6 +28,12 @@ public class CastlingHandler { this.rookToY = rookToY; this.isKingside = isKingside; } + + public String toString() { + return (isKingside ? "Kingside" : "Queenside") + " Castling: King(" + + kingFromX + "," + kingFromY + ")->(" + kingToX + "," + kingToY + + "), Rook(" + rookFromX + "," + rookFromY + ")->(" + rookToX + "," + rookToY + ")"; + } } public class Position { @@ -45,15 +51,19 @@ public class CastlingHandler { Position position = (Position) obj; return x == position.x && y == position.y; } + + public int hashCode() { + return 31 * x + y; + } + + public String toString() { + return "(" + x + ", " + y + ")"; + } } - /** - * Checks if castling is possible and returns the castling move details - */ public CastlingMove getCastlingMove(int fromX, int fromY, int toX, int toY) { Piece piece = board.getPieceAt(fromX, fromY); - // Must be a king if (piece == null || piece.getType() != PieceType.King) { return null; } @@ -61,12 +71,10 @@ public class CastlingHandler { boolean isWhite = piece.isWhite(); int kingRow = isWhite ? 7 : 0; - // King must be on its starting position if (fromY != kingRow || fromX != 4) { return null; } - // Check if this is a castling move (king moves 2 squares horizontally) if (fromY != toY || Math.abs(toX - fromX) != 2) { return null; } @@ -80,21 +88,16 @@ public class CastlingHandler { isKingside); } - /** - * Validates if castling is legal - */ public boolean isCastlingValid(CastlingMove castling) { if (castling == null) return false; Piece king = board.getPieceAt(castling.kingFromX, castling.kingFromY); Piece rook = board.getPieceAt(castling.rookFromX, castling.rookFromY); - // Verify pieces exist and are correct type/color if (king == null || king.getType() != PieceType.King) return false; if (rook == null || rook.getType() != PieceType.Rook) return false; if (king.isWhite() != rook.isWhite()) return false; - // Check if king or rook have moved (simplified - assumes starting positions) boolean isWhite = king.isWhite(); int expectedKingRow = isWhite ? 7 : 0; if (castling.kingFromY != expectedKingRow || castling.kingFromX != 4) return false; @@ -102,7 +105,62 @@ public class CastlingHandler { if (castling.isKingside && castling.rookFromX != 7) return false; if (!castling.isKingside && castling.rookFromX != 0) return false; - // Check path is clear between king and rook + if (hasKingOrRookMoved(isWhite, castling.isKingside)) { + return false; + } + + if (!isPathClear(castling)) { + return false; + } + + if (isKingInCheck(isWhite)) { + return false; + } + + return !wouldKingPassThroughCheck(castling, isWhite); + } + + private boolean hasKingOrRookMoved(boolean isWhite, boolean isKingside) { + List history = board.getBoardHistory(); + if (history.isEmpty()) return false; + + int kingRow = isWhite ? 7 : 0; + int rookX = isKingside ? 7 : 0; + + for (Board previousBoard : history) { + Piece kingInHistory = previousBoard.getPieceAt(4, kingRow); + Piece rookInHistory = previousBoard.getPieceAt(rookX, kingRow); + + if (kingInHistory == null || kingInHistory.getType() != PieceType.King || + kingInHistory.isWhite() != isWhite) { + return true; + } + + if (rookInHistory == null || rookInHistory.getType() != PieceType.Rook || + rookInHistory.isWhite() != isWhite) { + return true; + } + } + + Move lastMove = board.getLastMove(); + if (lastMove != null) { + Piece lastMovedPiece = board.getPieceAt(lastMove.getToX(), lastMove.getToY()); + if (lastMovedPiece != null) { + if (lastMovedPiece.getType() == PieceType.King && lastMovedPiece.isWhite() == isWhite) { + return true; + } + if (lastMovedPiece.getType() == PieceType.Rook && lastMovedPiece.isWhite() == isWhite) { + if ((isKingside && lastMove.getFromX() == 7) || (!isKingside && lastMove.getFromX() == 0)) { + return true; + } + } + } + } + + return false; + } + + private boolean isPathClear(CastlingMove castling) { int startX = Math.min(castling.kingFromX, castling.rookFromX) + 1; int endX = Math.max(castling.kingFromX, castling.rookFromX) - 1; @@ -111,49 +169,42 @@ public class CastlingHandler { return false; } } + return true; + } + + private boolean wouldKingPassThroughCheck(CastlingMove castling, boolean isWhite) { + int step = castling.isKingside ? 1 : -1; - // Check that king is not in check - if (isKingInCheck(isWhite)) { - return false; - } - - // Check that king doesn't pass through check - for (int x = castling.kingFromX; x != castling.kingToX + (castling.isKingside ? 1 : -1); - x += castling.isKingside ? 1 : -1) { + for (int x = castling.kingFromX; x != castling.kingToX + step; x += step) { + if (x == castling.kingFromX) continue; - // Create temporary board with king at this position Board tempBoard = new Board(board); tempBoard.removePiece(castling.kingFromX, castling.kingFromY); tempBoard.setPiece(isWhite, PieceType.King, x, castling.kingFromY); CastlingHandler tempHandler = new CastlingHandler(tempBoard); if (tempHandler.isKingInCheck(isWhite)) { - return false; + return true; } } - - return true; + return false; } - /** - * Executes the castling move on the board - */ public void executeCastling(CastlingMove castling) { + if (!isCastlingValid(castling)) { + throw new IllegalArgumentException("Invalid castling move"); + } + Piece king = board.getPieceAt(castling.kingFromX, castling.kingFromY); Piece rook = board.getPieceAt(castling.rookFromX, castling.rookFromY); - // Move the king board.removePiece(castling.kingFromX, castling.kingFromY); - board.setPiece(king.isWhite(), king.getType(), castling.kingToX, castling.kingToY); - - // Move the rook board.removePiece(castling.rookFromX, castling.rookFromY); + + board.setPiece(king.isWhite(), king.getType(), castling.kingToX, castling.kingToY); board.setPiece(rook.isWhite(), rook.getType(), castling.rookToX, castling.rookToY); } - /** - * Gets all possible castling moves for a king - */ public List getCastlingPositions(Piece king) { List castlingMoves = new ArrayList<>(); @@ -164,18 +215,15 @@ public class CastlingHandler { boolean isWhite = king.isWhite(); int kingRow = isWhite ? 7 : 0; - // King must be on starting position if (king.getX() != 4 || king.getY() != kingRow) { return castlingMoves; } - // Check kingside castling CastlingMove kingsideCastling = getCastlingMove(4, kingRow, 6, kingRow); if (isCastlingValid(kingsideCastling)) { castlingMoves.add(new Position(6, kingRow)); } - // Check queenside castling CastlingMove queensideCastling = getCastlingMove(4, kingRow, 2, kingRow); if (isCastlingValid(queensideCastling)) { castlingMoves.add(new Position(2, kingRow)); @@ -184,8 +232,41 @@ public class CastlingHandler { return castlingMoves; } + public List getAllCastlingMoves(boolean isWhite) { + List castlingMoves = new ArrayList<>(); + + int kingRow = isWhite ? 7 : 0; + Piece king = board.getPieceAt(4, kingRow); + + if (king != null && king.getType() == PieceType.King && king.isWhite() == isWhite) { + castlingMoves.addAll(getCastlingPositions(king)); + } + + return castlingMoves; + } + + public boolean isCastlingMove(int fromX, int fromY, int toX, int toY) { + return getCastlingMove(fromX, fromY, toX, toY) != null; + } + + public boolean wouldCastlingPutKingInCheck(CastlingMove castling) { + if (castling == null) return true; + + Board tempBoard = new Board(board); + CastlingHandler tempHandler = new CastlingHandler(tempBoard); + + try { + Piece originalKing = board.getPieceAt(castling.kingFromX, castling.kingFromY); + if (originalKing == null) return true; + + tempHandler.executeCastling(castling); + return tempHandler.isKingInCheck(originalKing.isWhite()); + } catch (Exception e) { + return true; + } + } + public boolean isKingInCheck(boolean isWhiteKing) { - // Find the king's position Piece king = null; for (Piece p : board.getPieces()) { if (p.getType() == PieceType.King && p.isWhite() == isWhiteKing) { @@ -200,14 +281,11 @@ public class CastlingHandler { } private boolean checkIfKingUnderAttack(boolean isWhiteKing, Piece king) { - // Check if any opponent piece can attack the king for (Piece p : board.getPieces()) { - if (p.isWhite() == isWhiteKing) continue; // Skip pieces of same color + if (p.isWhite() == isWhiteKing) continue; - // Get raw moves without check validation List attackMoves = getValidDestinations(p); - // If any piece can move to king's position, king is in check for (Position pos : attackMoves) { if (pos.x == king.getX() && pos.y == king.getY()) { return true; @@ -223,7 +301,7 @@ public class CastlingHandler { switch (piece.getType()) { case Pawn: - addPawnMoves(moves, piece); + addPawnAttackMoves(moves, piece); break; case Rook: addRookMoves(moves, piece); @@ -246,15 +324,14 @@ public class CastlingHandler { return moves; } - private void addPawnMoves(List validMoves, Piece piece) { + private void addPawnAttackMoves(List validMoves, Piece piece) { int x = piece.getX(); int y = piece.getY(); boolean isWhite = piece.isWhite(); int direction = isWhite ? -1 : 1; - - // Diagonal captures only (for attack patterns) int newY = y + direction; + if (newY >= 0 && newY < board.getHeight()) { for (int dx = -1; dx <= 1; dx += 2) { int newX = x + dx; @@ -283,7 +360,7 @@ public class CastlingHandler { Piece targetPiece = board.getPieceAt(newX, newY); if (targetPiece != null) { - break; // Cannot move beyond a piece + break; } newX += dx; @@ -329,7 +406,7 @@ public class CastlingHandler { Piece targetPiece = board.getPieceAt(newX, newY); if (targetPiece != null) { - break; // Cannot move beyond a piece + break; } newX += dx; diff --git a/OOP_1A2_Project/src/backend/Move.java b/OOP_1A2_Project/src/backend/Move.java index a13797e..6a242c0 100644 --- a/OOP_1A2_Project/src/backend/Move.java +++ b/OOP_1A2_Project/src/backend/Move.java @@ -12,7 +12,9 @@ public class Move { private Piece capturedPiece; private Board board; private boolean isEnPassant = false; + private boolean isCastling = false; private Piece enPassantCapturedPiece = null; + private CastlingHandler.CastlingMove castlingMove = null; public Move(int fromX, int fromY, int toX, int toY, Board board) { this.fromX = fromX; @@ -23,17 +25,15 @@ public class Move { this.movingPiece = board.getPieceAt(fromX, fromY); this.capturedPiece = board.getPieceAt(toX, toY); - // Check if this is an en passant move checkEnPassant(); + checkCastling(); } private void checkEnPassant() { if (movingPiece != null && movingPiece.getType() == PieceType.Pawn) { - // Utiliser la classe Enpassant pour vérifier Enpassant enpassantHandler = board.getEnpassantHandler(); if (enpassantHandler.isEnPassantValid(fromX, fromY, toX, toY)) { isEnPassant = true; - // Obtenir la position du pion capturé Enpassant.Position capturedPos = enpassantHandler.getCapturedPawnPosition(toX, toY); if (capturedPos != null) { enPassantCapturedPiece = board.getPieceAt(capturedPos.x, capturedPos.y); @@ -41,103 +41,119 @@ public class Move { } } } + + private void checkCastling() { + if (movingPiece != null && movingPiece.getType() == PieceType.King) { + CastlingHandler castlingHandler = board.getCastlingHandler(); + castlingMove = castlingHandler.getCastlingMove(fromX, fromY, toX, toY); + if (castlingMove != null && castlingHandler.isCastlingValid(castlingMove)) { + isCastling = true; + } + } + } public boolean isValid() { - // Check if the moving piece exists if (movingPiece == null) { return false; } - // Check if the move is in the list of valid moves for this piece + if (isCastling) { + CastlingHandler castlingHandler = board.getCastlingHandler(); + return castlingHandler.isCastlingValid(castlingMove); + } + List validMoves = getValidDestinations(movingPiece, board); return validMoves.contains(new Position(toX, toY)); } public void execute() { - if (isEnPassant) { - // Utiliser la classe Enpassant pour l'exécution + if (isCastling) { + CastlingHandler castlingHandler = board.getCastlingHandler(); + castlingHandler.executeCastling(castlingMove); + } else if (isEnPassant) { Enpassant enpassantHandler = board.getEnpassantHandler(); enpassantHandler.executeEnPassant(fromX, fromY, toX, toY); } else { - // Normal move or capture if (capturedPiece != null) { board.removePiece(toX, toY); } - // Move the piece board.removePiece(fromX, fromY); board.setPiece(movingPiece.isWhite(), movingPiece.getType(), toX, toY); } - // Advance turn board.advanceTurn(); } public boolean putsOwnKingInCheck() { - // Create a temporary board to simulate the move Board tempBoard = new Board(board); - // Find the piece in the temp board Piece tempPiece = tempBoard.getPieceAt(fromX, fromY); - if (tempPiece == null) return true; // Safety check + if (tempPiece == null) return true; - if (isEnPassant) { - // Simulate en passant on temp board + if (isCastling) { + CastlingHandler tempCastlingHandler = tempBoard.getCastlingHandler(); + CastlingHandler.CastlingMove tempCastlingMove = tempCastlingHandler.getCastlingMove(fromX, fromY, toX, toY); + if (tempCastlingMove != null) { + return tempCastlingHandler.wouldCastlingPutKingInCheck(tempCastlingMove); + } + return true; + } else if (isEnPassant) { Enpassant tempEnpassantHandler = tempBoard.getEnpassantHandler(); tempEnpassantHandler.executeEnPassant(fromX, fromY, toX, toY); } else { - // Normal move simulation tempBoard.removePiece(toX, toY); tempBoard.removePiece(fromX, fromY); tempBoard.setPiece(tempPiece.isWhite(), tempPiece.getType(), toX, toY); } - // Check if king is in check after move return isKingInCheck(tempBoard, tempPiece.isWhite()); } public boolean putsOpponentInCheck() { - // Create a temporary board to simulate the move Board tempBoard = new Board(board); - // Find the piece in the temp board Piece tempPiece = tempBoard.getPieceAt(fromX, fromY); - if (tempPiece == null) return false; // Safety check + if (tempPiece == null) return false; - if (isEnPassant) { - // Simulate en passant on temp board + if (isCastling) { + CastlingHandler tempCastlingHandler = tempBoard.getCastlingHandler(); + CastlingHandler.CastlingMove tempCastlingMove = tempCastlingHandler.getCastlingMove(fromX, fromY, toX, toY); + if (tempCastlingMove != null) { + tempCastlingHandler.executeCastling(tempCastlingMove); + } + } else if (isEnPassant) { Enpassant tempEnpassantHandler = tempBoard.getEnpassantHandler(); tempEnpassantHandler.executeEnPassant(fromX, fromY, toX, toY); } else { - // Normal move simulation tempBoard.removePiece(toX, toY); tempBoard.removePiece(fromX, fromY); tempBoard.setPiece(tempPiece.isWhite(), tempPiece.getType(), toX, toY); } - // Check if opponent's king is in check after move return isKingInCheck(tempBoard, !tempPiece.isWhite()); } public boolean putsOpponentInCheckmate() { - // First, check if the move puts the opponent in check if (!putsOpponentInCheck()) { return false; } - // Create a temporary board to simulate the move Board tempBoard = new Board(board); - // Find the piece in the temp board Piece tempPiece = tempBoard.getPieceAt(fromX, fromY); - if (tempPiece == null) return false; // Safety check + if (tempPiece == null) return false; - if (isEnPassant) { - // Simulate en passant on temp board + if (isCastling) { + CastlingHandler tempCastlingHandler = tempBoard.getCastlingHandler(); + CastlingHandler.CastlingMove tempCastlingMove = tempCastlingHandler.getCastlingMove(fromX, fromY, toX, toY); + if (tempCastlingMove != null) { + tempCastlingHandler.executeCastling(tempCastlingMove); + } + } else if (isEnPassant) { Enpassant tempEnpassantHandler = tempBoard.getEnpassantHandler(); tempEnpassantHandler.executeEnPassant(fromX, fromY, toX, toY); } else { - // Normal move simulation tempBoard.removePiece(toX, toY); tempBoard.removePiece(fromX, fromY); tempBoard.setPiece(tempPiece.isWhite(), tempPiece.getType(), toX, toY); @@ -145,23 +161,19 @@ public class Move { boolean opponentColor = !tempPiece.isWhite(); - // Try all possible moves for all opponent pieces for (Piece p : tempBoard.getPieces()) { - if (p.isWhite() != opponentColor) continue; // Skip pieces of the wrong color + if (p.isWhite() != opponentColor) continue; List possibleMoves = getValidDestinations(p, tempBoard); for (Position pos : possibleMoves) { - // Create a temporary move Move testMove = new Move(p.getX(), p.getY(), pos.x, pos.y, tempBoard); - // Check if this move would get the opponent out of check if (!testMove.putsOwnKingInCheck()) { - return false; // Opponent has at least one valid move + return false; } } } - // If we get here, opponent has no valid moves return true; } @@ -187,6 +199,7 @@ public class Move { return moves; case King: addKingMoves(moves, piece, board); + addCastlingMoves(moves, piece, board); return moves; } @@ -194,10 +207,8 @@ public class Move { } public List getValidMoves(Piece piece, Board board) { - // Get all possible moves without considering check List candidateMoves = getValidDestinations(piece, board); - // Filter out moves that would leave king in check List legalMoves = new ArrayList<>(); for (Position pos : candidateMoves) { Move move = new Move(piece.getX(), piece.getY(), pos.x, pos.y, board); @@ -210,7 +221,6 @@ public class Move { } public boolean isKingInCheck(Board board, boolean isWhiteKing) { - // Find the king's position Piece king = null; for (Piece p : board.getPieces()) { if (p.getType() == PieceType.King && p.isWhite() == isWhiteKing) { @@ -223,14 +233,11 @@ public class Move { } private boolean checkIfKingUnderAttack(Board board, boolean isWhiteKing, Piece king) { - // Check if any opponent piece can attack the king for (Piece p : board.getPieces()) { - if (p.isWhite() == isWhiteKing) continue; // Skip pieces of same color + if (p.isWhite() == isWhiteKing) continue; - // Get raw moves without check validation List attackMoves = getValidDestinations(p, board); - // If any piece can move to king's position, king is in check if (attackMoves.contains(new Position(king.getX(), king.getY()))) { return true; } @@ -239,21 +246,31 @@ public class Move { return false; } + private void addCastlingMoves(List validMoves, Piece piece, Board board) { + if (piece.getType() != PieceType.King) { + return; + } + + CastlingHandler castlingHandler = board.getCastlingHandler(); + List castlingPositions = castlingHandler.getCastlingPositions(piece); + + for (CastlingHandler.Position castlingPos : castlingPositions) { + validMoves.add(new Position(castlingPos.x, castlingPos.y)); + } + } + private void addPawnMoves(List validMoves, Piece piece, Board board) { int x = piece.getX(); int y = piece.getY(); boolean isWhite = piece.isWhite(); - int direction = isWhite ? -1 : 1; // White pawns move up, black pawns move down + int direction = isWhite ? -1 : 1; - // Forward movement int newY = y + direction; if (newY >= 0 && newY < board.getHeight()) { - // Single square forward if (board.getPieceAt(x, newY) == null) { validMoves.add(new Position(x, newY)); - // Initial double move int startRow = isWhite ? 6 : 1; if (y == startRow) { int doubleY = newY + direction; @@ -263,7 +280,6 @@ public class Move { } } - // Diagonal captures (normal) for (int dx = -1; dx <= 1; dx += 2) { int newX = x + dx; if (newX >= 0 && newX < board.getWidth()) { @@ -275,7 +291,6 @@ public class Move { } } - // EN PASSANT: Ajouter les mouvements en passant en utilisant la classe Enpassant Enpassant enpassantHandler = board.getEnpassantHandler(); List enPassantMoves = enpassantHandler.getPossibleEnPassantMoves(x, y); for (Enpassant.Position enPos : enPassantMoves) { @@ -288,7 +303,6 @@ public class Move { int y = piece.getY(); boolean isWhite = piece.isWhite(); - // Directions: horizontal and vertical int[][] directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; for (int[] dir : directions) { @@ -303,15 +317,12 @@ public class Move { Piece targetPiece = board.getPieceAt(newX, newY); if (targetPiece == null) { - // Empty square validMoves.add(new Position(newX, newY)); } else { - // Occupied square if (targetPiece.isWhite() != isWhite) { - // Capture opponent's piece validMoves.add(new Position(newX, newY)); } - continueInDirection = false; // Cannot move beyond a piece + continueInDirection = false; } if (continueInDirection) { @@ -327,7 +338,6 @@ public class Move { int y = piece.getY(); boolean isWhite = piece.isWhite(); - // All possible knight moves: L-shapes int[][] knightMoves = { {-2, -1}, {-2, 1}, {-1, -2}, {-1, 2}, {1, -2}, {1, 2}, {2, -1}, {2, 1} @@ -341,7 +351,6 @@ public class Move { Piece targetPiece = board.getPieceAt(newX, newY); if (targetPiece == null || targetPiece.isWhite() != isWhite) { - // Empty square or can capture opponent's piece validMoves.add(new Position(newX, newY)); } } @@ -353,7 +362,6 @@ public class Move { int y = piece.getY(); boolean isWhite = piece.isWhite(); - // Directions: diagonals int[][] directions = {{1, 1}, {1, -1}, {-1, 1}, {-1, -1}}; for (int[] dir : directions) { @@ -368,15 +376,12 @@ public class Move { Piece targetPiece = board.getPieceAt(newX, newY); if (targetPiece == null) { - // Empty square validMoves.add(new Position(newX, newY)); } else { - // Occupied square if (targetPiece.isWhite() != isWhite) { - // Capture opponent's piece validMoves.add(new Position(newX, newY)); } - continueInDirection = false; // Cannot move beyond a piece + continueInDirection = false; } if (continueInDirection) { @@ -392,10 +397,9 @@ public class Move { int y = piece.getY(); boolean isWhite = piece.isWhite(); - // All adjacent squares for (int dx = -1; dx <= 1; dx++) { for (int dy = -1; dy <= 1; dy++) { - if (dx == 0 && dy == 0) continue; // Skip the current position + if (dx == 0 && dy == 0) continue; int newX = x + dx; int newY = y + dy; @@ -404,7 +408,6 @@ public class Move { Piece targetPiece = board.getPieceAt(newX, newY); if (targetPiece == null || targetPiece.isWhite() != isWhite) { - // Empty square or can capture opponent's piece validMoves.add(new Position(newX, newY)); } } @@ -421,7 +424,6 @@ public class Move { this.y = y; } - @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null || getClass() != obj.getClass()) return false; @@ -429,19 +431,19 @@ public class Move { return x == position.x && y == position.y; } - @Override public int hashCode() { return 31 * x + y; } } - // Getters public int getFromX() { return fromX; } public int getFromY() { return fromY; } public int getToX() { return toX; } public int getToY() { return toY; } public boolean isEnPassant() { return isEnPassant; } + public boolean isCastling() { return isCastling; } public Piece getMovingPiece() { return movingPiece; } public Piece getCapturedPiece() { return capturedPiece; } public Piece getEnPassantCapturedPiece() { return enPassantCapturedPiece; } + public CastlingHandler.CastlingMove getCastlingMove() { return castlingMove; } } \ No newline at end of file