From 11a4b431cf469725ddc7246c7a998d4862c19291 Mon Sep 17 00:00:00 2001 From: cleme Date: Thu, 27 Mar 2025 15:24:53 +0100 Subject: [PATCH] adding piece rules --- src/backend/Board.java | 380 ++++++++++++++++++++++------------------- src/backend/Piece.java | 127 ++++++++++++++ 2 files changed, 327 insertions(+), 180 deletions(-) diff --git a/src/backend/Board.java b/src/backend/Board.java index ef8b459..4a5441b 100644 --- a/src/backend/Board.java +++ b/src/backend/Board.java @@ -4,206 +4,226 @@ import java.util.ArrayList; public class Board { - private int width; - private int height; - private ArrayList pieces; - private int selectedX; - private int selectedY; - private int turnNumber; - private boolean isTurnWhite; - public int getSelectedX () { - return selectedX; - } - public int getSelectedY() { - return selectedY; - } - - - - public Board(int colNum, int lineNum) { // constructor to get width and height - this.width = colNum;//TODO - this.height = lineNum; - this.pieces = new ArrayList<>(); // Initialize the pieces list - } + private int width; + private int height; + private ArrayList pieces; + private int selectedX; + private int selectedY; + private int turnNumber; + private boolean isTurnWhite; - public int getWidth() { // returns width of the board (x axis) - return this.width; //TODO - } + public Board(int colNum, int lineNum) { + this.width = colNum; + this.height = lineNum; + this.pieces = new ArrayList<>(); + this.selectedX = -1; + this.selectedY = -1; + this.turnNumber = 0; + this.isTurnWhite = true; + } - public int getHeight() { - return this.height;//TODO - } + public int getWidth() { + return this.width; + } - public int getTurnNumber() { - //TODO - return turnNumber; - } + public int getHeight() { + return this.height; + } - public boolean isTurnWhite() { - //TODO - return isTurnWhite; - } + public int getTurnNumber() { + return turnNumber; + } - public void setPiece(boolean isWhite, PieceType type, int x, int y) { - if (x < 0 || x >= width || y < 0 || y >= height) {//TODO - return; //ignore invalid positions - } - pieces.removeIf(piece -> piece.getX() == x && piece.getY() == y); - pieces.add(new Piece(x, y, type, isWhite)); - } + public boolean isTurnWhite() { + return isTurnWhite; + } - public void populateBoard() { - cleanBoard();//TODO - - for (int x= 0; x < 8; x++) { - setPiece(true, PieceType.Pawn, x, 6); - } - - setPiece(true, PieceType.Rook, 0, 7); - setPiece(true, PieceType.Knight, 1, 7); - setPiece(true, PieceType.Bishop, 2, 7); - setPiece(true, PieceType.Queen, 3, 7); - setPiece(true, PieceType.King, 4, 7); - setPiece(true, PieceType.Bishop, 5, 7); - setPiece(true, PieceType.Knight, 6, 7); - setPiece(true, PieceType.Rook, 7, 7); - - for (int x = 0; x < 8; x++) { - setPiece(false, PieceType.Pawn, x, 1); - } - setPiece(false, PieceType.Rook, 0, 0); - setPiece(false, PieceType.Knight, 1, 0); - setPiece(false, PieceType.Bishop, 2, 0); - setPiece(false, PieceType.Queen, 3, 0); - setPiece(false, PieceType.King, 4, 0); - setPiece(false, PieceType.Bishop, 5, 0); - setPiece(false, PieceType.Knight, 6, 0); - setPiece(false, PieceType.Rook, 7, 0); - } - - public void cleanBoard() { - pieces.clear();//TODO - selectedX = -1; - selectedY = -1; - turnNumber = 0; - isTurnWhite = true; - } - - public String toString() { - String[][] boardRep = new String[height][width]; - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - boardRep[y][x] = ".";//TODO - } - } - for (Piece piece : pieces) { - String symbol = piece.getType().getSummary(); - symbol = piece.isWhite() ? symbol.toUpperCase() : symbol.toLowerCase(); - boardRep[piece.getY()][piece.getX()] = symbol; - } - - StringBuilder sb = new StringBuilder(); - for (int y = 0; y< height; y++) { - for (int x =0; x < width; x++) { - sb.append(boardRep[y][x]).append(" "); - } - sb.append("\n"); - } - return sb.toString(); - } - - - public ArrayList getPieces() { - //ArrayList pieces = new ArrayList<>(); - return new ArrayList<>(pieces);//TODO - - //return pieces; - } + public int getSelectedX() { + return selectedX; + } - public void userTouch(int x, int y) { - if (x < 0 || x >= width || y < 0 || y >= height) { - return; - } - - if (selectedX == -1 && selectedY == -1) { - Piece piece = getPieceAt(x, y); - if (piece != null ) { - selectedX = x; - selectedY = y; - } - } else { - - if (selectedX == x && selectedY == y) { - selectedX = -1; - selectedY = -1; - } else { - - Piece selectedPiece = getPieceAt(selectedX, selectedY); - if (selectedPiece != null) { - Piece pieceAtDestination = getPieceAt(x, y); - Move move = new Move(selectedX, selectedY, x ,y , selectedPiece, pieceAtDestination); - playMove(move); - selectedX = -1; - selectedY = -1; - } - } - } - } + public int getSelectedY() { + return selectedY; + } - public boolean isSelected(int x, int y) { - //TODO - return selectedX == x && selectedY == y; - } - - /* saving-loading feature :*/ + public void setPiece(boolean isWhite, PieceType type, int x, int y) { + if (x < 0 || x >= width || y < 0 || y >= height) { + System.out.println("setPiece: Out of bounds at (" + x + "," + y + ")"); + return; + } + pieces.removeIf(piece -> { + if (piece.getX() == x && piece.getY() == y) { + System.out.println("setPiece: Removing piece at (" + x + "," + y + "): " + piece.getType() + ", isWhite=" + piece.isWhite()); + return true; + } + return false; + }); + System.out.println("setPiece: Adding " + type + ", isWhite=" + isWhite + " at (" + x + "," + y + ")"); + pieces.add(new Piece(x, y, type, isWhite)); + } - public String[] toFileRep() { - //TODO - return null; - } + public void populateBoard() { + cleanBoard(); + for (int x = 0; x < 8; x++) { + setPiece(true, PieceType.Pawn, x, 6); + } + setPiece(true, PieceType.Rook, 0, 7); + setPiece(true, PieceType.Knight, 1, 7); + setPiece(true, PieceType.Bishop, 2, 7); + setPiece(true, PieceType.Queen, 3, 7); + setPiece(true, PieceType.King, 4, 7); + setPiece(true, PieceType.Bishop, 5, 7); + setPiece(true, PieceType.Knight, 6, 7); + setPiece(true, PieceType.Rook, 7, 7); + for (int x = 0; x < 8; x++) { + setPiece(false, PieceType.Pawn, x, 1); + } + setPiece(false, PieceType.Rook, 0, 0); + setPiece(false, PieceType.Knight, 1, 0); + setPiece(false, PieceType.Bishop, 2, 0); + setPiece(false, PieceType.Queen, 3, 0); + setPiece(false, PieceType.King, 4, 0); + setPiece(false, PieceType.Bishop, 5, 0); + setPiece(false, PieceType.Knight, 6, 0); + setPiece(false, PieceType.Rook, 7, 0); + } - public Board(String[] array) { - //TODO + public void cleanBoard() { + System.out.println("cleanBoard: Clearing all pieces"); + pieces.clear(); + selectedX = -1; + selectedY = -1; + turnNumber = 0; + isTurnWhite = true; + } - } - - /* The following methods require more work ! */ + public String toString() { + String[][] boardRep = new String[height][width]; + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + boardRep[y][x] = "."; + } + } + for (Piece piece : pieces) { + String symbol = piece.getType().getSummary(); + symbol = piece.isWhite() ? symbol.toUpperCase() : symbol.toLowerCase(); + boardRep[piece.getY()][piece.getX()] = symbol; + } + StringBuilder sb = new StringBuilder(); + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + sb.append(boardRep[y][x]).append(" "); + } + sb.append("\n"); + } + return sb.toString(); + } - public boolean isHighlighted(int x, int y) { - //TODO - return false; - } + public ArrayList getPieces() { + return new ArrayList<>(pieces); + } - public void undoLastMove() { - //TODO - - } + public void userTouch(int x, int y) { + System.out.println("userTouch called with x=" + x + ", y=" + y); + if (x < 0 || x >= width || y < 0 || y >= height) { + System.out.println("Click out of bounds"); + return; + } - public Board(Board board) { - //TODO + if (selectedX == -1 && selectedY == -1) { + Piece piece = getPieceAt(x, y); + if (piece != null) { + System.out.println("Selected piece at (" + x + "," + y + "): " + piece.getType() + ", isWhite=" + piece.isWhite()); + selectedX = x; + selectedY = y; + } else { + System.out.println("No piece at (" + x + "," + y + ")"); + } + } else { + System.out.println("Selected position: (" + selectedX + "," + selectedY + ")"); + if (selectedX == x && selectedY == y) { + System.out.println("Unselecting piece"); + selectedX = -1; + selectedY = -1; + } else { + Piece selectedPiece = getPieceAt(selectedX, selectedY); + if (selectedPiece != null) { + if (!selectedPiece.canMoveTo(x, y, this)) { + System.out.println("Invalid move for " + selectedPiece.getType() + " from (" + + selectedX + "," + selectedY + ") to (" + x + "," + y + ")"); + selectedX = -1; + selectedY = -1; + return; + } + System.out.println("Moving piece from (" + selectedX + "," + selectedY + ") to (" + x + "," + y + ")"); + Piece pieceAtDestination = getPieceAt(x, y); + if (pieceAtDestination != null) { + System.out.println("Capturing piece at destination: " + pieceAtDestination.getType() + ", isWhite=" + pieceAtDestination.isWhite()); + } else { + System.out.println("No piece at destination"); + } + Move move = new Move(selectedX, selectedY, x, y, selectedPiece, pieceAtDestination); + playMove(move); + selectedX = -1; + selectedY = -1; + } else { + System.out.println("No piece at (" + selectedX + "," + selectedY + ")"); + selectedX = -1; + selectedY = -1; + } + } + } + } - } - - public void playMove(Move move) { - // Remove any piece at the destination - pieces.removeIf(piece -> piece.getX() == move.getToX() && piece.getY() == move.getToY()); - // Remove the piece at the starting position - pieces.removeIf(piece -> piece.getX() == move.getFromX() && piece.getY() == move.getFromY()); - // Add the piece at the destination - Piece pieceMoved = move.getPieceMoved(); - pieces.add(new Piece(move.getToX(), move.getToY(), pieceMoved.getType(), pieceMoved.isWhite())); - // Update turn information - turnNumber++; - isTurnWhite = !isTurnWhite; - } + public boolean isSelected(int x, int y) { + return selectedX == x && selectedY == y; + } - private Piece getPieceAt(int x, int y) { + public void playMove(Move move) { + System.out.println("playMove: Moving from (" + move.getFromX() + "," + move.getFromY() + ") to (" + + move.getToX() + "," + move.getToY() + ")"); + System.out.println("Before move - Pieces: " + pieces.size()); + for (Piece piece : pieces) { + System.out.println("Piece at (" + piece.getX() + "," + piece.getY() + "): " + piece.getType() + ", isWhite=" + piece.isWhite()); + } + pieces.removeIf(piece -> piece.getX() == move.getToX() && piece.getY() == move.getToY()); + pieces.removeIf(piece -> piece.getX() == move.getFromX() && piece.getY() == move.getFromY()); + Piece pieceMoved = move.getPieceMoved(); + pieces.add(new Piece(move.getToX(), move.getToY(), pieceMoved.getType(), pieceMoved.isWhite())); + turnNumber++; + isTurnWhite = !isTurnWhite; + System.out.println("After move - Pieces: " + pieces.size()); + for (Piece piece : pieces) { + System.out.println("Piece at (" + piece.getX() + "," + piece.getY() + "): " + piece.getType() + ", isWhite=" + piece.isWhite()); + } + } + + private Piece getPieceAt(int x, int y) { for (Piece piece : pieces) { if (piece.getX() == x && piece.getY() == y) { return piece; } } return null; - } + } -} + public String[] toFileRep() { + return null; + } + + public Board(String[] array) { + // TODO + } + + public boolean isHighlighted(int x, int y) { + return false; + } + + public void undoLastMove() { + // TODO + } + + public Board(Board board) { + // TODO + } +} \ No newline at end of file diff --git a/src/backend/Piece.java b/src/backend/Piece.java index 710efb3..34ce044 100644 --- a/src/backend/Piece.java +++ b/src/backend/Piece.java @@ -30,4 +30,131 @@ public class Piece { return this.isWhite; } + public boolean canMoveTo(int toX, int toY, Board board) { + + if (x == toX && y == toY) { + return false; + } + + int dx = Math.abs(toX - x); + int dy = Math.abs(toY -y); + + switch (type) { + case Pawn: + return canPawnMoveTo(toX, toY, board); + case Rook: + return canRookMoveTo(toX, toY, dx, dy, board); + case Knight: + return canKnightMoveTo(dx, dy); + case Bishop: + return canBishopMoveTo(toX, toY, dx, dy, board); + case Queen: + return canQueenMoveTo(toX, toY, dx, dy, board); + case King: + return canKingMoveTo(dx, dy); + default: + return false; // should never happen + } + } + + private boolean canPawnMoveTo(int toX, int toY, Board board) { + int dx = toX - x; + int dy = toY - y; + int fowardDirection = isWhite ? -1 : 1; + int startingRow = isWhite ? 6 : 1; + + Piece pieceAtDestination = null; + for (Piece p : board.getPieces()) { + if (p.getX() == toX && p.getY() == toY) { + pieceAtDestination = p; + break; + + } + } + + if (dx == 0) { + if (pieceAtDestination != null) { + return true; + } + + if (dy == fowardDirection) { + return true; + } + + if (dy == 2 * fowardDirection && y == startingRow) { + int intermediateY = y + fowardDirection; + for (Piece p : board.getPieces()) { + if (p.getX() == x && p.getY() == intermediateY) { + return false; //path is blocked + } + } + return true; + } + } + + if (Math.abs(dx) == 1 && dy == fowardDirection) { + if (pieceAtDestination != null && pieceAtDestination.isWhite() != isWhite) { + return true; + } + } + return false; +} + + private boolean canRookMoveTo(int toX, int toY, int dx, int dy, Board board) { + // Rook moves horizontally or vertically + if (dx != 0 && dy != 0) { + return false; // Not a horizontal or vertical move + } + // Check the path for blocking pieces + return isPathClear(x, y, toX, toY, board); + } + + private boolean canKnightMoveTo(int dx, int dy) { + // Knight moves in an L-shape: (2,1) or (1,2) + return (dx == 2 && dy == 1) || (dx == 1 && dy == 2); + } + + private boolean canBishopMoveTo(int toX, int toY, int dx, int dy, Board board) { + // Bishop moves diagonally + if (dx != dy) { + return false; // Not a diagonal move + } + // Check the path for blocking pieces + return isPathClear(x, y, toX, toY, board); + } + + private boolean canQueenMoveTo(int toX, int toY, int dx, int dy, Board board) { + // Queen moves horizontally, vertically, or diagonally + if (dx != 0 && dy != 0 && dx != dy) { + return false; // Not a horizontal, vertical, or diagonal move + } + // Check the path for blocking pieces + return isPathClear(x, y, toX, toY, board); + } + + private boolean canKingMoveTo(int dx, int dy) { + // King moves one square in any direction + return dx <= 1 && dy <= 1; + } + + // Helper method to check if the path between (fromX, fromY) and (toX, toY) is clear + private boolean isPathClear(int fromX, int fromY, int toX, int toY, Board board) { + int dx = toX - fromX; + int dy = toY - fromY; + int steps = Math.max(Math.abs(dx), Math.abs(dy)); + int stepX = dx == 0 ? 0 : dx / Math.abs(dx); // Direction of x movement + int stepY = dy == 0 ? 0 : dy / Math.abs(dy); // Direction of y movement + + // Check each square along the path, excluding the starting and ending positions + for (int i = 1; i < steps; i++) { + int checkX = fromX + i * stepX; + int checkY = fromY + i * stepY; + for (Piece p : board.getPieces()) { + if (p.getX() == checkX && p.getY() == checkY) { + return false; // Path is blocked + } + } + } + return true; + } }