diff --git a/OOP_1A2_Project/bin/.gitignore b/OOP_1A2_Project/bin/.gitignore index 6d0c385..5c7ebe3 100644 --- a/OOP_1A2_Project/bin/.gitignore +++ b/OOP_1A2_Project/bin/.gitignore @@ -1 +1,2 @@ /backend/ +/windowInterface/ diff --git a/OOP_1A2_Project/bin/backend/Move.class b/OOP_1A2_Project/bin/backend/Move.class index c8b4a21..27a3180 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/Move.java b/OOP_1A2_Project/src/backend/Move.java index c5cb3f9..b636b15 100644 --- a/OOP_1A2_Project/src/backend/Move.java +++ b/OOP_1A2_Project/src/backend/Move.java @@ -12,6 +12,11 @@ public class Move { private Piece capturedPiece; private Board board; + // Castling-related fields + private CastlingHandler castlingHandler; + private CastlingHandler.CastlingMove castlingMove; + private boolean isCastling; + public Move(int fromX, int fromY, int toX, int toY, Board board) { this.fromX = fromX; this.fromY = fromY; @@ -20,6 +25,11 @@ public class Move { this.board = board; this.movingPiece = board.getPieceAt(fromX, fromY); this.capturedPiece = board.getPieceAt(toX, toY); + + // Initialize castling handler and check if this is a castling move + this.castlingHandler = new CastlingHandler(board); + this.castlingMove = castlingHandler.getCastlingMove(fromX, fromY, toX, toY); + this.isCastling = (castlingMove != null); } public boolean isValid() { @@ -28,21 +38,31 @@ public class Move { return false; } + // Handle castling validation + if (isCastling) { + return castlingHandler.isCastlingValid(castlingMove); + } + // Check if the move is in the list of valid moves for this piece List validMoves = getValidDestinations(movingPiece, board); - return validMoves.contains(new Position(toX, toY)); + return containsPosition(validMoves, new Position(toX, toY)); } public void execute() { - // Remove any piece at the destination (normal capture) - if (capturedPiece != null) { - board.removePiece(toX, toY); + if (isCastling) { + // Execute castling move + castlingHandler.executeCastling(castlingMove); + } else { + // Remove any piece at the destination (normal capture) + if (capturedPiece != null) { + board.removePiece(toX, toY); + } + + // Move the piece (remove from original position, add to new position) + board.removePiece(fromX, fromY); + board.setPiece(movingPiece.isWhite(), movingPiece.getType(), toX, toY); } - // Move the piece (remove from original position, add to new position) - board.removePiece(fromX, fromY); - board.setPiece(movingPiece.isWhite(), movingPiece.getType(), toX, toY); - // Advance turn board.advanceTurn(); } @@ -55,15 +75,25 @@ public class Move { Piece tempPiece = tempBoard.getPieceAt(fromX, fromY); if (tempPiece == null) return true; // Safety check - // Remove any piece at destination (normal capture) - tempBoard.removePiece(toX, toY); - - // Move the piece - tempBoard.removePiece(fromX, fromY); - tempBoard.setPiece(tempPiece.isWhite(), tempPiece.getType(), toX, toY); + if (isCastling) { + // For castling, we need to check the castling move specifically + CastlingHandler tempHandler = new CastlingHandler(tempBoard); + CastlingHandler.CastlingMove tempCastling = tempHandler.getCastlingMove(fromX, fromY, toX, toY); + if (tempCastling != null) { + tempHandler.executeCastling(tempCastling); + } + } else { + // Remove any piece at destination (normal capture) + tempBoard.removePiece(toX, toY); + + // Move the piece + 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()); + CastlingHandler tempHandler = new CastlingHandler(tempBoard); + return tempHandler.isKingInCheck(tempPiece.isWhite()); } public boolean putsOpponentInCheck() { @@ -74,15 +104,25 @@ public class Move { Piece tempPiece = tempBoard.getPieceAt(fromX, fromY); if (tempPiece == null) return false; // Safety check - // Remove any piece at destination (normal capture) - tempBoard.removePiece(toX, toY); - - // Move the piece - tempBoard.removePiece(fromX, fromY); - tempBoard.setPiece(tempPiece.isWhite(), tempPiece.getType(), toX, toY); + if (isCastling) { + // For castling, execute the castling move + CastlingHandler tempHandler = new CastlingHandler(tempBoard); + CastlingHandler.CastlingMove tempCastling = tempHandler.getCastlingMove(fromX, fromY, toX, toY); + if (tempCastling != null) { + tempHandler.executeCastling(tempCastling); + } + } else { + // Remove any piece at destination (normal capture) + tempBoard.removePiece(toX, toY); + + // Move the piece + 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()); + CastlingHandler tempHandler = new CastlingHandler(tempBoard); + return tempHandler.isKingInCheck(!tempPiece.isWhite()); } public boolean putsOpponentInCheckmate() { @@ -98,12 +138,21 @@ public class Move { Piece tempPiece = tempBoard.getPieceAt(fromX, fromY); if (tempPiece == null) return false; // Safety check - // Remove any piece at destination (normal capture) - tempBoard.removePiece(toX, toY); - - // Move the piece - tempBoard.removePiece(fromX, fromY); - tempBoard.setPiece(tempPiece.isWhite(), tempPiece.getType(), toX, toY); + if (isCastling) { + // For castling, execute the castling move + CastlingHandler tempHandler = new CastlingHandler(tempBoard); + CastlingHandler.CastlingMove tempCastling = tempHandler.getCastlingMove(fromX, fromY, toX, toY); + if (tempCastling != null) { + tempHandler.executeCastling(tempCastling); + } + } else { + // Remove any piece at destination (normal capture) + tempBoard.removePiece(toX, toY); + + // Move the piece + tempBoard.removePiece(fromX, fromY); + tempBoard.setPiece(tempPiece.isWhite(), tempPiece.getType(), toX, toY); + } boolean opponentColor = !tempPiece.isWhite(); @@ -133,23 +182,23 @@ public class Move { switch (piece.getType()) { case Pawn: addPawnMoves(moves, piece, board); - return moves; + break; case Rook: addRookMoves(moves, piece, board); - return moves; + break; case Knight: addKnightMoves(moves, piece, board); - return moves; + break; case Bishop: addBishopMoves(moves, piece, board); - return moves; + break; case Queen: addRookMoves(moves, piece, board); addBishopMoves(moves, piece, board); - return moves; + break; case King: addKingMoves(moves, piece, board); - return moves; + break; } return moves; @@ -172,33 +221,8 @@ 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) { - king = p; - return checkIfKingUnderAttack(board, isWhiteKing, king); - } - } - - return false; - } - - 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 - - // 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; - } - } - - return false; + CastlingHandler handler = new CastlingHandler(board); + return handler.isKingInCheck(isWhiteKing); } private void addPawnMoves(List validMoves, Piece piece, Board board) { @@ -347,7 +371,7 @@ public class Move { int y = piece.getY(); boolean isWhite = piece.isWhite(); - // All adjacent squares + // All adjacent squares (normal king moves) for (int dx = -1; dx <= 1; dx++) { for (int dy = -1; dy <= 1; dy++) { if (dx == 0 && dy == 0) continue; // Skip the current position @@ -365,6 +389,23 @@ public class Move { } } } + + // Add castling moves + CastlingHandler handler = new CastlingHandler(board); + List castlingPositions = handler.getCastlingPositions(piece); + for (CastlingHandler.Position castlingPos : castlingPositions) { + validMoves.add(new Position(castlingPos.x, castlingPos.y)); + } + } + + // Helper method to check if a list contains a position + private boolean containsPosition(List positions, Position target) { + for (Position pos : positions) { + if (pos.x == target.x && pos.y == target.y) { + return true; + } + } + return false; } public class Position { @@ -376,7 +417,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;