From b12735869ae1cccc55e30877473dab28ea44d0b3 Mon Sep 17 00:00:00 2001 From: Juliette Date: Tue, 13 May 2025 19:24:42 +0200 Subject: [PATCH] For highlight: FIlled in hihglight method, added a Position class, findMoves method (gives all possible cases), extend method (for rook, queen, and bishop), updated user touch (to show the highlight) --- default.board | 2 +- src/backend/Board.java | 490 ++++++++++++++++++++++++----------------- 2 files changed, 290 insertions(+), 202 deletions(-) diff --git a/default.board b/default.board index 8d83268..368db78 100644 --- a/default.board +++ b/default.board @@ -6,4 +6,4 @@ BP,BP,BP,BP,BP,BP,BP,BP , , , , , , , WP,WP,WP,WP,WP,WP,WP,WP WR,WN,WB,WQ,WK,WB,WN,WR -W + diff --git a/src/backend/Board.java b/src/backend/Board.java index d4b47a6..a63a471 100644 --- a/src/backend/Board.java +++ b/src/backend/Board.java @@ -2,233 +2,321 @@ package backend; import java.util.ArrayList; - public class Board { + private int colNum; + private int lineNum; + public String board[][]; + private PieceType type; + private ArrayList pieces; + private ArrayList highlight = new ArrayList<>(); + private int selectedX = -1; // Tracks selected column (-1 = no selection) + private int selectedY = -1; // Tracks selected row (-1 = no selection) + private int turnNumber = 0; // Starts at 0 (White's turn) + private boolean isWhiteTurn = true; // Track current player's turn - private int colNum; - private int lineNum; - public String board[][]; - private PieceType type; - private ArrayList pieces; - private int selectedX = -1; // Tracks selected column (-1 = no selection) - private int selectedY = -1; // Tracks selected row (-1 = no selection) - private int turnNumber = 0; // Starts at 0 (White's turn) - private boolean isWhiteTurn = true; // Track current player's turn + private char getPieceSymbol(Piece p) { + char symbol; + switch (p.getType()) { + case Pawn: symbol = 'P'; break; + case Rook: symbol = 'R'; break; + case Knight: symbol = 'N'; break; + case Bishop: symbol = 'B'; break; + case Queen: symbol = 'Q'; break; + case King: symbol = 'K'; break; + default: symbol = '?'; // Should never happen + } + return p.isWhite() ? symbol : Character.toLowerCase(symbol); + } - public Board(int colNum, int lineNum) { - this.colNum = colNum; - this.lineNum = lineNum; - this.pieces = new ArrayList<>(); - this.turnNumber = 0; // Initialize turn number - this.isWhiteTurn = true; // White starts first - - } + private Piece getPieceAt(int x, int y) { + for (Piece p : pieces) { + if (p.getX() == x && p.getY() == y) return p; + } + return null; + } - public int getWidth() { - //System.out.println("The width is " + lineNum); - return lineNum; - } + private static class Position { + int x, y; + Position(int x, int y) { + this.x = x; + this.y = y; + } + } - public int getHeight() { - //System.out.println("The height is " + colNum); - return colNum; - } + public Board(int colNum, int lineNum) { + this.colNum = colNum; + this.lineNum = lineNum; + this.pieces = new ArrayList<>(); + this.turnNumber = 0; // Initialize turn number + this.isWhiteTurn = true; // White starts first + } - public int getTurnNumber() { - return turnNumber; - } + public int getWidth() { + return lineNum; + } - public boolean isTurnWhite() { - return isWhiteTurn; - } + public int getHeight() { + return colNum; + } - public void setPiece(boolean isWhite, PieceType type, int x, int y) { - // Remove existing piece at coordinates (x,y) + public int getTurnNumber() { + return turnNumber; + } + + public boolean isTurnWhite() { + return isWhiteTurn; + } + + public void setPiece(boolean isWhite, PieceType type, int x, int y) { pieces.removeIf(p -> p.getX() == x && p.getY() == y); - // Add new piece pieces.add(new Piece(isWhite, type, x, y)); - //TODO - } + } - - ; - - public void populateBoard() { - for(int x=0; x<8;x++) { - setPiece(false,PieceType.Pawn,x,1); - setPiece(true,PieceType.Pawn,x,6); - } - setPiece(false,PieceType.Rook,0,0); - setPiece(false,PieceType.Rook,7,0); - setPiece(true,PieceType.Rook,0,7); - setPiece(true,PieceType.Rook,7,7); - - setPiece(false,PieceType.Knight,1,0); - setPiece(false,PieceType.Knight,6,0); - setPiece(true,PieceType.Knight,1,7); - setPiece(true,PieceType.Knight,6,7); - - setPiece(false,PieceType.Bishop,2,0); - setPiece(false,PieceType.Bishop,5,0); - setPiece(true,PieceType.Bishop,2,7); - setPiece(true,PieceType.Bishop,5,7); - - setPiece(false,PieceType.Queen,3,0); - setPiece(true,PieceType.Queen,3,7); - - setPiece(false,PieceType.King,4,0); - setPiece(true,PieceType.King,4,7); - } - - public void cleanBoard() { - pieces.clear(); // Remove all pieces from the board - //TODO - } - - public String toString() { - StringBuilder sb = new StringBuilder(); - - // Create a temporary grid representation - char[][] grid = new char[lineNum][colNum]; - // Initialize grid with empty squares - for (int y = 0; y < lineNum; y++) { - for (int x = 0; x < colNum; x++) { - grid[y][x] = '.'; - } - } - - // Fill pieces into the grid - for (Piece p : pieces) { - int x = p.getX(); - int y = p.getY(); - if (x >= 0 && x < colNum && y >= 0 && y < lineNum) { - grid[y][x] = getPieceSymbol(p); - } - } + public void populateBoard() { + for (int x = 0; x < 8; x++) { + setPiece(false, PieceType.Pawn, x, 1); + setPiece(true, PieceType.Pawn, x, 6); + } + setPiece(false, PieceType.Rook, 0, 0); + setPiece(false, PieceType.Rook, 7, 0); + setPiece(true, PieceType.Rook, 0, 7); + setPiece(true, PieceType.Rook, 7, 7); - // Build header - sb.append(" "); - for (int x = 0; x < colNum; x++) { - sb.append((char) ('a' + x)).append(' '); - } - sb.append('\n'); + setPiece(false, PieceType.Knight, 1, 0); + setPiece(false, PieceType.Knight, 6, 0); + setPiece(true, PieceType.Knight, 1, 7); + setPiece(true, PieceType.Knight, 6, 7); - // Build board rows (top to bottom) - for (int y = 0; y < lineNum; y++) { - sb.append(lineNum - y).append(' '); - for (int x = 0; x < colNum; x++) { - sb.append(grid[y][x]).append(' '); - } - sb.append('\n'); - } + setPiece(false, PieceType.Bishop, 2, 0); + setPiece(false, PieceType.Bishop, 5, 0); + setPiece(true, PieceType.Bishop, 2, 7); + setPiece(true, PieceType.Bishop, 5, 7); - return sb.toString(); - } - // Helper method to convert Piece to symbol (e.g., 'K' for white king) - private char getPieceSymbol(Piece p) { - char symbol; - switch (p.getType()) { - case Pawn: symbol = 'P'; break; - case Rook: symbol = 'R'; break; - case Knight: symbol = 'N'; break; - case Bishop: symbol = 'B'; break; - case Queen: symbol = 'Q'; break; - case King: symbol = 'K'; break; - default: symbol = '?'; // Should never happen - } - return p.isWhite() ? symbol : Character.toLowerCase(symbol); - } - - public ArrayList getPieces() { - return pieces; - } + setPiece(false, PieceType.Queen, 3, 0); + setPiece(true, PieceType.Queen, 3, 7); - public void userTouch(int x, int y) { - if (selectedX == -1) { // No current selection - // Check if there's a piece at the clicked position - for (Piece p : pieces) { - if (p.getX() == x && p.getY() == y) { - // Only allow selection if it's the correct player's turn - if (p.isWhite() == isWhiteTurn) { - selectedX = x; - selectedY = y; - } - return; - } - } - } else { // Already have a selected piece - if (x == selectedX && y == selectedY) { // Clicked same position: unselect - selectedX = -1; - selectedY = -1; - } else { // Attempt to move - Piece pieceToMove = null; - - // Find the selected piece - for (Piece p : pieces) { - if (p.getX() == selectedX && p.getY() == selectedY) { - pieceToMove = p; - break; - } - } + setPiece(false, PieceType.King, 4, 0); + setPiece(true, PieceType.King, 4, 7); + } - if (pieceToMove != null) { - // Remove any piece at target location - pieces.removeIf(p -> p.getX() == x && p.getY() == y); - - // Update piece position - pieceToMove.setX(x); - pieceToMove.setY(y); - - // Advance game state - turnNumber++; - isWhiteTurn = !isWhiteTurn; - } - - // Clear selection regardless of move success - selectedX = -1; - selectedY = -1; - } - } - } + public void cleanBoard() { + pieces.clear(); // Remove all pieces from the board + } - public boolean isSelected(int x, int y) { - return (x == selectedX && y == selectedY); + public String toString() { + StringBuilder sb = new StringBuilder(); - } - - /* saving-loading feature :*/ + char[][] grid = new char[lineNum][colNum]; + for (int y = 0; y < lineNum; y++) { + for (int x = 0; x < colNum; x++) { + grid[y][x] = '.'; + } + } - public String[] toFileRep() { - //TODO - return null; - } + for (Piece p : pieces) { + int x = p.getX(); + int y = p.getY(); + if (x >= 0 && x < colNum && y >= 0 && y < lineNum) { + grid[y][x] = getPieceSymbol(p); + } + } - public Board(String[] array) { - //TODO + sb.append(" "); + for (int x = 0; x < colNum; x++) { + sb.append((char) ('a' + x)).append(' '); + } + sb.append('\n'); - } - - /* The following methods require more work ! */ + for (int y = 0; y < lineNum; y++) { + sb.append(lineNum - y).append(' '); + for (int x = 0; x < colNum; x++) { + sb.append(grid[y][x]).append(' '); + } + sb.append('\n'); + } - public boolean isHighlighted(int x, int y) { - //TODO - return false; - } + return sb.toString(); + } - public void undoLastMove() { - //TODO - - } + public ArrayList getPieces() { + return pieces; + } - public Board(Board board) { - //TODO + public void userTouch(int x, int y) { + if (selectedX != -1 && x >= 0 && x < colNum && y >= 0 && y < lineNum && isHighlighted(x, y)) { + Piece selectedPiece = getPieceAt(selectedX, selectedY); + if (selectedPiece != null) { + pieces.removeIf(p -> p.getX() == x && p.getY() == y); + selectedPiece.setX(x); + selectedPiece.setY(y); - } - - public void playMove(Move move) { - //TODO + turnNumber++; + isWhiteTurn = !isWhiteTurn; + } - } + selectedX = -1; + selectedY = -1; + highlight.clear(); + return; + } + Piece p = getPieceAt(x, y); + if (p != null && p.isWhite() == isWhiteTurn) { + selectedX = x; + selectedY = y; + + highlight.clear(); + highlight.addAll(getValidMoves(p)); + } else { + selectedX = -1; + selectedY = -1; + highlight.clear(); + } + } + + public boolean isSelected(int x, int y) { + return (x == selectedX && y == selectedY); + } + + public String[] toFileRep() { + //TODO + return null; + } + + public Board(String[] array) { + //TODO + } + + public boolean isHighlighted(int x, int y) { + for (Position pos : highlight) { + if (pos.x == x && pos.y == y) { + return true; + } + } + return false; + } + + public void undoLastMove() { + //TODO + } + + public Board(Board board) { + //TODO + } + + public void playMove(Move move) { + //TODO + } + + private ArrayList getValidMoves(Piece p) { + ArrayList moves = new ArrayList<>(); + + int x = p.getX(); + int y = p.getY(); + boolean isWhite = p.isWhite(); + + if (p.getType() == PieceType.Pawn) { + int direction = isWhite ? -1 : 1; + int startRow = isWhite ? 6 : 1; + + if (x >= 0 && x < colNum && y + direction >= 0 && y + direction < lineNum && + getPieceAt(x, y + direction) == null) { + moves.add(new Position(x, y + direction)); + if (y == startRow && y + 2 * direction >= 0 && y + 2 * direction < lineNum && + getPieceAt(x, y + 2 * direction) == null) { + moves.add(new Position(x, y + 2 * direction)); + } + } + + for (int dx = -1; dx <= 1; dx += 2) { + int nx = x + dx; + int ny = y + direction; + if (nx >= 0 && nx < colNum && ny >= 0 && ny < lineNum) { + Piece target = getPieceAt(nx, ny); + if (target != null && target.isWhite() != isWhite) { + moves.add(new Position(nx, ny)); + } + } + } + } + + if (p.getType() == PieceType.Knight) { + int[][] jumps = { + {-2, -1}, {-2, 1}, {-1, -2}, {-1, 2}, + {1, -2}, {1, 2}, {2, -1}, {2, 1} + }; + + for (int[] j : jumps) { + int nx = x + j[0]; + int ny = y + j[1]; + if (nx >= 0 && nx < colNum && ny >= 0 && ny < lineNum) { + Piece target = getPieceAt(nx, ny); + if (target == null || target.isWhite() != isWhite) { + moves.add(new Position(nx, ny)); + } + } + } + } + + if (p.getType() == PieceType.Rook) { + addMovesInLine(moves, x, y, isWhite, 1, 0); + addMovesInLine(moves, x, y, isWhite, -1, 0); + addMovesInLine(moves, x, y, isWhite, 0, 1); + addMovesInLine(moves, x, y, isWhite, 0, -1); + } + + if (p.getType() == PieceType.Bishop) { + addMovesInLine(moves, x, y, isWhite, 1, 1); + addMovesInLine(moves, x, y, isWhite, -1, 1); + addMovesInLine(moves, x, y, isWhite, 1, -1); + addMovesInLine(moves, x, y, isWhite, -1, -1); + } + + if (p.getType() == PieceType.Queen) { + addMovesInLine(moves, x, y, isWhite, 1, 0); + addMovesInLine(moves, x, y, isWhite, -1, 0); + addMovesInLine(moves, x, y, isWhite, 0, 1); + addMovesInLine(moves, x, y, isWhite, 0, -1); + addMovesInLine(moves, x, y, isWhite, 1, 1); + addMovesInLine(moves, x, y, isWhite, -1, 1); + addMovesInLine(moves, x, y, isWhite, 1, -1); + addMovesInLine(moves, x, y, isWhite, -1, -1); + } + + if (p.getType() == PieceType.King) { + for (int dx = -1; dx <= 1; dx++) { + for (int dy = -1; dy <= 1; dy++) { + int nx = x + dx; + int ny = y + dy; + if (nx >= 0 && nx < colNum && ny >= 0 && ny < lineNum) { + Piece target = getPieceAt(nx, ny); + if (target == null || target.isWhite() != isWhite) { + moves.add(new Position(nx, ny)); + } + } + } + } + } + + return moves; + } + + private void addMovesInLine(ArrayList moves, int x, int y, boolean isWhite, int dx, int dy) { + int nx = x + dx; + int ny = y + dy; + while (nx >= 0 && nx < colNum && ny >= 0 && ny < lineNum) { + Piece target = getPieceAt(nx, ny); + if (target == null) { + moves.add(new Position(nx, ny)); + } else if (target.isWhite() != isWhite) { + moves.add(new Position(nx, ny)); + break; + } else { + break; + } + nx += dx; + ny += dy; + } + } }