diff --git a/src/backend/Move.java b/src/backend/Move.java index 4896b00..57f6502 100644 --- a/src/backend/Move.java +++ b/src/backend/Move.java @@ -1,31 +1,31 @@ package backend; public class Move { - private int fromX; - private int fromY; - private int toX; - private int toY; - private Piece pieceMoved; - private Piece pieceCaptured; - - public Move(int fromX, int fromY, int toX, int toY, Piece pieceMoved, Piece pieceCaptured) { - this.fromX = fromX; - this.fromY = fromY; - this.toX = toX; - this.toY = toY; - this.pieceMoved = pieceMoved; - this.pieceCaptured = pieceCaptured; - } - - public int getFromX() { - return fromX; - } + private int fromX; + private int fromY; + private int toX; + private int toY; + private Piece pieceMoved; + private Piece pieceCaptured; - public int getFromY() { - return fromY; - } - - public int getToX() { + public Move(int fromX, int fromY, int toX, int toY, Piece pieceMoved, Piece pieceCaptured) { + this.fromX = fromX; + this.fromY = fromY; + this.toX = toX; + this.toY = toY; + this.pieceMoved = pieceMoved; + this.pieceCaptured = pieceCaptured; + } + + public int getFromX() { + return fromX; + } + + public int getFromY() { + return fromY; + } + + public int getToX() { return toX; } @@ -40,4 +40,173 @@ public class Move { public Piece getPieceCaptured() { return pieceCaptured; } -} + + // Static method to calculate all valid moves for a piece + public static String[] calculateValidMoves(Board board, Piece piece) { + String[] validMoves = new String[32]; // Allocate space for up to 32 moves + int[] moveCount = new int[1]; // Use an array to simulate a mutable counter + moveCount[0] = 0; + + int x = piece.getX(); + int y = piece.getY(); + switch (piece.getType()) { + case Pawn: + calculatePawnMoves(board, piece, x, y, validMoves, moveCount); + break; + case Rook: + calculateRookMoves(board, piece, x, y, validMoves, moveCount); + break; + case Knight: + calculateKnightMoves(board, piece, x, y, validMoves, moveCount); + break; + case Bishop: + calculateBishopMoves(board, piece, x, y, validMoves, moveCount); + break; + case Queen: + calculateQueenMoves(board, piece, x, y, validMoves, moveCount); + break; + case King: + calculateKingMoves(board, piece, x, y, validMoves, moveCount); + break; + } + + // Trim the array to the actual number of moves + String[] result = new String[moveCount[0]]; + for (int i = 0; i < moveCount[0]; i++) { + result[i] = validMoves[i]; + } + return result; + } + + private static void calculatePawnMoves(Board board, Piece piece, int x, int y, String[] validMoves, int[] moveCount) { + int direction = piece.isWhite() ? -1 : 1; // White pawns move up, black pawns move down + int startRow = piece.isWhite() ? 6 : 1; // Starting row for double move + + // Move forward one square + if (isValidPosition(board, x, y + direction) && getPieceAt(board, x, y + direction) == null) { + addMoveIfNotDuplicate(x, y + direction, validMoves, moveCount); + // Move forward two squares from starting position + if (y == startRow && getPieceAt(board, x, y + 2 * direction) == null) { + addMoveIfNotDuplicate(x, y + 2 * direction, validMoves, moveCount); + } + } + + // Capture diagonally + if (isValidPosition(board, x - 1, y + direction)) { + Piece target = getPieceAt(board, x - 1, y + direction); + if (target != null && target.isWhite() != piece.isWhite()) { + addMoveIfNotDuplicate(x - 1, y + direction, validMoves, moveCount); + } + } + if (isValidPosition(board, x + 1, y + direction)) { + Piece target = getPieceAt(board, x + 1, y + direction); + if (target != null && target.isWhite() != piece.isWhite()) { + addMoveIfNotDuplicate(x + 1, y + direction, validMoves, moveCount); + } + } + } + + private static void calculateRookMoves(Board board, Piece piece, int x, int y, String[] validMoves, int[] moveCount) { + // Horizontal: left + for (int i = x - 1; i >= 0; i--) { + if (!addMoveIfValid(board, piece, i, y, validMoves, moveCount)) break; + } + // Horizontal: right + for (int i = x + 1; i < board.getWidth(); i++) { + if (!addMoveIfValid(board, piece, i, y, validMoves, moveCount)) break; + } + // Vertical: up + for (int j = y - 1; j >= 0; j--) { + if (!addMoveIfValid(board, piece, x, j, validMoves, moveCount)) break; + } + // Vertical: down + for (int j = y + 1; j < board.getHeight(); j++) { + if (!addMoveIfValid(board, piece, x, j, validMoves, moveCount)) break; + } + } + + private static void calculateKnightMoves(Board board, Piece piece, int x, int y, String[] validMoves, int[] moveCount) { + int[][] knightMoves = { + {-2, -1}, {-2, 1}, {-1, -2}, {-1, 2}, + {1, -2}, {1, 2}, {2, -1}, {2, 1} + }; + for (int i = 0; i < knightMoves.length; i++) { + int newX = x + knightMoves[i][0]; + int newY = y + knightMoves[i][1]; + addMoveIfValid(board, piece, newX, newY, validMoves, moveCount); + } + } + + private static void calculateBishopMoves(Board board, Piece piece, int x, int y, String[] validMoves, int[] moveCount) { + // Diagonal: up-left + for (int i = 1; x - i >= 0 && y - i >= 0; i++) { + if (!addMoveIfValid(board, piece, x - i, y - i, validMoves, moveCount)) break; + } + // Diagonal: up-right + for (int i = 1; x + i < board.getWidth() && y - i >= 0; i++) { + if (!addMoveIfValid(board, piece, x + i, y - i, validMoves, moveCount)) break; + } + // Diagonal: down-left + for (int i = 1; x - i >= 0 && y + i < board.getHeight(); i++) { + if (!addMoveIfValid(board, piece, x - i, y + i, validMoves, moveCount)) break; + } + // Diagonal: down-right + for (int i = 1; x + i < board.getWidth() && y + i < board.getHeight(); i++) { + if (!addMoveIfValid(board, piece, x + i, y + i, validMoves, moveCount)) break; + } + } + + private static void calculateQueenMoves(Board board, Piece piece, int x, int y, String[] validMoves, int[] moveCount) { + // Queen moves like a rook + bishop + calculateRookMoves(board, piece, x, y, validMoves, moveCount); + calculateBishopMoves(board, piece, x, y, validMoves, moveCount); + } + + private static void calculateKingMoves(Board board, Piece piece, int x, int y, String[] validMoves, int[] moveCount) { + for (int dx = -1; dx <= 1; dx++) { + for (int dy = -1; dy <= 1; dy++) { + if (dx == 0 && dy == 0) continue; + int newX = x + dx; + int newY = y + dy; + addMoveIfValid(board, piece, newX, newY, validMoves, moveCount); + } + } + } + + private static boolean addMoveIfValid(Board board, Piece piece, int x, int y, String[] validMoves, int[] moveCount) { + if (!isValidPosition(board, x, y)) return false; + Piece target = getPieceAt(board, x, y); + if (target == null || target.isWhite() != piece.isWhite()) { + addMoveIfNotDuplicate(x, y, validMoves, moveCount); + return target == null; // Continue if the square is empty, stop if we hit a piece + } + return false; // Stop if we hit a piece of the same color + } + + private static void addMoveIfNotDuplicate(int x, int y, String[] validMoves, int[] moveCount) { + if (moveCount[0] >= validMoves.length) return; // Prevent array overflow + String position = x + "," + y; + // Check for duplicates + for (int i = 0; i < moveCount[0]; i++) { + if (validMoves[i] != null && validMoves[i].equals(position)) { + return; // Position already exists + } + } + validMoves[moveCount[0]] = position; + moveCount[0]++; + } + + private static boolean isValidPosition(Board board, int x, int y) { + return x >= 0 && x < board.getWidth() && y >= 0 && y < board.getHeight(); + } + + private static Piece getPieceAt(Board board, int x, int y) { + Piece[] pieces = board.getPieces().toArray(new Piece[0]); + for (int i = 0; i < pieces.length; i++) { + if (pieces[i].getX() == x && pieces[i].getY() == y) { + return pieces[i]; + } + } + return null; + } +} \ No newline at end of file