From 43e44bf7d2b1b81eaa7e8dc7b17ec17cb7ba4892 Mon Sep 17 00:00:00 2001 From: felix-vi Date: Thu, 5 Feb 2026 19:46:02 +0100 Subject: [PATCH 1/3] ajout d'une fenetre arene et bug divinebot --- fr/iut_fbleau/Avalam/ArenaWindow.java | 102 ++++++++++++++++---------- fr/iut_fbleau/Bot/DivineBot.java | 44 +++++++---- 2 files changed, 95 insertions(+), 51 deletions(-) diff --git a/fr/iut_fbleau/Avalam/ArenaWindow.java b/fr/iut_fbleau/Avalam/ArenaWindow.java index 2a604ad..54d8b4d 100644 --- a/fr/iut_fbleau/Avalam/ArenaWindow.java +++ b/fr/iut_fbleau/Avalam/ArenaWindow.java @@ -208,48 +208,76 @@ public class ArenaWindow extends JFrame { // Charger le plateau initial Tower[][] initialGrid = BoardLoader.loadFromFile("fr/iut_fbleau/Res/Plateau.txt"); - // Lancer les parties - for (int i = 1; i <= nbParties; i++) { - AvalamBoard board = new AvalamBoard(initialGrid, Player.PLAYER1); - ArenaGame game = new ArenaGame(board, bot1, bot2); + // Créer un dialogue de progression + JDialog progressDialog = new JDialog(this, "Parties en cours...", true); + JLabel progressLabel = new JLabel("Préparation des parties...", JLabel.CENTER); + progressLabel.setBorder(BorderFactory.createEmptyBorder(20, 40, 20, 40)); + progressDialog.add(progressLabel); + progressDialog.setSize(300, 100); + progressDialog.setLocationRelativeTo(this); + progressDialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE); - try { - Result result = game.run(); - String winner = getWinnerName(result, bot1Type, bot2Type); - - // Ajouter au tableau - tableModel.addRow(new Object[]{ - "Partie " + i, - bot1Type, - bot2Type, - winner - }); - } catch (Exception e) { - tableModel.addRow(new Object[]{ - "Partie " + i, - bot1Type, - bot2Type, - "Erreur: " + e.getMessage() + // Exécuter les parties dans un thread séparé pour ne pas bloquer l'interface + Thread arenaThread = new Thread(() -> { + SwingUtilities.invokeLater(() -> progressDialog.setVisible(true)); + + for (int i = 1; i <= nbParties; i++) { + final int partieNum = i; + SwingUtilities.invokeLater(() -> { + progressLabel.setText("Partie " + partieNum + " / " + nbParties + " en cours..."); }); + + AvalamBoard board = new AvalamBoard(initialGrid, Player.PLAYER1); + ArenaGame game = new ArenaGame(board, bot1, bot2); + + try { + Result result = game.run(); + String winner = getWinnerName(result, bot1Type, bot2Type); + + // Ajouter au tableau dans le thread EDT + SwingUtilities.invokeLater(() -> { + tableModel.addRow(new Object[]{ + "Partie " + partieNum, + bot1Type, + bot2Type, + winner + }); + }); + } catch (Exception e) { + SwingUtilities.invokeLater(() -> { + tableModel.addRow(new Object[]{ + "Partie " + partieNum, + bot1Type, + bot2Type, + "Erreur: " + e.getMessage() + }); + }); + } } - } - // Afficher un message de fin avec possibilité de quitter directement - Object[] options = {"OK", "Quitter le jeu"}; - int choice = JOptionPane.showOptionDialog( - this, - "Toutes les parties sont terminées !", - "Arène terminée", - JOptionPane.DEFAULT_OPTION, - JOptionPane.INFORMATION_MESSAGE, - null, - options, - options[0] - ); + // Fermer le dialogue et afficher le message de fin + SwingUtilities.invokeLater(() -> { + progressDialog.dispose(); + + Object[] options = {"OK", "Quitter le jeu"}; + int choice = JOptionPane.showOptionDialog( + this, + "Toutes les parties sont terminées !", + "Arène terminée", + JOptionPane.DEFAULT_OPTION, + JOptionPane.INFORMATION_MESSAGE, + null, + options, + options[0] + ); - if (choice == 1) { - System.exit(0); - } + if (choice == 1) { + System.exit(0); + } + }); + }); + + arenaThread.start(); } /** diff --git a/fr/iut_fbleau/Bot/DivineBot.java b/fr/iut_fbleau/Bot/DivineBot.java index 0361e98..7902df9 100644 --- a/fr/iut_fbleau/Bot/DivineBot.java +++ b/fr/iut_fbleau/Bot/DivineBot.java @@ -105,22 +105,38 @@ public class DivineBot extends AbstractGamePlayer { boolean isMax = board.getCurrentPlayer() == me; - for (AbstractPly m : listMoves(board)) { - IBoard next = board.safeCopy(); - next.doPly(m); - - int val = alphaBeta(next, depth - 1, alpha, beta); - - if (isMax) { - alpha = Math.max(alpha, val); - if (alpha >= beta) break; // Coupure Beta - } else { - beta = Math.min(beta, val); - if (alpha >= beta) break; // Coupure Alpha - } + List moves = listMoves(board); + if (moves.isEmpty()) { + return evaluate(board); } - return isMax ? alpha : beta; + if (isMax) { + int best = Integer.MIN_VALUE; + for (AbstractPly m : moves) { + IBoard next = board.safeCopy(); + next.doPly(m); + + int val = alphaBeta(next, depth - 1, alpha, beta); + best = Math.max(best, val); + alpha = Math.max(alpha, best); + + if (alpha >= beta) break; // Coupure Beta + } + return best; + } else { + int best = Integer.MAX_VALUE; + for (AbstractPly m : moves) { + IBoard next = board.safeCopy(); + next.doPly(m); + + int val = alphaBeta(next, depth - 1, alpha, beta); + best = Math.min(best, val); + beta = Math.min(beta, best); + + if (alpha >= beta) break; // Coupure Alpha + } + return best; + } } /** -- 2.52.0 From 2db0212b314330a3ef7d245649a24980c9d5982c Mon Sep 17 00:00:00 2001 From: felix-vi Date: Thu, 5 Feb 2026 20:13:37 +0100 Subject: [PATCH 2/3] =?UTF-8?q?bug=20sur=20la=20r=C3=A9f=C3=A9rence=20des?= =?UTF-8?q?=20tour=20dans=20avalamboard?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fr/iut_fbleau/Avalam/ArenaWindow.java | 39 ++++++++++++++++++++++++-- fr/iut_fbleau/Avalam/AvalamBoard.java | 11 ++++++-- fr/iut_fbleau/Avalam/AvalamWindow.java | 1 - 3 files changed, 46 insertions(+), 5 deletions(-) diff --git a/fr/iut_fbleau/Avalam/ArenaWindow.java b/fr/iut_fbleau/Avalam/ArenaWindow.java index 54d8b4d..1df16a9 100644 --- a/fr/iut_fbleau/Avalam/ArenaWindow.java +++ b/fr/iut_fbleau/Avalam/ArenaWindow.java @@ -221,6 +221,12 @@ public class ArenaWindow extends JFrame { Thread arenaThread = new Thread(() -> { SwingUtilities.invokeLater(() -> progressDialog.setVisible(true)); + // Statistiques pour déboguer + int bot1Wins = 0; + int bot2Wins = 0; + int draws = 0; + int errors = 0; + for (int i = 1; i <= nbParties; i++) { final int partieNum = i; SwingUtilities.invokeLater(() -> { @@ -234,6 +240,15 @@ public class ArenaWindow extends JFrame { Result result = game.run(); String winner = getWinnerName(result, bot1Type, bot2Type); + // Mettre à jour les statistiques + if (result == Result.WIN) { + bot1Wins++; + } else if (result == Result.LOSS) { + bot2Wins++; + } else if (result == Result.DRAW) { + draws++; + } + // Ajouter au tableau dans le thread EDT SwingUtilities.invokeLater(() -> { tableModel.addRow(new Object[]{ @@ -244,6 +259,7 @@ public class ArenaWindow extends JFrame { }); }); } catch (Exception e) { + errors++; SwingUtilities.invokeLater(() -> { tableModel.addRow(new Object[]{ "Partie " + partieNum, @@ -254,15 +270,34 @@ public class ArenaWindow extends JFrame { }); } } + + // Afficher les statistiques finales + final int finalBot1Wins = bot1Wins; + final int finalBot2Wins = bot2Wins; + final int finalDraws = draws; + final int finalErrors = errors; - // Fermer le dialogue et afficher le message de fin + // Fermer le dialogue et afficher le message de fin avec statistiques SwingUtilities.invokeLater(() -> { progressDialog.dispose(); + String statsMessage = String.format( + "Toutes les parties sont terminées !\n\n" + + "Statistiques :\n" + + "- %s (Bot 1) : %d victoires\n" + + "- %s (Bot 2) : %d victoires\n" + + "- Matchs nuls : %d\n" + + "- Erreurs : %d", + bot1Type, finalBot1Wins, + bot2Type, finalBot2Wins, + finalDraws, + finalErrors + ); + Object[] options = {"OK", "Quitter le jeu"}; int choice = JOptionPane.showOptionDialog( this, - "Toutes les parties sont terminées !", + statsMessage, "Arène terminée", JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE, diff --git a/fr/iut_fbleau/Avalam/AvalamBoard.java b/fr/iut_fbleau/Avalam/AvalamBoard.java index 9ef33e1..a3f09de 100644 --- a/fr/iut_fbleau/Avalam/AvalamBoard.java +++ b/fr/iut_fbleau/Avalam/AvalamBoard.java @@ -51,9 +51,16 @@ public class AvalamBoard extends AbstractBoard { super(startingPlayer, new ArrayDeque<>()); this.grid = new Tower[SIZE][SIZE]; + // Copie profonde : créer de nouvelles tours pour éviter que toutes les parties partagent les mêmes objets for (int r = 0; r < SIZE; r++) - for (int c = 0; c < SIZE; c++) - this.grid[r][c] = initialGrid[r][c]; + for (int c = 0; c < SIZE; c++) { + Tower t = initialGrid[r][c]; + if (t == null) { + this.grid[r][c] = null; + } else { + this.grid[r][c] = new Tower(t.getHeight(), t.getColor()); + } + } } /** diff --git a/fr/iut_fbleau/Avalam/AvalamWindow.java b/fr/iut_fbleau/Avalam/AvalamWindow.java index 5594021..7daa29b 100644 --- a/fr/iut_fbleau/Avalam/AvalamWindow.java +++ b/fr/iut_fbleau/Avalam/AvalamWindow.java @@ -233,7 +233,6 @@ public class AvalamWindow extends JFrame { } else if (mode == GameMode.PVALPHA) { botMove = alphaBot.giveYourMove(board.safeCopy()); } else { - // A FAIRE PLUS TARD (PVGOD) botMove = divineBot.giveYourMove(board.safeCopy()); } -- 2.52.0 From d94b95fa36a88373f69498ef1c325e6a5304e900 Mon Sep 17 00:00:00 2001 From: felix-vi Date: Thu, 5 Feb 2026 20:50:23 +0100 Subject: [PATCH 3/3] =?UTF-8?q?erreur=20de=20cr=C3=A9ation=20dans=20l'ar?= =?UTF-8?q?=C3=A8ne?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fr/iut_fbleau/Avalam/ArenaWindow.java | 32 +++++++++++++++++---------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/fr/iut_fbleau/Avalam/ArenaWindow.java b/fr/iut_fbleau/Avalam/ArenaWindow.java index 1df16a9..68b074e 100644 --- a/fr/iut_fbleau/Avalam/ArenaWindow.java +++ b/fr/iut_fbleau/Avalam/ArenaWindow.java @@ -192,22 +192,10 @@ public class ArenaWindow extends JFrame { * @param nbParties nombre de parties à jouer */ private void runArena(String bot1Type, String bot2Type, int depth, int nbParties) { - // Créer les bots - AbstractGamePlayer bot1 = createBot(bot1Type, Player.PLAYER1, depth); - AbstractGamePlayer bot2 = createBot(bot2Type, Player.PLAYER2, depth); - - if (bot1 == null || bot2 == null) { - JOptionPane.showMessageDialog(this, "Erreur lors de la création des bots."); - return; - } - // Vider le tableau tableModel.setRowCount(0); results.clear(); - // Charger le plateau initial - Tower[][] initialGrid = BoardLoader.loadFromFile("fr/iut_fbleau/Res/Plateau.txt"); - // Créer un dialogue de progression JDialog progressDialog = new JDialog(this, "Parties en cours...", true); JLabel progressLabel = new JLabel("Préparation des parties...", JLabel.CENTER); @@ -233,6 +221,26 @@ public class ArenaWindow extends JFrame { progressLabel.setText("Partie " + partieNum + " / " + nbParties + " en cours..."); }); + // Recréer les bots à chaque partie pour garantir l'indépendance complète + // (notamment pour réinitialiser les générateurs aléatoires) + AbstractGamePlayer bot1 = createBot(bot1Type, Player.PLAYER1, depth); + AbstractGamePlayer bot2 = createBot(bot2Type, Player.PLAYER2, depth); + + if (bot1 == null || bot2 == null) { + errors++; + SwingUtilities.invokeLater(() -> { + tableModel.addRow(new Object[]{ + "Partie " + partieNum, + bot1Type, + bot2Type, + "Erreur: Impossible de créer les bots" + }); + }); + continue; + } + + // Recharger le plateau à chaque partie pour garantir l'indépendance complète + Tower[][] initialGrid = BoardLoader.loadFromFile("fr/iut_fbleau/Res/Plateau.txt"); AvalamBoard board = new AvalamBoard(initialGrid, Player.PLAYER1); ArenaGame game = new ArenaGame(board, bot1, bot2); -- 2.52.0