diff --git a/src/backend/Board.java b/src/backend/Board.java index d92faed..5434419 100644 --- a/src/backend/Board.java +++ b/src/backend/Board.java @@ -90,8 +90,12 @@ public class Board { } } } + public Piece getPiece(int x, int y) { + if (!isInBounds (x, y)) return null; + return board [x][y]; + } - private void clearConsole() { + private void clearConsole() { // ***************CONSOLE for (int i = 0; i < 50; i++) { System.out.println(); // Print 50 empty lines to "clear" the console } @@ -111,11 +115,21 @@ public class Board { } else { // convert each piece of both color into a character Piece piece = board[x][y]; - String pieceChar = piece.getType().getSummary(); + char pieceChar; + + switch (piece.getType()) { // switch function avoids too many if-else + case King: pieceChar = 'K'; break; + case Queen: pieceChar = 'Q'; break; + case Bishop: pieceChar = 'B'; break; + case Knight: pieceChar = 'N'; break; // N because we already have King + case Rook: pieceChar = 'R'; break; + case Pawn: pieceChar = 'P'; break; + default: pieceChar = '?'; break; // safety net + } // Make black pieces in lowercase if (!piece.isWhite()) { - pieceChar = pieceChar.toLowerCase(); + pieceChar = Character.toLowerCase(pieceChar); } str.append(pieceChar).append(" "); // gives structure to the output @@ -147,22 +161,22 @@ public class Board { // user clicks on the board public void userTouch(int x, int y) { - if (selectedX == -1 && selectedY == -1) { + if (selectedX == -1 && selectedY == -1) { // This condition is only possible at the very start of the game // check if the position is empty and the color if (board[x][y] != null && board[x][y].isWhite() == isTurnWhite()) { // select it as active location selectedX = x; selectedY = y; - highlightedPositions = getValidMoves(board[x][y]); // compute valid moves + highlightedPositions = getValidMoves(board[x][y]); // compute moves } } else { if (x == selectedX && y == selectedY) { - // unselect it + // unselect it if the destination is unvalid (not highlighted) selectedX = -1; selectedY = -1; highlightedPositions.clear(); } else { - // allow move if valid destination + // move if valid destination boolean valid = false; for (int[] pos : highlightedPositions) { if (pos[0] == x && pos[1] == y) { @@ -192,7 +206,7 @@ public class Board { return (x == selectedX && y == selectedY); // true if matching position } - public boolean isHighlighted(int x, int y) { // checking for a given position if the square is highlighted or not + public boolean isHighlighted(int x, int y) { for (int[] pos : highlightedPositions) { if (pos[0] == x && pos[1] == y) { return true; @@ -202,112 +216,12 @@ public class Board { } /* utility methods */ - private boolean isInBounds(int x, int y) { + public boolean isInBounds(int x, int y) { return x >= 0 && x < width && y >= 0 && y < height; } - private void addLinearMoves(ArrayList moves, int x, int y, Piece piece, int dx, int dy) { - int nx = x + dx; - int ny = y + dy; - while (isInBounds(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 += dx; - ny += dy; - } - } - private ArrayList getValidMoves(Piece piece) { - ArrayList moves = new ArrayList<>(); - int x = piece.getX(); - int y = piece.getY(); - - switch (piece.getType()) { - case Pawn: - int direction = piece.isWhite() ? -1 : 1; - int nextY = y + direction; - - // forward move - if (isInBounds(x, nextY) && board[x][nextY] == null) { - moves.add(new int[]{x, nextY}); - - // double move from starting position - int startRow = piece.isWhite() ? 6 : 1; - int doubleStepY = y + 2 * direction; - if (y == startRow && isInBounds(x, doubleStepY) && board[x][doubleStepY] == null) { - moves.add(new int[]{x, doubleStepY}); - } - } - - // diagonal captures - for (int dx = -1; dx <= 1; dx += 2) { - int nx = x + dx; - if (isInBounds(nx, nextY) && board[nx][nextY] != null && board[nx][nextY].isWhite() != piece.isWhite()) { - moves.add(new int[]{nx, nextY}); - } - } - break; -//for each piece, we calculate the positions it can end up in from an initial position - case Rook: - addLinearMoves(moves, x, y, piece, 1, 0); - addLinearMoves(moves, x, y, piece, -1, 0); - addLinearMoves(moves, x, y, piece, 0, 1); - addLinearMoves(moves, x, y, piece, 0, -1); - break; - - case Bishop: - addLinearMoves(moves, x, y, piece, 1, 1); - addLinearMoves(moves, x, y, piece, -1, 1); - addLinearMoves(moves, x, y, piece, 1, -1); - addLinearMoves(moves, x, y, piece, -1, -1); - break; - - case Queen: - for (int dx = -1; dx <= 1; dx++) { - for (int dy = -1; dy <= 1; dy++) { - if (dx != 0 || dy != 0) { - addLinearMoves(moves, x, y, piece, dx, dy); - } - } - } - break; - - case King: - for (int dx = -1; dx <= 1; dx++) { - for (int dy = -1; dy <= 1; dy++) { - if (dx != 0 || dy != 0) { - int nx = x + dx; - int ny = y + dy; - if (isInBounds(nx, ny) && (board[nx][ny] == null || board[nx][ny].isWhite() != piece.isWhite())) { - moves.add(new int[]{nx, ny}); - } - } - } - } - break; - - case Knight: - int[][] jumps = { - {1, 2}, {2, 1}, {-1, 2}, {-2, 1}, // possible moves for - {-1, -2}, {-2, -1}, {1, -2}, {2, -1} - }; - for (int[] j : jumps) { - int nx = x + j[0]; - int ny = y + j[1]; - if (isInBounds(nx, ny) && (board[nx][ny] == null || board[nx][ny].isWhite() != piece.isWhite())) { - moves.add(new int[]{nx, ny}); - } - } - break; - } - - return moves; + return piece.getValidMoves(this); } public String[] toFileRep() { diff --git a/src/backend/Move.java b/src/backend/Move.java index 2b49255..6d77bf7 100644 --- a/src/backend/Move.java +++ b/src/backend/Move.java @@ -1,7 +1,11 @@ package backend; -import java.util.ArrayList; +import java.util.Optional; +/** + * Represents a chess move, including the starting and ending positions, + * the moving piece, and an optional captured piece. + */ public class Move { } diff --git a/src/backend/Pawn.java b/src/backend/Pawn.java new file mode 100644 index 0000000..8123ed9 --- /dev/null +++ b/src/backend/Pawn.java @@ -0,0 +1,5 @@ +package backend; + +public class Pawn { + +} diff --git a/src/backend/Piece.java b/src/backend/Piece.java index 55cd98a..531c84d 100644 --- a/src/backend/Piece.java +++ b/src/backend/Piece.java @@ -22,6 +22,7 @@ public class Piece { public int getY() { return y; } + public PieceType getType() { return type; @@ -30,5 +31,116 @@ public class Piece { public boolean isWhite() { return pieceColor; } - + public ArrayList getValidMoves(Board board) { + ArrayList moves = new ArrayList<>(); + int x = this.getX(); + int y = this.getY(); + + switch (type) { + case Pawn: + int direction = isWhite() ? -1 : 1; + int nextY = y + direction; + + // forward move + if (board.isInBounds(x, nextY) && board.getPiece(x, nextY) == null) { + moves.add(new int[]{x, nextY}); + + // double move from starting position + int startRow = isWhite() ? 6 : 1; + int doubleStepY = y + 2 * direction; + if (y == startRow && board.isInBounds(x, doubleStepY) && board.getPiece(x, doubleStepY) == null) { + moves.add(new int[]{x, doubleStepY}); + } + } + + // diagonal captures + for (int dx = -1; dx <= 1; dx += 2) { + int nx = x + dx; + if (board.isInBounds(nx, nextY)) { + Piece target = board.getPiece(nx, nextY); + if (target != null && target.isWhite() != this.isWhite()) { + moves.add(new int[]{nx, nextY}); + } + } + } + break; + + case Rook: + addLinearMoves(board, moves, x, y, 1, 0); + addLinearMoves(board, moves, x, y, -1, 0); + addLinearMoves(board, moves, x, y, 0, 1); + addLinearMoves(board, moves, x, y, 0, -1); + break; + + case Bishop: + addLinearMoves(board, moves, x, y, 1, 1); + addLinearMoves(board, moves, x, y, -1, 1); + addLinearMoves(board, moves, x, y, 1, -1); + addLinearMoves(board, moves, x, y, -1, -1); + break; + + case Queen: + for (int dx = -1; dx <= 1; dx++) { + for (int dy = -1; dy <= 1; dy++) { + if (dx != 0 || dy != 0) { + addLinearMoves(board, moves, x, y, dx, dy); + } + } + } + break; + + case King: + for (int dx = -1; dx <= 1; dx++) { + for (int dy = -1; dy <= 1; dy++) { + if (dx != 0 || dy != 0) { + int nx = x + dx; + int ny = y + dy; + if (board.isInBounds(nx, ny)) { + Piece target = board.getPiece(nx, ny); + if (target == null || target.isWhite() != this.isWhite()) { + moves.add(new int[]{nx, ny}); + } + } + } + } + } + break; + + case Knight: + int[][] jumps = { + {1, 2}, {2, 1}, {-1, 2}, {-2, 1}, + {-1, -2}, {-2, -1}, {1, -2}, {2, -1} + }; + for (int[] j : jumps) { + int nx = x + j[0]; + int ny = y + j[1]; + if (board.isInBounds(nx, ny)) { + Piece target = board.getPiece(nx, ny); + if (target == null || target.isWhite() != this.isWhite()) { + moves.add(new int[]{nx, ny}); + } + } + } + break; + } + + return moves; + } + private void addLinearMoves(Board board, ArrayList moves, int x, int y, int dx, int dy) { + int nx = x + dx; + int ny = y + dy; + while (board.isInBounds(nx, ny)) { + Piece target = board.getPiece(nx, ny); + if (target == null) { + moves.add(new int[]{nx, ny}); + } else { + if (target.isWhite() != this.isWhite()) { + moves.add(new int[]{nx, ny}); + } + break; + } + nx += dx; + ny += dy; + } + } } \ No newline at end of file