From cf9c7bbd8c88b30f2ac8f1d78462e54b909383a1 Mon Sep 17 00:00:00 2001 From: Tilman Crosetti Date: Thu, 15 May 2025 14:47:26 +0200 Subject: [PATCH] Modification of pieces rules, modif AutoPlayer+ isHighlight method+ UserTouch --- OOP_2B1_Project/src/backend/AutoPlayer.java | 53 ++++---- OOP_2B1_Project/src/backend/Bishop.java | 18 +-- OOP_2B1_Project/src/backend/Board.java | 129 +++++++++----------- OOP_2B1_Project/src/backend/King.java | 26 ++-- OOP_2B1_Project/src/backend/Knight.java | 22 ++-- OOP_2B1_Project/src/backend/Pawn.java | 44 +++---- OOP_2B1_Project/src/backend/Queen.java | 19 +-- OOP_2B1_Project/src/backend/Rook.java | 17 +-- 8 files changed, 139 insertions(+), 189 deletions(-) diff --git a/OOP_2B1_Project/src/backend/AutoPlayer.java b/OOP_2B1_Project/src/backend/AutoPlayer.java index 97dd4dc..8c6587b 100644 --- a/OOP_2B1_Project/src/backend/AutoPlayer.java +++ b/OOP_2B1_Project/src/backend/AutoPlayer.java @@ -1,25 +1,21 @@ package backend; + import java.util.List; public class AutoPlayer { - - - /** - * returns the best Move to try on provided board for active player - * @param board - * @return - */ + public Move computeBestMove(Board board) { - List moves = board.getAllLegalMoves(board.isTurnWhite()); + boolean aiIsWhite = board.isTurnWhite(); // Important! + List moves = board.getAllLegalMoves(aiIsWhite); + Move bestMove = null; int bestScore = Integer.MIN_VALUE; for (Move move : moves) { - Board simulated = board.clone(); // Clone the board + Board simulated = board.clone(); simulated.playMove(move); - int score = evaluate(simulated, board.isTurnWhite()); - + int score = evaluate(simulated, aiIsWhite); // Pass correct side if (score > bestScore) { bestScore = score; bestMove = move; @@ -28,26 +24,25 @@ public class AutoPlayer { return bestMove; } - - private int evaluate(Board board, boolean forWhite) { + + private int evaluate(Board board, boolean forWhite) { int score = 0; - for (Piece piece : board.getAllPieces()) { + for (Piece piece : board.getPieces()) { int value = getPieceValue(piece); - score += (piece.isWhite() == forWhite) ? value : -value; + score += piece.isWhite() == forWhite ? value : -value; } return score; } - private int getPieceValue(Piece piece) { - switch (piece.getType()) { - case Pawn: return 1; - case Knight: case Bishop: return 3; - case Rook: return 5; - case Queen: return 9; - case King: return 100; - default: return 0; - } - } - - - -} + + private int getPieceValue(Piece piece) { + switch (piece.getType()) { + case Pawn: return 1; + case Knight: + case Bishop: return 3; + case Rook: return 5; + case Queen: return 9; + case King: return 100; + default: return 0; + } + } +} \ No newline at end of file diff --git a/OOP_2B1_Project/src/backend/Bishop.java b/OOP_2B1_Project/src/backend/Bishop.java index 1218be0..fd920b3 100644 --- a/OOP_2B1_Project/src/backend/Bishop.java +++ b/OOP_2B1_Project/src/backend/Bishop.java @@ -3,22 +3,15 @@ package backend; import java.util.ArrayList; import java.util.List; -public class Bishop extends Piece { +class Bishop extends Piece { public Bishop(boolean isWhite, int x, int y) { super(isWhite, PieceType.Bishop, x, y); } - @Override - public PieceType getType() { - return PieceType.Bishop; - } - @Override public List getLegalMoves(Board board, int row, int col) { List moves = new ArrayList<>(); - int[][] directions = { - {-1, -1}, {-1, 1}, {1, -1}, {1, 1} - }; + int[][] directions = {{-1, -1}, {-1, 1}, {1, -1}, {1, 1}}; for (int[] dir : directions) { int r = row + dir[0]; @@ -28,20 +21,19 @@ public class Bishop extends Piece { if (target == null) { moves.add(new Move(this, row, col, r, c)); } else { - if (target.isWhite() != this.isWhite) - moves.add(new Move(this, row, col, r, c)); + if (target.isWhite() != isWhite) + moves.add(new Move(this, row, col, r, c, target)); break; } r += dir[0]; c += dir[1]; } } - return moves; } @Override public Piece clone() { - return new Bishop(this.isWhite, this.x, this.y); + return new Bishop(isWhite, x, y); } } \ No newline at end of file diff --git a/OOP_2B1_Project/src/backend/Board.java b/OOP_2B1_Project/src/backend/Board.java index db370d5..bb1d816 100644 --- a/OOP_2B1_Project/src/backend/Board.java +++ b/OOP_2B1_Project/src/backend/Board.java @@ -1,5 +1,5 @@ package backend; -import javax.print.attribute.standard.MediaSize.Other; + import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.Clip; @@ -147,53 +147,45 @@ public class Board implements Cloneable { public void userTouch(int x, int y) { if (selectedX == null && selectedY == null) { Piece pieceAtPos = getPieceAt(x, y); - if (pieceAtPos != null) { + + if (pieceAtPos != null && pieceAtPos.isWhite() == turnIsWhite) { selectedX = x; selectedY = y; - // Calculate and highlight valid moves for the selected piece highlightedPositions.clear(); - List legalMoves = pieceAtPos.getLegalMoves(this, x, y); + + List legalMoves = pieceAtPos.getLegalMoves(this, y, x); for (Move move : legalMoves) { highlightedPositions.add(new int[]{move.getToCol(), move.getToRow()}); } } } else { if (selectedX == x && selectedY == y) { - // Unselect the piece and clear highlighted positions selectedX = null; selectedY = null; highlightedPositions.clear(); } else { Piece pieceToMove = getPieceAt(selectedX, selectedY); - if (pieceToMove != null) { - Piece pieceAtDestination = getPieceAt(x, y); - if (pieceAtDestination == null || pieceAtDestination.isWhite() != pieceToMove.isWhite()) { - saveStateToHistory(); - if (pieceAtDestination != null) { - pieces.remove(pieceAtDestination); + + if (pieceToMove != null && pieceToMove.isWhite() == turnIsWhite) { + List legalMoves = pieceToMove.getLegalMoves(this, selectedY, selectedX); + + for (Move move : legalMoves) { + if (move.getToCol() == x && move.getToRow() == y) { + saveStateToHistory(); + playMove(move); + break; } - pieces.remove(pieceToMove); - - // Create a new instance of the specific piece type - Piece newPiece = makeNewPiece(pieceToMove.getType(), pieceToMove.isWhite(), x, y); - pieces.add(newPiece); - - playMoveSound(); - - turnNumber++; - turnIsWhite = !turnIsWhite; - - // Clear highlighted positions after moving the piece - highlightedPositions.clear(); } } + selectedX = null; selectedY = null; + highlightedPositions.clear(); } } } - + private Piece makeNewPiece(PieceType type, boolean isWhite, int x, int y) { Piece newPiece; switch (type) { @@ -238,12 +230,12 @@ public class Board implements Cloneable { public Piece getPieceAt(int x, int y) { - for (Piece piece : pieces) { - if (piece.getX() == x && piece.getY() == y) { - return piece; - } - } - return null; + for (Piece piece : pieces) { + if (piece.getX() == x && piece.getY() == y) { + return piece; + } + } + return null; } @@ -302,8 +294,9 @@ public class Board implements Cloneable { /* The following methods require more work ! */ public boolean isHighlighted(int x, int y) { - for (int[] position : highlightedPositions) { - if (position[0] == x && position[1] == y) { + // Ensure coordinates are correct + for (int[] pos : highlightedPositions) { + if (pos[0] == x && pos[1] == y) { return true; } } @@ -337,45 +330,38 @@ public class Board implements Cloneable { } public void playMove(Move move) { - Piece pieceToMove = getPieceAt(move.getFromCol(), move.getFromRow()); - if (pieceToMove != null) { - Piece pieceAtDestination = getPieceAt(move.getToCol(), move.getToRow()); - if (pieceAtDestination != null) { - pieces.remove(pieceAtDestination); - } - pieces.remove(pieceToMove); + // Note: getPieceAt(x, y), x = col, y = row + Piece pieceToMove = getPieceAt(move.getFromCol(), move.getFromRow()); - // Create a new instance of the specific piece type - Piece newPiece; - switch (pieceToMove.getType()) { - case Pawn: - newPiece = new Pawn(pieceToMove.isWhite(), move.getToCol(), move.getToRow()); - break; - case King: - newPiece = new King(pieceToMove.isWhite(), move.getToCol(), move.getToRow()); - break; - case Queen: - newPiece = new Queen(pieceToMove.isWhite(), move.getToCol(), move.getToRow()); - break; - case Rook: - newPiece = new Rook(pieceToMove.isWhite(), move.getToCol(), move.getToRow()); - break; - case Bishop: - newPiece = new Bishop(pieceToMove.isWhite(), move.getToCol(), move.getToRow()); - break; - case Knight: - newPiece = new Knight(pieceToMove.isWhite(), move.getToCol(), move.getToRow()); - break; - default: - throw new IllegalArgumentException("Unknown piece type"); - } - pieces.add(newPiece); + if (pieceToMove == null) { + System.err.println("Invalid move: no piece at source"); + return; + } - turnNumber++; - turnIsWhite = !turnIsWhite; - } - } + if (pieceToMove.isWhite() != turnIsWhite) { + System.err.println("Invalid move: wrong turn"); + return; + } + // Remove captured piece, if any + Piece capturedPiece = getPieceAt(move.getToCol(), move.getToRow()); + if (capturedPiece != null) { + pieces.remove(capturedPiece); + } + + pieces.remove(pieceToMove); + + // Add moved piece at the new position + Piece movedPiece = makeNewPiece(pieceToMove.getType(), pieceToMove.isWhite(), move.getToCol(), move.getToRow()); + pieces.add(movedPiece); + + // Update turn info + turnIsWhite = !turnIsWhite; + turnNumber++; + + // Play move sound if enabled + playMoveSound(); + } public ArrayList getAllLegalMoves(boolean isWhite) { ArrayList moves = new ArrayList<>(); @@ -405,11 +391,10 @@ public class Board implements Cloneable { return pieces; } - public boolean isInBounds(int row, int col) { - return row >= 0 && row < 8 && col >= 0 && col < 8; + public boolean isInBounds(int x, int y) { + return x >= 0 && x < Width && y >= 0 && y < Height; } - @Override public Board clone() { try { diff --git a/OOP_2B1_Project/src/backend/King.java b/OOP_2B1_Project/src/backend/King.java index 3d31626..280953a 100644 --- a/OOP_2B1_Project/src/backend/King.java +++ b/OOP_2B1_Project/src/backend/King.java @@ -3,39 +3,35 @@ package backend; import java.util.ArrayList; import java.util.List; -public class King extends Piece { +class King extends Piece { public King(boolean isWhite, int x, int y) { super(isWhite, PieceType.King, x, y); } - @Override - public PieceType getType() { - return PieceType.King; - } - @Override public List getLegalMoves(Board board, int row, int col) { List moves = new ArrayList<>(); - int[] d = {-1, 0, 1}; - - for (int dr : d) { - for (int dc : d) { + for (int dr = -1; dr <= 1; dr++) { + for (int dc = -1; dc <= 1; dc++) { if (dr == 0 && dc == 0) continue; int r = row + dr; int c = col + dc; if (board.isInBounds(r, c)) { - Piece p = board.getPieceAt(r, c); - if (p == null || p.isWhite() != this.isWhite) - moves.add(new Move(this, row, col, r, c)); + Piece target = board.getPieceAt(r, c); + if (target == null || target.isWhite() != isWhite) { + if (target != null) + moves.add(new Move(this, row, col, r, c, target)); + else + moves.add(new Move(this, row, col, r, c)); + } } } } - return moves; } @Override public Piece clone() { - return new King(this.isWhite, this.x, this.y); + return new King(isWhite, x, y); } } \ No newline at end of file diff --git a/OOP_2B1_Project/src/backend/Knight.java b/OOP_2B1_Project/src/backend/Knight.java index 1a43c34..d8c7e43 100644 --- a/OOP_2B1_Project/src/backend/Knight.java +++ b/OOP_2B1_Project/src/backend/Knight.java @@ -3,16 +3,11 @@ package backend; import java.util.ArrayList; import java.util.List; -public class Knight extends Piece { +class Knight extends Piece { public Knight(boolean isWhite, int x, int y) { super(isWhite, PieceType.Knight, x, y); } - @Override - public PieceType getType() { - return PieceType.Knight; - } - @Override public List getLegalMoves(Board board, int row, int col) { List moves = new ArrayList<>(); @@ -25,17 +20,20 @@ public class Knight extends Piece { int r = row + offset[0]; int c = col + offset[1]; if (board.isInBounds(r, c)) { - Piece p = board.getPieceAt(r, c); - if (p == null || p.isWhite() != this.isWhite) - moves.add(new Move(this, row, col, r, c)); + Piece target = board.getPieceAt(r, c); + if (target == null || target.isWhite() != isWhite) { + if (target != null) + moves.add(new Move(this, row, col, r, c, target)); + else + moves.add(new Move(this, row, col, r, c)); + } } } - return moves; } @Override public Piece clone() { - return new Knight(this.isWhite, this.x, this.y); + return new Knight(isWhite, x, y); } -} +} \ No newline at end of file diff --git a/OOP_2B1_Project/src/backend/Pawn.java b/OOP_2B1_Project/src/backend/Pawn.java index 156291d..a6c394a 100644 --- a/OOP_2B1_Project/src/backend/Pawn.java +++ b/OOP_2B1_Project/src/backend/Pawn.java @@ -3,41 +3,37 @@ package backend; import java.util.ArrayList; import java.util.List; + public class Pawn extends Piece { public Pawn(boolean isWhite, int x, int y) { super(isWhite, PieceType.Pawn, x, y); } - @Override - public PieceType getType() { - return PieceType.Pawn; - } - @Override public List getLegalMoves(Board board, int row, int col) { List moves = new ArrayList<>(); - int direction = isWhite ? -1 : 1; + int direction = isWhite ? -1 : 1; // White moves up, black down int startRow = isWhite ? 6 : 1; - // Forward 1 square - int forwardRow = row + direction; - if (board.isInBounds(forwardRow, col) && board.getPieceAt(forwardRow, col) == null) { - moves.add(new Move(this, row, col, forwardRow, col)); - - // Forward 2 squares from starting position - int doubleForwardRow = row + 2 * direction; - if (row == startRow && board.getPieceAt(doubleForwardRow, col) == null) { - moves.add(new Move(this, row, col, doubleForwardRow, col)); + // Move forward + int oneStep = row + direction; + if (board.isInBounds(col, oneStep) && board.getPieceAt(col, oneStep) == null) { + moves.add(new Move(this, row, col, oneStep, col)); + int twoStep = row + 2 * direction; + if (row == startRow && board.isInBounds(col, twoStep) && board.getPieceAt(col, twoStep) == null) { + moves.add(new Move(this, row, col, twoStep, col)); } } - // Diagonal captures - for (int dc = -1; dc <= 1; dc += 2) { - int c = col + dc; - if (board.isInBounds(forwardRow, c)) { - Piece target = board.getPieceAt(forwardRow, c); - if (target != null && target.isWhite() != this.isWhite) - moves.add(new Move(this, row, col, forwardRow, c)); + // Captures + int[] dx = {-1, 1}; + for (int d : dx) { + int targetCol = col + d; + if (board.isInBounds(targetCol, oneStep)) { + Piece enemy = board.getPieceAt(targetCol, oneStep); + if (enemy != null && enemy.isWhite() != this.isWhite) { + moves.add(new Move(this, row, col, oneStep, targetCol, enemy)); + } } } @@ -46,6 +42,6 @@ public class Pawn extends Piece { @Override public Piece clone() { - return new Pawn(this.isWhite, this.x, this.y); + return new Pawn(isWhite, x, y); } -} +} \ No newline at end of file diff --git a/OOP_2B1_Project/src/backend/Queen.java b/OOP_2B1_Project/src/backend/Queen.java index 8b8692d..706e186 100644 --- a/OOP_2B1_Project/src/backend/Queen.java +++ b/OOP_2B1_Project/src/backend/Queen.java @@ -3,22 +3,17 @@ package backend; import java.util.ArrayList; import java.util.List; -public class Queen extends Piece { +class Queen extends Piece { public Queen(boolean isWhite, int x, int y) { super(isWhite, PieceType.Queen, x, y); } - @Override - public PieceType getType() { - return PieceType.Queen; - } - @Override public List getLegalMoves(Board board, int row, int col) { List moves = new ArrayList<>(); int[][] directions = { - {-1, 0}, {1, 0}, {0, -1}, {0, 1}, // Rook-like - {-1, -1}, {-1, 1}, {1, -1}, {1, 1} // Bishop-like + {-1, 0}, {1, 0}, {0, -1}, {0, 1}, + {-1, -1}, {-1, 1}, {1, -1}, {1, 1} }; for (int[] dir : directions) { @@ -29,21 +24,19 @@ public class Queen extends Piece { if (target == null) { moves.add(new Move(this, row, col, r, c)); } else { - if (target.isWhite() != this.isWhite) { - moves.add(new Move(this, row, col, r, c)); - } + if (target.isWhite() != isWhite) + moves.add(new Move(this, row, col, r, c, target)); break; } r += dir[0]; c += dir[1]; } } - return moves; } @Override public Piece clone() { - return new Queen(this.isWhite, this.x, this.y); + return new Queen(isWhite, x, y); } } diff --git a/OOP_2B1_Project/src/backend/Rook.java b/OOP_2B1_Project/src/backend/Rook.java index d5202f0..64ae21e 100644 --- a/OOP_2B1_Project/src/backend/Rook.java +++ b/OOP_2B1_Project/src/backend/Rook.java @@ -3,42 +3,37 @@ package backend; import java.util.ArrayList; import java.util.List; -public class Rook extends Piece { +class Rook extends Piece { public Rook(boolean isWhite, int x, int y) { super(isWhite, PieceType.Rook, x, y); } - @Override - public PieceType getType() { - return PieceType.Rook; - } - @Override public List getLegalMoves(Board board, int row, int col) { List moves = new ArrayList<>(); int[][] directions = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}}; for (int[] dir : directions) { - int r = row + dir[0], c = col + dir[1]; + int r = row + dir[0]; + int c = col + dir[1]; while (board.isInBounds(r, c)) { Piece target = board.getPieceAt(r, c); if (target == null) { moves.add(new Move(this, row, col, r, c)); } else { - if (target.isWhite() != this.isWhite) - moves.add(new Move(this, row, col, r, c)); + if (target.isWhite() != isWhite) + moves.add(new Move(this, row, col, r, c, target)); break; } r += dir[0]; c += dir[1]; } } - return moves; } @Override public Piece clone() { - return new Rook(this.isWhite, this.x, this.y); + return new Rook(isWhite, x, y); } } \ No newline at end of file