From ee6e20cb596f4c477c115fdc8715757a060249c4 Mon Sep 17 00:00:00 2001 From: clement Date: Tue, 13 May 2025 14:39:03 +0200 Subject: [PATCH] bug push pull test --- OOP_2B6_PROJECT/src/backend/Board.java | 260 +++++++++---------------- 1 file changed, 94 insertions(+), 166 deletions(-) diff --git a/OOP_2B6_PROJECT/src/backend/Board.java b/OOP_2B6_PROJECT/src/backend/Board.java index 2046fb7..6e80921 100644 --- a/OOP_2B6_PROJECT/src/backend/Board.java +++ b/OOP_2B6_PROJECT/src/backend/Board.java @@ -17,7 +17,7 @@ public class Board { private Stack moveHistory = new Stack<>(); - // Indique si la partie est terminée (roi capturé) + // Indique si la partie est terminée (échec et mat) private boolean gameOver = false; public Board(int colNum, int lineNum) { @@ -26,26 +26,11 @@ public class Board { this.pieces = new ArrayList<>(); } - public int getWidth() { - return this.width; - } - - public int getHeight() { - return this.height; - } - - public int getTurnNumber() { - return turnNumber; - } - - public boolean isTurnWhite() { - return turnIsWhite; - } - - // Expose l'état de fin de partie - public boolean isGameOver() { - return gameOver; - } + public int getWidth() { return width; } + public int getHeight() { return height; } + public int getTurnNumber() { return turnNumber; } + public boolean isTurnWhite() { return turnIsWhite; } + public boolean isGameOver() { return gameOver; } public void setPiece(boolean isWhite, PieceType type, int x, int y) { pieces.removeIf(p -> p.getX() == x && p.getY() == y); @@ -53,9 +38,7 @@ public class Board { } public void populateBoard() { - // Réinitialiser l'état de fin de partie gameOver = false; - pieces.clear(); setPiece(true, PieceType.Rook, 0, 7); setPiece(true, PieceType.Knight, 1, 7); @@ -66,7 +49,6 @@ public class Board { setPiece(true, PieceType.Knight, 6, 7); setPiece(true, PieceType.Rook, 7, 7); for (int x = 0; x < 8; x++) setPiece(true, PieceType.Pawn, x, 6); - setPiece(false, PieceType.Rook, 0, 0); setPiece(false, PieceType.Knight, 1, 0); setPiece(false, PieceType.Bishop, 2, 0); @@ -79,15 +61,12 @@ public class Board { } public void cleanBoard() { - // Réinitialiser l'état de fin de partie gameOver = false; - pieces.clear(); selectedX = null; selectedY = null; highlightedPositions.clear(); - boolean kingInCheck = isInCheck(turnIsWhite); - if (kingInCheck) { + if (isInCheck(turnIsWhite)) { System.out.println("Échec !"); } moveHistory.clear(); @@ -98,11 +77,7 @@ public class Board { } public void userTouch(int x, int y) { - if (gameOver) { - // Ne pas autoriser de nouveaux coups si la partie est terminée - return; - } - + if (gameOver) return; Piece clickedPiece = getPieceAt(x, y); if (selectedX == null || selectedY == null) { if (clickedPiece != null && clickedPiece.isWhite() == turnIsWhite) { @@ -113,24 +88,23 @@ public class Board { } else { Piece selectedPiece = getPieceAt(selectedX, selectedY); if (selectedPiece != null && selectedPiece.isWhite() == turnIsWhite) { - // Détecter capture de roi Piece captured = getPieceAt(x, y); + // Détection de la capture du roi (sécuritaire) if (captured != null && captured.getType() == PieceType.King) { gameOver = true; + System.out.println("Game over: King captured."); } pieces.removeIf(p -> p.getX() == x && p.getY() == y); pieces.removeIf(p -> p.getX() == selectedX && p.getY() == selectedY); - Piece moved = new Piece( - selectedPiece.isWhite(), - selectedPiece.getType(), - x, - y - ); - pieces.add(moved); - Move move = new Move(selectedPiece, selectedX, selectedY, x, y, captured); - moveHistory.push(move); + pieces.add(new Piece(selectedPiece.isWhite(), selectedPiece.getType(), x, y)); + moveHistory.push(new Move(selectedPiece, selectedX, selectedY, x, y, captured)); turnNumber++; turnIsWhite = !turnIsWhite; + // Détection d'échec et mat + if (isInCheck(turnIsWhite) && !hasLegalMoves(turnIsWhite)) { + gameOver = true; + System.out.println("Game over: Checkmate."); + } } selectedX = null; selectedY = null; @@ -139,26 +113,17 @@ public class Board { } public void undoLastMove() { - if (!moveHistory.isEmpty()) { - Move lastMove = moveHistory.pop(); - pieces.removeIf(p -> p.getX() == lastMove.getToX() && p.getY() == lastMove.getToY()); - pieces.add(new Piece( - lastMove.getMovedPiece().isWhite(), - lastMove.getMovedPiece().getType(), - lastMove.getFromX(), - lastMove.getFromY() - )); - if (lastMove.getCapturedPiece() != null) { - pieces.add(lastMove.getCapturedPiece()); - } - turnNumber--; - turnIsWhite = !turnIsWhite; - selectedX = null; - selectedY = null; - highlightedPositions.clear(); - // Réinitialiser gameOver si on ressuscite un roi - gameOver = false; - } + if (moveHistory.isEmpty()) return; + Move lastMove = moveHistory.pop(); + pieces.removeIf(p -> p.getX() == lastMove.getToX() && p.getY() == lastMove.getToY()); + pieces.add(new Piece(lastMove.getMovedPiece().isWhite(), lastMove.getMovedPiece().getType(), lastMove.getFromX(), lastMove.getFromY())); + if (lastMove.getCapturedPiece() != null) pieces.add(lastMove.getCapturedPiece()); + turnNumber--; + turnIsWhite = !turnIsWhite; + selectedX = null; + selectedY = null; + highlightedPositions.clear(); + gameOver = false; } public boolean isSelected(int x, int y) { @@ -166,9 +131,7 @@ public class Board { } public boolean isHighlighted(int x, int y) { - for (int[] pos : highlightedPositions) { - if (pos[0] == x && pos[1] == y) return true; - } + for (int[] pos : highlightedPositions) if (pos[0] == x && pos[1] == y) return true; return false; } @@ -179,110 +142,77 @@ public class Board { private ArrayList getLegalMovesFor(Piece piece) { ArrayList moves = new ArrayList<>(); - int x = piece.getX(); - int y = piece.getY(); + int x = piece.getX(), y = piece.getY(); boolean isWhite = piece.isWhite(); - switch (piece.getType()) { case Pawn: int dir = isWhite ? -1 : 1; - int startRow = isWhite ? 6 : 1; - int oneStepY = y + dir; - int twoStepY = y + 2 * dir; - - if (inBounds(x, oneStepY) && getPieceAt(x, oneStepY) == null) { - moves.add(new int[]{x, oneStepY}); - if (y == startRow && getPieceAt(x, twoStepY) == null) { - moves.add(new int[]{x, twoStepY}); + int start = isWhite ? 6 : 1; + if (inBounds(x, y + dir) && getPieceAt(x, y + dir) == null) { + moves.add(new int[]{x, y + dir}); + if (y == start && inBounds(x, y + 2 * dir) && getPieceAt(x, y + 2 * dir) == null) + moves.add(new int[]{x, y + 2 * dir}); + } + for (int dx : new int[]{-1, 1}) { + if (inBounds(x + dx, y + dir)) { + Piece p = getPieceAt(x + dx, y + dir); + if (p != null && p.isWhite() != isWhite) moves.add(new int[]{x + dx, y + dir}); } } - - if (inBounds(x - 1, oneStepY)) { - Piece left = getPieceAt(x - 1, oneStepY); - if (left != null && left.isWhite() != isWhite) - moves.add(new int[]{x - 1, oneStepY}); - } - - if (inBounds(x + 1, oneStepY)) { - Piece right = getPieceAt(x + 1, oneStepY); - if (right != null && right.isWhite() != isWhite) - moves.add(new int[]{x + 1, oneStepY}); - } break; - case Rook: addSlideMoves(moves, piece, 1, 0); addSlideMoves(moves, piece, -1, 0); addSlideMoves(moves, piece, 0, 1); addSlideMoves(moves, piece, 0, -1); break; - case Bishop: addSlideMoves(moves, piece, 1, 1); addSlideMoves(moves, piece, 1, -1); addSlideMoves(moves, piece, -1, 1); addSlideMoves(moves, 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) { + for (int dx = -1; dx <= 1; dx++) + for (int dy = -1; dy <= 1; dy++) + if (dx != 0 || dy != 0) addSlideMoves(moves, piece, dx, dy); - } - } - } break; - case Knight: - int[][] deltas = { - {2, 1}, {1, 2}, {-1, 2}, {-2, 1}, - {-2, -1}, {-1, -2}, {1, -2}, {2, -1} - }; - for (int[] d : deltas) { - int nx = x + d[0]; - int ny = y + d[1]; + int[][] d = {{2, 1}, {1, 2}, {-1, 2}, {-2, 1}, {-2, -1}, {-1, -2}, {1, -2}, {2, -1}}; + for (int[] dd : d) { + int nx = x + dd[0], ny = y + dd[1]; if (inBounds(nx, ny)) { Piece p = getPieceAt(nx, ny); - if (p == null || p.isWhite() != isWhite) - moves.add(new int[]{nx, ny}); + if (p == null || p.isWhite() != isWhite) moves.add(new int[]{nx, ny}); } } break; - case King: - for (int dx = -1; dx <= 1; dx++) { + 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; + int nx = x + dx, ny = y + dy; if (inBounds(nx, ny)) { Piece p = getPieceAt(nx, ny); - if (p == null || p.isWhite() != isWhite) - moves.add(new int[]{nx, ny}); + if (p == null || p.isWhite() != isWhite) moves.add(new int[]{nx, ny}); } } - } break; } - return moves; } private void addSlideMoves(ArrayList moves, Piece piece, int dx, int dy) { - int x = piece.getX(); - int y = piece.getY(); - boolean isWhite = piece.isWhite(); - int nx = x + dx; - int ny = y + dy; - + int x = piece.getX(), y = piece.getY(); + boolean white = piece.isWhite(); + int nx = x + dx, ny = y + dy; while (inBounds(nx, ny)) { Piece p = getPieceAt(nx, ny); if (p == null) { moves.add(new int[]{nx, ny}); } else { - if (p.isWhite() != isWhite) - moves.add(new int[]{nx, ny}); + if (p.isWhite() != white) moves.add(new int[]{nx, ny}); break; } nx += dx; @@ -295,12 +225,43 @@ public class Board { } private Piece getPieceAt(int x, int y) { - for (Piece p : pieces) { - if (p.getX() == x && p.getY() == y) return p; - } + for (Piece p : pieces) if (p.getX() == x && p.getY() == y) return p; return null; } + private boolean isInCheck(boolean whiteKing) { + Piece king = null; + for (Piece p : pieces) if (p.getType() == PieceType.King && p.isWhite() == whiteKing) { king = p; break; } + if (king == null) return false; + int kx = king.getX(), ky = king.getY(); + for (Piece p : pieces) { + if (p.isWhite() != whiteKing) { + for (int[] m : getLegalMovesFor(p)) if (m[0] == kx && m[1] == ky) return true; + } + } + return false; + } + + public boolean hasLegalMoves(boolean white) { + for (Piece p : pieces) { + if (p.isWhite() == white) { + for (int[] m : getLegalMovesFor(p)) { + Board copy = new Board(this); + Piece captured = copy.getPieceAt(m[0], m[1]); + copy.pieces.removeIf(pc -> pc.getX() == m[0] && pc.getY() == m[1]); + copy.pieces.removeIf(pc -> pc.getX() == p.getX() && pc.getY() == p.getY()); + copy.pieces.add(new Piece(p.isWhite(), p.getType(), m[0], m[1])); + if (!copy.isInCheck(white)) return true; + } + } + } + return false; + } + + public boolean isCheckmate(boolean whiteKing) { + return isInCheck(whiteKing) && !hasLegalMoves(whiteKing); + } + public String[] toFileRep() { String[] output = new String[height + 1]; for (int y = 0; y < height; y++) { @@ -308,11 +269,7 @@ public class Board { for (int x = 0; x < width; x++) { Piece p = getPieceAt(x, y); if (x > 0) row.append(","); - if (p == null) { - row.append(""); - } else { - row.append(p.isWhite() ? "w" : "b").append(p.getType().getSummary()); - } + row.append(p == null ? "" : (p.isWhite() ? "w" : "b") + p.getType().getSummary()); } output[y] = row.toString(); } @@ -350,52 +307,23 @@ public class Board { public void playMove(Move move) { if (move == null || gameOver) return; - // Détecter capture du roi avant d'appliquer le coup Piece captured = move.getCapturedPiece(); if (captured != null && captured.getType() == PieceType.King) { gameOver = true; + System.out.println("Game over: King captured."); } pieces.removeIf(p -> p.getX() == move.getToX() && p.getY() == move.getToY()); pieces.removeIf(p -> p.getX() == move.getFromX() && p.getY() == move.getFromY()); - pieces.add(new Piece( - move.getMovedPiece().isWhite(), - move.getMovedPiece().getType(), - move.getToX(), - move.getToY() - )); + pieces.add(new Piece(move.getMovedPiece().isWhite(), move.getMovedPiece().getType(), move.getToX(), move.getToY())); moveHistory.push(move); turnNumber++; turnIsWhite = !turnIsWhite; selectedX = null; selectedY = null; highlightedPositions.clear(); - } - - private boolean isInCheck(boolean whiteKing) { - Piece king = null; - for (Piece p : pieces) { - if (p.getType() == PieceType.King && p.isWhite() == whiteKing) { - king = p; - break; - } + if (isInCheck(turnIsWhite) && !hasLegalMoves(turnIsWhite)) { + gameOver = true; + System.out.println("Game over: Checkmate."); } - - if (king == null) return false; // Cas improbable - - int kingX = king.getX(); - int kingY = king.getY(); - - for (Piece p : pieces) { - if (p.isWhite() != whiteKing) { - ArrayList moves = getLegalMovesFor(p); - for (int[] move : moves) { - if (move[0] == kingX && move[1] == kingY) { - return true; - } - } - } - } - - return false; } }