From e3b4b0c3d40ed98e13cd9dfcc581ecd17b1ef052 Mon Sep 17 00:00:00 2001 From: bensefia Date: Tue, 13 May 2025 14:11:10 +0200 Subject: [PATCH 1/8] arret de jeu lors de la mise en echec --- OOP_2B6_PROJECT/src/backend/AutoPlayer.java | 168 ++++++++++++++++---- OOP_2B6_PROJECT/src/backend/Board.java | 63 +++++++- 2 files changed, 201 insertions(+), 30 deletions(-) diff --git a/OOP_2B6_PROJECT/src/backend/AutoPlayer.java b/OOP_2B6_PROJECT/src/backend/AutoPlayer.java index d7f3197..63e3e83 100644 --- a/OOP_2B6_PROJECT/src/backend/AutoPlayer.java +++ b/OOP_2B6_PROJECT/src/backend/AutoPlayer.java @@ -15,48 +15,160 @@ public class AutoPlayer { int px = p.getX(); int py = p.getY(); - for (int dx = -1; dx <= 1; dx++) { - for (int dy = -1; dy <= 1; dy++) { - if (dx == 0 && dy == 0) continue; - int nx = px + dx; - int ny = py + dy; + ArrayList candidateMoves = generatePossibleMoves(p, board); + for (int[] move : candidateMoves) { + int nx = move[0]; + int ny = move[1]; + Piece target = board.getPieceAt(nx, ny); - if (nx >= 0 && ny >= 0 && nx < board.getWidth() && ny < board.getHeight()) { - Piece target = getPieceAt(pieces, nx, ny); - if (target == null || target.isWhite() != aiColor) { - int score = (target != null) ? pieceValue(target) : 0; - if (score > bestScore) { - bestScore = score; - bestMove = new Move(p, px, py, nx, ny, target); - } - } - } + Board simulated = new Board(board); + simulated.playMove(new Move(p, px, py, nx, ny, target)); + + int score = evaluateBoard(simulated, aiColor); + if (score > bestScore) { + bestScore = score; + bestMove = new Move(p, px, py, nx, ny, target); } } } } - return bestMove; } + private ArrayList generatePossibleMoves(Piece piece, Board board) { + 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 oneStepY = y + dir; + int twoStepY = y + 2 * dir; + if (inBounds(x, oneStepY, board) && board.getPieceAt(x, oneStepY) == null) { + moves.add(new int[] { x, oneStepY }); + if ((isWhite && y == 6) || (!isWhite && y == 1)) { + if (board.getPieceAt(x, twoStepY) == null) { + moves.add(new int[] { x, twoStepY }); + } + } + } + for (int dx = -1; dx <= 1; dx += 2) { + int nx = x + dx; + if (inBounds(nx, oneStepY, board)) { + Piece target = board.getPieceAt(nx, oneStepY); + if (target != null && target.isWhite() != isWhite) { + moves.add(new int[] { nx, oneStepY }); + } + } + } + break; + + case Knight: + int[][] knightMoves = { { 2, 1 }, { 1, 2 }, { -1, 2 }, { -2, 1 }, + { -2, -1 }, { -1, -2 }, { 1, -2 }, { 2, -1 } }; + for (int[] d : knightMoves) { + int nx = x + d[0]; + int ny = y + d[1]; + if (inBounds(nx, ny, board)) { + Piece target = board.getPieceAt(nx, ny); + if (target == null || target.isWhite() != isWhite) + moves.add(new int[] { nx, ny }); + } + } + break; + + case Bishop: + addSlideMoves(moves, board, piece, 1, 1); + addSlideMoves(moves, board, piece, 1, -1); + addSlideMoves(moves, board, piece, -1, 1); + addSlideMoves(moves, board, piece, -1, -1); + break; + + case Rook: + addSlideMoves(moves, board, piece, 1, 0); + addSlideMoves(moves, board, piece, -1, 0); + addSlideMoves(moves, board, piece, 0, 1); + addSlideMoves(moves, board, piece, 0, -1); + break; + + case Queen: + for (int dx = -1; dx <= 1; dx++) { + for (int dy = -1; dy <= 1; dy++) { + if (dx != 0 || dy != 0) { + addSlideMoves(moves, board, 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) continue; + int nx = x + dx; + int ny = y + dy; + if (inBounds(nx, ny, board)) { + Piece target = board.getPieceAt(nx, ny); + if (target == null || target.isWhite() != isWhite) { + moves.add(new int[] { nx, ny }); + } + } + } + } + break; + } + return moves; + } + + private void addSlideMoves(ArrayList moves, Board board, 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; + + while (inBounds(nx, ny, board)) { + Piece p = board.getPieceAt(nx, ny); + if (p == null) { + moves.add(new int[] { nx, ny }); + } else { + if (p.isWhite() != isWhite) + moves.add(new int[] { nx, ny }); + break; + } + nx += dx; + ny += dy; + } + } + + private boolean inBounds(int x, int y, Board board) { + return x >= 0 && y >= 0 && x < board.getWidth() && y < board.getHeight(); + } + + private int evaluateBoard(Board board, boolean aiColor) { + int score = 0; + for (Piece p : board.getPieces()) { + int value = pieceValue(p); + score += p.isWhite() == aiColor ? value : -value; + } + return score; + } + private int pieceValue(Piece piece) { switch (piece.getType()) { - case Pawn: return 1; + case Pawn: return 10; case Knight: - case Bishop: return 3; - case Rook: return 5; - case Queen: return 9; - case King: return 1000; + case Bishop: return 30; + case Rook: return 50; + case Queen: return 90; + case King: return 900; default: return 0; } } - - private Piece getPieceAt(ArrayList list, int x, int y) { - for (Piece p : list) { - if (p.getX() == x && p.getY() == y) return p; - } - return null; - } } + + diff --git a/OOP_2B6_PROJECT/src/backend/Board.java b/OOP_2B6_PROJECT/src/backend/Board.java index 31582ac..05dbfef 100644 --- a/OOP_2B6_PROJECT/src/backend/Board.java +++ b/OOP_2B6_PROJECT/src/backend/Board.java @@ -10,6 +10,7 @@ public class Board { private ArrayList pieces; private int turnNumber = 0; private boolean turnIsWhite = true; + private boolean gameOver = false; private Integer selectedX = null; private Integer selectedY = null; @@ -39,6 +40,10 @@ public class Board { 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); pieces.add(new Piece(isWhite, type, x, y)); @@ -73,6 +78,7 @@ public class Board { selectedY = null; highlightedPositions.clear(); moveHistory.clear(); + gameOver = false; } public ArrayList getPieces() { @@ -80,6 +86,8 @@ public class Board { } public void userTouch(int x, int y) { + if (gameOver) return; + Piece clickedPiece = getPieceAt(x, y); if (selectedX == null || selectedY == null) { if (clickedPiece != null && clickedPiece.isWhite() == turnIsWhite) { @@ -104,6 +112,10 @@ public class Board { moveHistory.push(move); turnNumber++; turnIsWhite = !turnIsWhite; + + if (isCheckmate(!turnIsWhite)) { + gameOver = true; + } } selectedX = null; selectedY = null; @@ -129,9 +141,52 @@ public class Board { selectedX = null; selectedY = null; highlightedPositions.clear(); + gameOver = false; } } + public boolean isCheckmate(boolean forWhite) { + for (Piece piece : pieces) { + if (piece.isWhite() == forWhite) { + ArrayList moves = getLegalMovesFor(piece); + for (int[] move : moves) { + Board copy = new Board(this); + Piece captured = copy.getPieceAt(move[0], move[1]); + copy.pieces.removeIf(p -> p.getX() == piece.getX() && p.getY() == piece.getY()); + copy.pieces.removeIf(p -> p.getX() == move[0] && p.getY() == move[1]); + copy.pieces.add(new Piece(piece.isWhite(), piece.getType(), move[0], move[1])); + if (!copy.isKingInCheck(forWhite)) { + return false; + } + } + } + } + return isKingInCheck(forWhite); + } + + public boolean isKingInCheck(boolean isWhite) { + Piece king = null; + for (Piece p : pieces) { + if (p.getType() == PieceType.King && p.isWhite() == isWhite) { + king = p; + break; + } + } + if (king == null) return true; + + for (Piece enemy : pieces) { + if (enemy.isWhite() != isWhite) { + ArrayList moves = getLegalMovesFor(enemy); + for (int[] pos : moves) { + if (pos[0] == king.getX() && pos[1] == king.getY()) { + return true; + } + } + } + } + return false; + } + public boolean isSelected(int x, int y) { return selectedX != null && selectedY != null && selectedX == x && selectedY == y; } @@ -265,7 +320,7 @@ public class Board { return x >= 0 && y >= 0 && x < width && y < height; } - private Piece getPieceAt(int x, int y) { + public Piece getPieceAt(int x, int y) { for (Piece p : pieces) { if (p.getX() == x && p.getY() == y) return p; } @@ -318,7 +373,7 @@ public class Board { } public void playMove(Move move) { - if (move == null) return; + if (move == null || gameOver) return; 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( @@ -333,6 +388,10 @@ public class Board { selectedX = null; selectedY = null; highlightedPositions.clear(); + + if (isCheckmate(!turnIsWhite)) { + gameOver = true; + } } } From 7618c02c71a985c0dcdbaf585e8002e05b3e2ef7 Mon Sep 17 00:00:00 2001 From: bensefia Date: Tue, 13 May 2025 14:17:41 +0200 Subject: [PATCH 2/8] better version --- OOP_2B6_PROJECT/src/backend/AutoPlayer.java | 1 + 1 file changed, 1 insertion(+) diff --git a/OOP_2B6_PROJECT/src/backend/AutoPlayer.java b/OOP_2B6_PROJECT/src/backend/AutoPlayer.java index 63e3e83..3bd85c3 100644 --- a/OOP_2B6_PROJECT/src/backend/AutoPlayer.java +++ b/OOP_2B6_PROJECT/src/backend/AutoPlayer.java @@ -168,6 +168,7 @@ public class AutoPlayer { } } } +//pour maieul From c6cdf82a3d346f680c9a39a645c21e53f9bc1d0f Mon Sep 17 00:00:00 2001 From: bensefia Date: Tue, 13 May 2025 14:18:46 +0200 Subject: [PATCH 3/8] better version --- OOP_2B6_PROJECT/src/backend/AutoPlayer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OOP_2B6_PROJECT/src/backend/AutoPlayer.java b/OOP_2B6_PROJECT/src/backend/AutoPlayer.java index 3bd85c3..e1fbcbf 100644 --- a/OOP_2B6_PROJECT/src/backend/AutoPlayer.java +++ b/OOP_2B6_PROJECT/src/backend/AutoPlayer.java @@ -168,7 +168,7 @@ public class AutoPlayer { } } } -//pour maieul +//pour maieul push From 973f2a6ab2a4ce85eda529575c853cecd3ac7b10 Mon Sep 17 00:00:00 2001 From: bensefia Date: Tue, 13 May 2025 14:22:26 +0200 Subject: [PATCH 4/8] push ameliorztion ia --- OOP_2B6_PROJECT/src/backend/AutoPlayer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OOP_2B6_PROJECT/src/backend/AutoPlayer.java b/OOP_2B6_PROJECT/src/backend/AutoPlayer.java index e1fbcbf..d04c034 100644 --- a/OOP_2B6_PROJECT/src/backend/AutoPlayer.java +++ b/OOP_2B6_PROJECT/src/backend/AutoPlayer.java @@ -168,7 +168,7 @@ public class AutoPlayer { } } } -//pour maieul push +//pour maieul push bx From 7f167c7d9bb0745560334332b6f126faf3f63381 Mon Sep 17 00:00:00 2001 From: bensefia Date: Tue, 13 May 2025 14:23:21 +0200 Subject: [PATCH 5/8] yb --- OOP_2B6_PROJECT/src/backend/AutoPlayer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OOP_2B6_PROJECT/src/backend/AutoPlayer.java b/OOP_2B6_PROJECT/src/backend/AutoPlayer.java index d04c034..2f54611 100644 --- a/OOP_2B6_PROJECT/src/backend/AutoPlayer.java +++ b/OOP_2B6_PROJECT/src/backend/AutoPlayer.java @@ -168,7 +168,7 @@ public class AutoPlayer { } } } -//pour maieul push bx +//pour maieul push b From 6a50006b91787c51ff5ae7d2e082576847d9cb95 Mon Sep 17 00:00:00 2001 From: bensefia Date: Tue, 13 May 2025 14:26:53 +0200 Subject: [PATCH 6/8] ff --- OOP_2B6_PROJECT/src/backend/AutoPlayer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OOP_2B6_PROJECT/src/backend/AutoPlayer.java b/OOP_2B6_PROJECT/src/backend/AutoPlayer.java index 2f54611..efeba44 100644 --- a/OOP_2B6_PROJECT/src/backend/AutoPlayer.java +++ b/OOP_2B6_PROJECT/src/backend/AutoPlayer.java @@ -168,7 +168,7 @@ public class AutoPlayer { } } } -//pour maieul push b +//pour maieul push bbh From c7ea2d9e3b5c2bdbd0d2f19b4fbb4a223fd4851f Mon Sep 17 00:00:00 2001 From: bensefia Date: Tue, 13 May 2025 14:40:07 +0200 Subject: [PATCH 7/8] pour clement --- OOP_2B6_PROJECT/src/backend/AutoPlayer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OOP_2B6_PROJECT/src/backend/AutoPlayer.java b/OOP_2B6_PROJECT/src/backend/AutoPlayer.java index efeba44..bfa8db4 100644 --- a/OOP_2B6_PROJECT/src/backend/AutoPlayer.java +++ b/OOP_2B6_PROJECT/src/backend/AutoPlayer.java @@ -168,7 +168,7 @@ public class AutoPlayer { } } } -//pour maieul push bbh +//pour maieul push bbh f From a2a9c28e368f70240b623f7633bf8cd2a291a650 Mon Sep 17 00:00:00 2001 From: bensefia Date: Tue, 13 May 2025 14:40:32 +0200 Subject: [PATCH 8/8] loud and clear --- OOP_2B6_PROJECT/src/backend/Board.java | 1 + 1 file changed, 1 insertion(+) diff --git a/OOP_2B6_PROJECT/src/backend/Board.java b/OOP_2B6_PROJECT/src/backend/Board.java index bd07d20..965c78e 100644 --- a/OOP_2B6_PROJECT/src/backend/Board.java +++ b/OOP_2B6_PROJECT/src/backend/Board.java @@ -394,3 +394,4 @@ public class Board { } } } +// load