diff --git a/src/backend/Board.java b/src/backend/Board.java index f0c04c5..43e9f8d 100644 --- a/src/backend/Board.java +++ b/src/backend/Board.java @@ -1,633 +1,330 @@ package backend; - - import java.util.ArrayList; - - public class Board { - - -public int width; - -public int height; - -private Piece[][] board; - -private boolean hasSelectedPiece = false; - -private int selectedX = -1; - -private int selectedY = -1; - -private int turnNumber = 0; - -private boolean turnWhite = true; - -private ArrayList highlightedSquares = new ArrayList<>(); - - - -public Board(int colNum, int lineNum) { - -this.width = colNum; - -this.height = lineNum; - -this.board = new Piece[width][height]; - -} - - - -public int getWidth() { - -return width; - -} - - - -public int getHeight() { - -return height; - -} - - - -public int getTurnNumber() { - -return turnNumber; - -} - - - -public boolean isTurnWhite() { - -return turnWhite; - -} - - - -public void setPiece(boolean isWhite, PieceType type, int x, int y) { - -if (x >= 0 && x < width && y >= 0 && y < height) { - -board[x][y] = new Piece(x, y, isWhite, type); - -} - -} - - - -public void populateBoard() { - -cleanBoard(); - -// White pawns - -for (int x = 0; x < 8; x++) { - -setPiece(true, PieceType.Pawn, x, 1); - -} - -// Black pawns - -for (int x = 0; x < 8; x++) { - -setPiece(false, PieceType.Pawn, x, 6); - -} - - - -PieceType[] backRow = { - -PieceType.Rook, PieceType.Knight, PieceType.Bishop, - -PieceType.Queen, PieceType.King, PieceType.Bishop, - -PieceType.Knight, PieceType.Rook - -}; - - - -// White back row - -for (int x = 0; x < 8; x++) { - -setPiece(true, backRow[x], x, 0); - -} - -// Black back row - -for (int x = 0; x < 8; x++) { - -setPiece(false, backRow[x], x, 7); - -} - -} - - - -public void cleanBoard() { - -for (int x = 0; x < width; x++) { - -for (int y = 0; y < height; y++) { - -board[x][y] = null; - -} - -} - -} - - - -public String toString() { - -StringBuilder stringboard= new StringBuilder(); - -for (int row = height - 1; row >= 0; row--) { - - - -for (int column = 0; column < width; column++) { - -Piece piece = board[column][row]; - -if (piece == null) { - -stringboard.append(". "); - -} else { - -char sym = piece.getType().name().charAt(0); - -stringboard.append(piece.isWhite() ? sym : Character.toLowerCase(sym)) - -.append(' '); - -} - -} - -stringboard.append("\n"); - -} - -stringboard.append(" "); - -for (int x = 0; x < width; x++) { - -stringboard.append((char)('a' + x)).append(' '); - -} - -stringboard.append("\n"); - -stringboard.append("Turn: ").append(isTurnWhite() ? "White" : "Black"); - -return stringboard.toString(); - -} - - - - - -public ArrayList getPieces() { - -ArrayList pieces = new ArrayList<>(); - -for (int x = 0; x < width; x++) { - -for (int y = 0; y < height; y++) { - -if (board[x][y] != null) { - -pieces.add(board[x][y]); - -} - -} - -} - -return pieces; - - - - - - - - - -} - - - -public boolean isSelected(int x, int y) { - -return hasSelectedPiece && selectedX == x && selectedY == y; - -} - - - -private boolean inBounds(int x, int y) { - -return x >= 0 && x < width && y >= 0 && y < height; - -} - - - - - -private ArrayList getValidMoves(Piece piece) { - -ArrayList moves = new ArrayList<>(); - -int x = piece.getX(); - -int y = piece.getY(); - -PieceType type = piece.getType(); - - - -if (type == PieceType.Pawn) { - -int dir = piece.isWhite() ? 1 : -1; - -int startRow = piece.isWhite() ? 1 : 6; - - - -int oneStep = y + dir; - -if (inBounds(x, oneStep) && board[x][oneStep] == null) { - -moves.add(new int[]{x, oneStep}); - - - -// If on start row, try two steps forward - -int twoStep = y + 2 * dir; - -if (y == startRow && inBounds(x, twoStep) && board[x][twoStep] == null) { - -moves.add(new int[]{x, twoStep}); - -} - -} - - - -// Capture diagonals - -for (int dx : new int[]{-1, 1}) { - -int nx = x + dx; - -int ny = y + dir; - -if (inBounds(nx, ny) && board[nx][ny] != null && - -board[nx][ny].isWhite() != piece.isWhite()) { - -moves.add(new int[]{nx, ny}); - -} - -} - -} - -else if (type == PieceType.Rook) { - -int[][] dirs = {{1,0}, {-1,0}, {0,1}, {0,-1}}; - -for (int[] d : dirs) { - -int nx = x + d[0], ny = y + d[1]; - -while (inBounds(nx, ny)) { - -if (board[nx][ny] == null) { - -moves.add(new int[]{nx, ny}); - -} else { - -if (board[nx][ny].isWhite() != piece.isWhite()) { - -moves.add(new int[]{nx, ny}); - -} - -break; - -} - -nx += d[0]; ny += d[1]; - -} - -} - -} - - - -else if (type == PieceType.Bishop) { - -int[][] dirs = {{1,1}, {-1,1}, {-1,-1}, {1,-1}}; - -for (int[] d : dirs) { - -int nx = x + d[0], ny = y + d[1]; - -while (inBounds(nx, ny)) { - -if (board[nx][ny] == null) { - -moves.add(new int[]{nx, ny}); - -} else { - -if (board[nx][ny].isWhite() != piece.isWhite()) { - -moves.add(new int[]{nx, ny}); - -} - -break; - -} - -nx += d[0]; ny += d[1]; - -} - -} - -} - - - -else if (type == PieceType.Queen) { - -// Queen = Rook + Bishop - -moves.addAll(getValidMoves(new Piece(x, y, piece.isWhite(), PieceType.Rook))); - -moves.addAll(getValidMoves(new Piece(x, y, piece.isWhite(), PieceType.Bishop))); - -} - - - -else if (type == PieceType.Knight) { - -int[][] jumps = { - -{2,1},{1,2},{-1,2},{-2,1}, - -{-2,-1},{-1,-2},{1,-2},{2,-1} - -}; - -for (int[] j : jumps) { - -int nx = x + j[0], ny = y + j[1]; - -if (inBounds(nx, ny)) { - -if (board[nx][ny] == null || board[nx][ny].isWhite() != piece.isWhite()) { - -moves.add(new int[]{nx, ny}); - -} - -} - -} - -} - - - -else if (type == PieceType.King) { - -int[][] dirs = { - -{1,0}, {-1,0}, {0,1}, {0,-1}, - -{1,1}, {-1,1}, {-1,-1}, {1,-1} - -}; - -for (int[] d : dirs) { - -int nx = x + d[0], ny = y + d[1]; - -if (inBounds(nx, ny)) { - -if (board[nx][ny] == null || board[nx][ny].isWhite() != piece.isWhite()) { - -moves.add(new int[]{nx, ny}); - -} - -} - -} - -} - - - -return moves; - -} - - - - - - - - - -public void userTouch(int x, int y) { - -if (x < 0 || x >= width || y < 0 || y >= height) return; - - - -Piece clicked = board[x][y]; - - - -if (!hasSelectedPiece) { - -if (clicked != null && clicked.isWhite() == turnWhite) { - -// Select piece - -selectedX = x; - -selectedY = y; - -hasSelectedPiece = true; - -highlightedSquares = getValidMoves(clicked); // ✅ Highlight legal moves - -} - -} else { - -// Check if clicked again on the same square to unselect - -if (selectedX == x && selectedY == y) { - -hasSelectedPiece = false; - -highlightedSquares.clear(); - -} - -// If clicked on a highlighted square, move there - -else if (isHighlighted(x, y)) { - -Piece selectedPiece = board[selectedX][selectedY]; - - - -// Move piece - -board[x][y] = selectedPiece; - -board[selectedX][selectedY] = null; - -selectedPiece.setX(x); - -selectedPiece.setY(y); - - - -// Update turn - -turnWhite = !turnWhite; - -turnNumber++; - - - -// Clear selection & highlights - -hasSelectedPiece = false; - -highlightedSquares.clear(); - -} - -// Invalid move: just unselect - -else { - -hasSelectedPiece = false; - -highlightedSquares.clear(); - -} - -} - -} - - - - - - - -/* saving-loading feature */ - -public String[] toFileRep() { - -return null; - -} - - - -public Board(String[] array) { - -// TODO - -} - - - -/* The following methods require more work */ - -public boolean isHighlighted(int x, int y) { - -for (int[] pos : highlightedSquares) { - -if (pos[0] == x && pos[1] == y) { - -return true; - -} - -} - -return false; - -} - - - -public void undoLastMove() { - -// TODO - -} - - - -public Board(Board board) { - -// TODO helloyo - -} - - - -public void playMove(Move move) { - -// TODO - -} - + public int width; + public int height; + private Piece[][] board; + private boolean hasSelectedPiece = false; + private int selectedX = -1; + private int selectedY = -1; + private int turnNumber = 0; + private boolean turnWhite = true; + private ArrayList highlightedSquares = new ArrayList<>(); + + public Board(int colNum, int lineNum) { + this.width = colNum; + this.height = lineNum; + this.board = new Piece[width][height]; + } + + public int getWidth() { + return width; + } + + public int getHeight() { + return height; + } + + public int getTurnNumber() { + return turnNumber; + } + + public boolean isTurnWhite() { + return turnWhite; + } + + public void setPiece(boolean isWhite, PieceType type, int x, int y) { + if (x >= 0 && x < width && y >= 0 && y < height) { + board[x][y] = new Piece(x, y, isWhite, type); + } + } + + public void populateBoard() { + cleanBoard(); + // White pawns + for (int x = 0; x < 8; x++) { + setPiece(true, PieceType.Pawn, x, 1); + } + // Black pawns + for (int x = 0; x < 8; x++) { + setPiece(false, PieceType.Pawn, x, 6); + } + + PieceType[] backRow = { + PieceType.Rook, PieceType.Knight, PieceType.Bishop, + PieceType.Queen, PieceType.King, PieceType.Bishop, + PieceType.Knight, PieceType.Rook + }; + + // White back row + for (int x = 0; x < 8; x++) { + setPiece(true, backRow[x], x, 0); + } + // Black back row + for (int x = 0; x < 8; x++) { + setPiece(false, backRow[x], x, 7); + } + } + + public void cleanBoard() { + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + board[x][y] = null; + } + } + } + + public String toString() { + StringBuilder stringboard= new StringBuilder(); + for (int row = height - 1; row >= 0; row--) { + + for (int column = 0; column < width; column++) { + Piece piece = board[column][row]; + if (piece == null) { + stringboard.append(". "); + } else { + char sym = piece.getType().name().charAt(0); + stringboard.append(piece.isWhite() ? sym : Character.toLowerCase(sym)) + .append(' '); + } + } + stringboard.append("\n"); + } + stringboard.append(" "); + for (int x = 0; x < width; x++) { + stringboard.append((char)('a' + x)).append(' '); + } + stringboard.append("\n"); + stringboard.append("Turn: ").append(isTurnWhite() ? "White" : "Black"); + return stringboard.toString(); + } + + + public ArrayList getPieces() { + ArrayList pieces = new ArrayList<>(); + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + if (board[x][y] != null) { + pieces.add(board[x][y]); + } + } + } + return pieces; + + + + + } + + public boolean isSelected(int x, int y) { + return hasSelectedPiece && selectedX == x && selectedY == y; + } + + private boolean inBounds(int x, int y) { + return x >= 0 && x < width && y >= 0 && y < height; + } + + + private ArrayList getValidMoves(Piece piece) { + ArrayList moves = new ArrayList<>(); + int x = piece.getX(); + int y = piece.getY(); + PieceType type = piece.getType(); + + if (type == PieceType.Pawn) { + int dir = piece.isWhite() ? 1 : -1; + int startRow = piece.isWhite() ? 1 : 6; + + int oneStep = y + dir; + if (inBounds(x, oneStep) && board[x][oneStep] == null) { + moves.add(new int[]{x, oneStep}); + + // If on start row, try two steps forward + int twoStep = y + 2 * dir; + if (y == startRow && inBounds(x, twoStep) && board[x][twoStep] == null) { + moves.add(new int[]{x, twoStep}); + } + } + + // Capture diagonals + for (int dx : new int[]{-1, 1}) { + int nx = x + dx; + int ny = y + dir; + if (inBounds(nx, ny) && board[nx][ny] != null && + board[nx][ny].isWhite() != piece.isWhite()) { + moves.add(new int[]{nx, ny}); + } + } + } + else if (type == PieceType.Rook) { + int[][] dirs = {{1,0}, {-1,0}, {0,1}, {0,-1}}; + for (int[] d : dirs) { + int nx = x + d[0], ny = y + d[1]; + while (inBounds(nx, ny)) { + if (board[nx][ny] == null) { + moves.add(new int[]{nx, ny}); + } else { + if (board[nx][ny].isWhite() != piece.isWhite()) { + moves.add(new int[]{nx, ny}); + } + break; + } + nx += d[0]; ny += d[1]; + } + } + } + + else if (type == PieceType.Bishop) { + int[][] dirs = {{1,1}, {-1,1}, {-1,-1}, {1,-1}}; + for (int[] d : dirs) { + int nx = x + d[0], ny = y + d[1]; + while (inBounds(nx, ny)) { + if (board[nx][ny] == null) { + moves.add(new int[]{nx, ny}); + } else { + if (board[nx][ny].isWhite() != piece.isWhite()) { + moves.add(new int[]{nx, ny}); + } + break; + } + nx += d[0]; ny += d[1]; + } + } + } + + else if (type == PieceType.Queen) { + // Queen = Rook + Bishop + moves.addAll(getValidMoves(new Piece(x, y, piece.isWhite(), PieceType.Rook))); + moves.addAll(getValidMoves(new Piece(x, y, piece.isWhite(), PieceType.Bishop))); + } + + else if (type == PieceType.Knight) { + int[][] jumps = { + {2,1},{1,2},{-1,2},{-2,1}, + {-2,-1},{-1,-2},{1,-2},{2,-1} + }; + for (int[] j : jumps) { + int nx = x + j[0], ny = y + j[1]; + if (inBounds(nx, ny)) { + if (board[nx][ny] == null || board[nx][ny].isWhite() != piece.isWhite()) { + moves.add(new int[]{nx, ny}); + } + } + } + } + + else if (type == PieceType.King) { + int[][] dirs = { + {1,0}, {-1,0}, {0,1}, {0,-1}, + {1,1}, {-1,1}, {-1,-1}, {1,-1} + }; + for (int[] d : dirs) { + int nx = x + d[0], ny = y + d[1]; + if (inBounds(nx, ny)) { + if (board[nx][ny] == null || board[nx][ny].isWhite() != piece.isWhite()) { + moves.add(new int[]{nx, ny}); + } + } + } + } + + return moves; + } + + + + + public void userTouch(int x, int y) { + if (x < 0 || x >= width || y < 0 || y >= height) return; + + Piece clicked = board[x][y]; + + if (!hasSelectedPiece) { + if (clicked != null && clicked.isWhite() == turnWhite) { + // Select piece + selectedX = x; + selectedY = y; + hasSelectedPiece = true; + highlightedSquares = getValidMoves(clicked); // ✅ Highlight legal moves + } + } else { + // Check if clicked again on the same square to unselect + if (selectedX == x && selectedY == y) { + hasSelectedPiece = false; + highlightedSquares.clear(); + } + // If clicked on a highlighted square, move there + else if (isHighlighted(x, y)) { + Piece selectedPiece = board[selectedX][selectedY]; + + // Move piece + board[x][y] = selectedPiece; + board[selectedX][selectedY] = null; + selectedPiece.setX(x); + selectedPiece.setY(y); + + // Update turn + turnWhite = !turnWhite; + turnNumber++; + + // Clear selection & highlights + hasSelectedPiece = false; + highlightedSquares.clear(); + } + // Invalid move: just unselect + else { + hasSelectedPiece = false; + highlightedSquares.clear(); + } + } + } + + + + /* saving-loading feature */ + public String[] toFileRep() { + ArrayList fileLines = new ArrayList<>(); + fileLines.add(turnNumber + "," + (turnWhite ? "white" : "black")); + fileLines.add(width + "," + height); + for (Piece piece : getPieces()) { + StringBuilder sb = new StringBuilder(); + sb.append(piece.getType()) // e.g. "Pawn" + .append(",").append(piece.getX()) // file X + .append(",").append(piece.getY()) // file Y + .append(",").append(piece.isWhite() ? "W" : "B"); + fileLines.add(sb.toString()); + } + return fileLines.toArray(new String[0]); + } + + + + public Board(String[] array) { + // TODO + } + + /* The following methods require more work */ + public boolean isHighlighted(int x, int y) { + for (int[] pos : highlightedSquares) { + if (pos[0] == x && pos[1] == y) { + return true; + } + } + return false; + } + + public void undoLastMove() { + // TODO + } + + public Board(Board board) { + // TODO helloyo + } + + public void playMove(Move move) { + // TODO + } } \ No newline at end of file