From f81c49d27c4988f9f35ab5c44690ed2d8e876c2c Mon Sep 17 00:00:00 2001 From: gitea Date: Tue, 15 Apr 2025 10:49:52 +0200 Subject: [PATCH] Part 1 --- OOP_3B6_Project/src/backend/Board.java | 366 ++++++++++++++++++++----- OOP_3B6_Project/src/backend/Move.java | 52 +++- OOP_3B6_Project/src/backend/Piece.java | 70 ++++- 3 files changed, 397 insertions(+), 91 deletions(-) diff --git a/OOP_3B6_Project/src/backend/Board.java b/OOP_3B6_Project/src/backend/Board.java index f165809..32613c7 100644 --- a/OOP_3B6_Project/src/backend/Board.java +++ b/OOP_3B6_Project/src/backend/Board.java @@ -1,99 +1,315 @@ + package backend; import java.util.ArrayList; +import java.util.Stack; public class Board { - public Board(int colNum, int lineNum) { - //TODO add constructor - } + private int width, height; + private ArrayList pieces; + private int turnNumber; + private boolean isWhiteTurn; + private Integer selectedX, selectedY; + private ArrayList highlightedSquares = new ArrayList<>(); + private Stack moveHistory = new Stack<>(); - public int getWidth() { - //TODO - return 0; - } + public Board(int colNum, int lineNum) { + this.width = colNum; + this.height = lineNum; + this.turnNumber = 0; + this.isWhiteTurn = true; + this.pieces = new ArrayList<>(); + this.selectedX = null; + this.selectedY = null; + } - public int getHeight() { - //TODO - return 0; - } + public int getWidth() { + return width; + } - public int getTurnNumber() { - //TODO - return 0; - } + public int getHeight() { + return height; + } - public boolean isTurnWhite() { - //TODO - return false; - } + public int getTurnNumber() { + return turnNumber; + } - public void setPiece(boolean isWhite, PieceType type, int x, int y) { - //TODO - } + public boolean isTurnWhite() { + return isWhiteTurn; + } - public void populateBoard() { - //TODO - } - - public void cleanBoard() { - //TODO - } - - public String toString() { - //TODO - return ""; - } - - public ArrayList getPieces() { - ArrayList pieces = new ArrayList<>(); - //TODO - - return pieces; - } + public void setPiece(boolean isWhite, PieceType type, int x, int y) { + removePieceAt(x, y); + pieces.add(new Piece(x, y, isWhite, type)); + } - public void userTouch(int x, int y) { - //TODO - - } + public void populateBoard() { + PieceType[] backRow = { + PieceType.Rook, PieceType.Knight, PieceType.Bishop, PieceType.Queen, + PieceType.King, PieceType.Bishop, PieceType.Knight, PieceType.Rook + }; - public boolean isSelected(int x, int y) { - //TODO - return false; - } - - /* saving-loading feature :*/ + for (int x = 0; x < width; x++) { + pieces.add(new Piece(x, 1, false, PieceType.Pawn)); // Black pawns + pieces.add(new Piece(x, 6, true, PieceType.Pawn)); // White pawns + } - public String[] toFileRep() { - //TODO - return null; - } + for (int x = 0; x < width; x++) { + pieces.add(new Piece(x, 0, false, backRow[x])); // Black back row + pieces.add(new Piece(x, 7, true, backRow[x])); // White back row + } + } + + public void cleanBoard() { + pieces.clear(); + turnNumber = 0; + isWhiteTurn = true; + selectedX = null; + selectedY = null; + highlightedSquares.clear(); + moveHistory.clear(); + } + //create the board + public String toString() { + StringBuilder sb = new StringBuilder(); + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + Piece p = getPieceAt(x, y); + if (p != null) { + sb.append(p.isWhite() ? "W" : "B"); + sb.append(p.getType().getSummary()); + } else { + sb.append("- "); + } + sb.append(" "); + } + sb.append("\n"); + } + return sb.toString(); + } + + public ArrayList getPieces() { + return new ArrayList<>(pieces); + } - public Board(String[] array) { - //TODO + public void userTouch(int x, int y) { + Piece clickedPiece = getPieceAt(x, y); - } - - /* The following methods require more work ! */ + // No selection yet + if (selectedX == null || selectedY == null) { + if (clickedPiece != null && clickedPiece.isWhite() == isWhiteTurn) { + selectedX = x; + selectedY = y; + highlightedSquares = computeLegalMoves(clickedPiece); + } + return; + } - public boolean isHighlighted(int x, int y) { - //TODO - return false; - } + // Click again to unselect + if (selectedX == x && selectedY == y) { + selectedX = null; + selectedY = null; + highlightedSquares.clear(); + return; + } - public void undoLastMove() { - //TODO - - } + // Try to move + for (int[] move : highlightedSquares) { + if (move[0] == x && move[1] == y) { + Piece selectedPiece = getPieceAt(selectedX, selectedY); + Piece captured = getPieceAt(x, y); - public Board(Board board) { - //TODO + // Store move for undo + Move m = new Move( + selectedX, selectedY, x, y, + selectedPiece.isWhite(), selectedPiece.getType(), captured + ); + moveHistory.push(m); - } - - public void playMove(Move move) { - //TODO + removePieceAt(x, y); // capture + removePieceAt(selectedX, selectedY); + pieces.add(new Piece(x, y, selectedPiece.isWhite(), selectedPiece.getType())); - } + turnNumber++; + isWhiteTurn = !isWhiteTurn; + break; + } + } + selectedX = null; + selectedY = null; + highlightedSquares.clear(); + } + + public boolean isSelected(int x, int y) { + return selectedX != null && selectedY != null && selectedX == x && selectedY == y; + } + + public String[] toFileRep() { + // TODO: Part 3 - Save + return null; + } + + public Board(String[] array) { + // TODO: Part 3 - Load + } + + public boolean isHighlighted(int x, int y) { + for (int[] move : highlightedSquares) { + if (move[0] == x && move[1] == y) return true; + } + return false; + } + + public void undoLastMove() { + if (moveHistory.isEmpty()) return; + + Move lastMove = moveHistory.pop(); + + // Remove moved piece from destination + removePieceAt(lastMove.getToX(), lastMove.getToY()); + + // Restore original piece + pieces.add(new Piece( + lastMove.getFromX(), + lastMove.getFromY(), + lastMove.isWhite(), + lastMove.getType() + )); + + // Restore captured piece, if any + if (lastMove.getCapturedPiece() != null) { + Piece p = lastMove.getCapturedPiece(); + pieces.add(new Piece(p.getX(), p.getY(), p.isWhite(), p.getType())); + } + + turnNumber--; + isWhiteTurn = !isWhiteTurn; + } + + public Board(Board board) { + // TODO: Part 4 - Clone + } + + public void playMove(Move move) { + // TODO: Part 4 - AutoPlayer + } + + // ========== Helper Methods ========== + + private void removePieceAt(int x, int y) { + pieces.removeIf(p -> p.getX() == x && p.getY() == y); + } + + private Piece getPieceAt(int x, int y) { + for (Piece p : pieces) { + if (p.getX() == x && p.getY() == y) return p; + } + return null; + } + + private ArrayList computeLegalMoves(Piece piece) { + ArrayList moves = new ArrayList<>(); + int x = piece.getX(); + int y = piece.getY(); + boolean isWhite = piece.isWhite(); + + switch (piece.getType()) { + case Pawn: + int dir = isWhite ? -1 : 1; + int startRow = isWhite ? 6 : 1; + + if (getPieceAt(x, y + dir) == null) { + moves.add(new int[]{x, y + dir}); + if (y == startRow && getPieceAt(x, y + 2 * dir) == null) { + moves.add(new int[]{x, y + 2 * dir}); + } + } + for (int dx = -1; dx <= 1; dx += 2) { + int nx = x + dx; + int ny = y + dir; + if (nx >= 0 && nx < width && ny >= 0 && ny < height) { + Piece target = getPieceAt(nx, ny); + if (target != null && target.isWhite() != isWhite) { + moves.add(new int[]{nx, ny}); + } + } + } + break; + + case Rook: + addSlidingMoves(moves, x, y, isWhite, new int[][]{{1,0},{-1,0},{0,1},{0,-1}}); + break; + + case Bishop: + addSlidingMoves(moves, x, y, isWhite, new int[][]{{1,1},{1,-1},{-1,1},{-1,-1}}); + break; + + case Queen: + addSlidingMoves(moves, x, y, isWhite, new int[][]{ + {1,0},{-1,0},{0,1},{0,-1},{1,1},{1,-1},{-1,1},{-1,-1} + }); + break; + + case Knight: + int[][] knightMoves = { + {x+1, y+2}, {x+1, y-2}, {x-1, y+2}, {x-1, y-2}, + {x+2, y+1}, {x+2, y-1}, {x-2, y+1}, {x-2, y-1} + }; + for (int[] move : knightMoves) { + int nx = move[0]; + int ny = move[1]; + if (nx >= 0 && nx < width && ny >= 0 && ny < height) { + Piece target = getPieceAt(nx, ny); + if (target == null || target.isWhite() != isWhite) { + moves.add(new int[]{nx, ny}); + } + } + } + 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; + int ny = y + dy; + if (nx >= 0 && nx < width && ny >= 0 && ny < height) { + Piece target = getPieceAt(nx, ny); + if (target == null || target.isWhite() != isWhite) { + moves.add(new int[]{nx, ny}); + } + } + } + } + break; + + default: + break; + } + return moves; + } + + private void addSlidingMoves(ArrayList moves, int x, int y, boolean isWhite, int[][] directions) { + for (int[] dir : directions) { + for (int i = 1; i < 8; i++) { + int nx = x + dir[0] * i; + int ny = y + dir[1] * i; + if (nx < 0 || nx >= width || ny < 0 || ny >= height) break; + Piece target = getPieceAt(nx, ny); + if (target == null) { + moves.add(new int[]{nx, ny}); + } else { + if (target.isWhite() != isWhite) { + moves.add(new int[]{nx, ny}); + } + break; + } + } + } + } + } + diff --git a/OOP_3B6_Project/src/backend/Move.java b/OOP_3B6_Project/src/backend/Move.java index 5f64282..3419161 100644 --- a/OOP_3B6_Project/src/backend/Move.java +++ b/OOP_3B6_Project/src/backend/Move.java @@ -1,5 +1,55 @@ package backend; + + public class Move { - + +private int fromX, fromY; + +private int toX, toY; + +private boolean isWhite; + +private PieceType type; + +private Piece capturedPiece; + + + +public Move(int fromX, int fromY, int toX, int toY, boolean isWhite, PieceType type, Piece capturedPiece) { + +this.fromX = fromX; + +this.fromY = fromY; + +this.toX = toX; + +this.toY = toY; + +this.isWhite = isWhite; + +this.type = type; + +this.capturedPiece = capturedPiece; + } + + + +// Getters + +public int getFromX() { return fromX; } + +public int getFromY() { return fromY; } + +public int getToX() { return toX; } + +public int getToY() { return toY; } + +public boolean isWhite() { return isWhite; } + +public PieceType getType() { return type; } + +public Piece getCapturedPiece() { return capturedPiece; } + +} \ No newline at end of file diff --git a/OOP_3B6_Project/src/backend/Piece.java b/OOP_3B6_Project/src/backend/Piece.java index ffa88bb..978c561 100644 --- a/OOP_3B6_Project/src/backend/Piece.java +++ b/OOP_3B6_Project/src/backend/Piece.java @@ -1,21 +1,61 @@ package backend; + + public class Piece { - public int getX() { - return 0; - } + + + + +private int x, y; + +private boolean isWhite; + +private PieceType type; + + + +public Piece(int x, int y, boolean isWhite, PieceType type) { + +this.x = x; + +this.y = y; + +this.isWhite = isWhite; + +this.type = type; + +} + + + +public int getX() { + +return x; + +} + + + +public int getY() { + +return y; + +} + +public PieceType getType() { + +return type; + +} + + + +public boolean isWhite() { + +return isWhite; + +} - public int getY() { - return 0; - } - - public PieceType getType() { - return null; - } - - public boolean isWhite() { - return false; - } - }