diff --git a/src/backend/Board.java b/src/backend/Board.java index a58ed5e..3bb29b0 100644 --- a/src/backend/Board.java +++ b/src/backend/Board.java @@ -136,102 +136,131 @@ public class Board { board[fromY][fromX] = null; } - private Set getValidMoves(Piece p) { - Set valid = new HashSet<>(); - int x = p.getX(); - int y = p.getY(); - PieceType type = p.getType(); - boolean isWhite = p.isWhite(); + private Set getValidMoves(Piece piece) { + Set validMoves = new HashSet<>(); - int dir = isWhite ? -1 : 1; + int x = piece.getX(); // Current position coordinate x + int y = piece.getY(); // Current position coordinate y + boolean isWhite = piece.isWhite(); // Returns true if a piece is white, if black then false + PieceType type = piece.getType(); // What type of piece is considered (pawn, rook...) - switch (type) { - case Pawn: - if (inBounds(x, y + dir) && board[y + dir][x] == null) { - valid.add(x + "," + (y + dir)); - } - // First move 2-steps - if ((isWhite && y == 6) || (!isWhite && y == 1)) { - if (board[y + dir][x] == null && board[y + 2 * dir][x] == null) { - valid.add(x + "," + (y + 2 * dir)); - } - } - // Capture diagonally - if (inBounds(x - 1, y + dir) && board[y + dir][x - 1] != null && board[y + dir][x - 1].isWhite() != isWhite) - valid.add((x - 1) + "," + (y + dir)); - if (inBounds(x + 1, y + dir) && board[y + dir][x + 1] != null && board[y + dir][x + 1].isWhite() != isWhite) - valid.add((x + 1) + "," + (y + dir)); - break; + // Direction (y coordinate change): White moves "up" (-1), Black moves "down" (+1) + int direction = isWhite ? -1 : 1; - case Rook: - addLinearMoves(valid, x, y, isWhite, 1, 0); - addLinearMoves(valid, x, y, isWhite, -1, 0); - addLinearMoves(valid, x, y, isWhite, 0, 1); - addLinearMoves(valid, x, y, isWhite, 0, -1); - break; + switch (type) { + case Pawn: // moves one square forward (1st move 2 squares possible) + // Move one step forward (if the square in front is inside the board and empty) + if (inBounds(x, y + direction) && board[y + direction][x] == null) { + validMoves.add(x + "," + (y + direction)); + } - case Bishop: - addLinearMoves(valid, x, y, isWhite, 1, 1); - addLinearMoves(valid, x, y, isWhite, 1, -1); - addLinearMoves(valid, x, y, isWhite, -1, 1); - addLinearMoves(valid, x, y, isWhite, -1, -1); - break; + // First move: two steps forward (initial position - white piece 6th row, black 1st row) + boolean onStartRow = (isWhite && y == 6) || (!isWhite && y == 1); + // The square in front and one after that must be empty + if (onStartRow && board[y + direction][x] == null && board[y + 2 * direction][x] == null) { + validMoves.add(x + "," + (y + 2 * direction)); + } - case Queen: - addLinearMoves(valid, x, y, isWhite, 1, 0); - addLinearMoves(valid, x, y, isWhite, -1, 0); - addLinearMoves(valid, x, y, isWhite, 0, 1); - addLinearMoves(valid, x, y, isWhite, 0, -1); - addLinearMoves(valid, x, y, isWhite, 1, 1); - addLinearMoves(valid, x, y, isWhite, 1, -1); - addLinearMoves(valid, x, y, isWhite, -1, 1); - addLinearMoves(valid, x, y, isWhite, -1, -1); - break; + // Capture diagonally + int[] dx = {-1, 1}; + // Checking diagonal squares in both directions + for (int i : dx) { + int targetX = x + i; + int targetY = y + direction; + // Checking if the target square is inside the board and contains opponent's piece + if (inBounds(targetX, targetY)) { + Piece target = board[targetY][targetX]; + if (target != null && target.isWhite() != isWhite) { + validMoves.add(targetX + "," + targetY); + } + } + } + break; - case Knight: - int[][] knightMoves = { - {1, 2}, {2, 1}, {-1, 2}, {-2, 1}, - {1, -2}, {2, -1}, {-1, -2}, {-2, -1} - }; - for (int[] m : knightMoves) { - int nx = x + m[0]; - int ny = y + m[1]; - if (inBounds(nx, ny) && (board[ny][nx] == null || board[ny][nx].isWhite() != isWhite)) { - valid.add(nx + "," + ny); - } - } - break; + case Rook: // Moves in straight lines + addLinearMoves(validMoves, x, y, isWhite, 1, 0); // Right + addLinearMoves(validMoves, x, y, isWhite, -1, 0); // Left + addLinearMoves(validMoves, x, y, isWhite, 0, 1); // Down + addLinearMoves(validMoves, x, y, isWhite, 0, -1); // Up + break; - case King: - for (int dx = -1; dx <= 1; dx++) { - for (int dy = -1; dy <= 1; dy++) { - if (dx == 0 && dy == 0) continue; - int nx = x + dx, ny = y + dy; - if (inBounds(nx, ny) && (board[ny][nx] == null || board[ny][nx].isWhite() != isWhite)) { - valid.add(nx + "," + ny); - } - } - } - break; - } - return valid; + case Bishop: // Moves diagonally + addLinearMoves(validMoves, x, y, isWhite, 1, 1); // Down-Right + addLinearMoves(validMoves, x, y, isWhite, 1, -1); // Up-Right + addLinearMoves(validMoves, x, y, isWhite, -1, 1); // Down-Left + addLinearMoves(validMoves, x, y, isWhite, -1, -1); // Up-Left + break; + + case Queen: // Combines Rook + Bishop movements + int[][] queenDirections = { + {1, 0}, {-1, 0}, {0, 1}, {0, -1}, + {1, 1}, {1, -1}, {-1, 1}, {-1, -1} + }; + for (int[] dir : queenDirections) { + addLinearMoves(validMoves, x, y, isWhite, dir[0], dir[1]); + } + break; + + case Knight: // Jumps in L shapes (3 straight, 1 to the side) + int[][] knightMoves = { + {1, 2}, {2, 1}, {-1, 2}, {-2, 1}, + {1, -2}, {2, -1}, {-1, -2}, {-2, -1} + }; + for (int[] move : knightMoves) { + int nx = x + move[0]; + int ny = y + move[1]; + if (inBounds(nx, ny)) { + Piece target = board[ny][nx]; + if (target == null || target.isWhite() != isWhite) { + validMoves.add(nx + "," + ny); + } + } + } + break; + + case King: // Moves 1 square in any direction + for (int dxKing = -1; dxKing <= 1; dxKing++) { + for (int dyKing = -1; dyKing <= 1; dyKing++) { + if (dxKing == 0 && dyKing == 0) continue; + int nx = x + dxKing; + int ny = y + dyKing; + if (inBounds(nx, ny)) { + Piece target = board[ny][nx]; + if (target == null || target.isWhite() != isWhite) { + validMoves.add(nx + "," + ny); + } + } + } + } + break; + } + + return validMoves; // Returning the list of valid moves for each piece } private void addLinearMoves(Set valid, int x, int y, boolean isWhite, int dx, int dy) { - int nx = x + dx; - int ny = y + dy; - while (inBounds(nx, ny)) { - if (board[ny][nx] == null) { - valid.add(nx + "," + ny); - } else { - if (board[ny][nx].isWhite() != isWhite) { - valid.add(nx + "," + ny); - } - break; - } - nx += dx; - ny += dy; - } + int nx = x + dx; + int ny = y + dy; + + while (inBounds(nx, ny)) { + Piece target = board[ny][nx]; + + if (target == null) { + // If empty square then add valid move + valid.add(nx + "," + ny); + } else { + // If it's an opponent's piece → capture is allowed + if (target.isWhite() != isWhite) { + valid.add(nx + "," + ny); + } + // Stop moving further (can't jump over pieces) + break; + } + + // Move one step further in the same direction + nx += dx; + ny += dy; + } } private boolean inBounds(int x, int y) {