package fr.iut_fbleau.Avalam; import fr.iut_fbleau.Bot.AlphaBetaBot; import fr.iut_fbleau.Bot.DivineBot; import fr.iut_fbleau.Bot.IdiotBot; import fr.iut_fbleau.GameAPI.AbstractGamePlayer; import fr.iut_fbleau.GameAPI.Player; import fr.iut_fbleau.GameAPI.Result; import javax.swing.*; import javax.swing.table.DefaultTableModel; import java.awt.*; import java.util.ArrayList; import java.util.List; /** * Fenêtre pour le mode Arène. * Permet de sélectionner trois bots (Idiot, Alpha-Beta, Divin), de configurer la profondeur * de recherche pour les bots intelligents, de choisir le nombre de parties, et d'afficher les résultats. * * @version 1.0 */ public class ArenaWindow extends JFrame { /** Tableau affichant les résultats des parties. */ private JTable resultsTable; /** Modèle de données pour le tableau des résultats. */ private DefaultTableModel tableModel; /** Liste des résultats des parties (non utilisée actuellement). */ private List results; /** * Construit la fenêtre Arène. */ public ArenaWindow() { super("Arène - Bot vs Bot"); setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); setLayout(new BorderLayout()); results = new ArrayList<>(); // Panneau de configuration JPanel configPanel = createConfigPanel(); add(configPanel, BorderLayout.NORTH); // Tableau des résultats createResultsTable(); JScrollPane scrollPane = new JScrollPane(resultsTable); add(scrollPane, BorderLayout.CENTER); // Panneau des boutons JPanel buttonPanel = new JPanel(new FlowLayout()); JButton startButton = new JButton("Lancer les parties"); startButton.addActionListener(e -> showConfigDialog()); buttonPanel.add(startButton); JButton backButton = new JButton("Retour au menu"); backButton.addActionListener(e -> { dispose(); // Ferme la fenêtre Arène Main.showModeSelection(); // Affiche le menu principal }); buttonPanel.add(backButton); add(buttonPanel, BorderLayout.SOUTH); pack(); setSize(600, 400); setLocationRelativeTo(null); setVisible(true); } /** * Crée le panneau de configuration (pour l'instant vide, sera rempli par le dialogue). * * @return un JPanel contenant les informations de configuration */ private JPanel createConfigPanel() { JPanel panel = new JPanel(); panel.setBorder(BorderFactory.createTitledBorder("Configuration")); panel.add(new JLabel("Utilisez le bouton 'Lancer les parties' pour configurer et démarrer.")); return panel; } /** * Crée le tableau des résultats avec les colonnes : Partie, Bot 1, Bot 2, Gagnant. */ private void createResultsTable() { String[] columnNames = {"Partie", "Bot 1", "Bot 2", "Gagnant"}; tableModel = new DefaultTableModel(columnNames, 0) { @Override public boolean isCellEditable(int row, int column) { return false; } }; resultsTable = new JTable(tableModel); resultsTable.setFillsViewportHeight(true); } /** * Affiche le dialogue de configuration et lance les parties. */ private void showConfigDialog() { // Choix du bot 1 String[] botTypes = {"Bot Idiot", "Bot Alpha-Beta", "Bot Divin"}; String bot1Choice = (String) JOptionPane.showInputDialog( this, "Choisissez le Bot 1 (Joueur 1) :", "Configuration Arène - Bot 1", JOptionPane.QUESTION_MESSAGE, null, botTypes, botTypes[0] ); if (bot1Choice == null) return; // Choix du bot 2 String bot2Choice = (String) JOptionPane.showInputDialog( this, "Choisissez le Bot 2 (Joueur 2) :", "Configuration Arène - Bot 2", JOptionPane.QUESTION_MESSAGE, null, botTypes, botTypes[0] ); if (bot2Choice == null) return; // Profondeur pour Alpha-Beta et Divin int depth = 4; if (bot1Choice.contains("Alpha") || bot1Choice.contains("Divin") || bot2Choice.contains("Alpha") || bot2Choice.contains("Divin")) { String depthStr = JOptionPane.showInputDialog( this, "Profondeur de recherche pour les bots Alpha-Beta/Divin ?\n(Conseil: 4)", "Profondeur", JOptionPane.QUESTION_MESSAGE ); if (depthStr != null) { try { depth = Integer.parseInt(depthStr.trim()); if (depth < 1) depth = 1; } catch (Exception e) { depth = 4; } } } // Nombre de parties String nbPartiesStr = JOptionPane.showInputDialog( this, "Combien de parties voulez-vous jouer ?", "Nombre de parties", JOptionPane.QUESTION_MESSAGE ); if (nbPartiesStr == null) return; int nbParties; try { nbParties = Integer.parseInt(nbPartiesStr.trim()); if (nbParties < 1) { JOptionPane.showMessageDialog(this, "Le nombre de parties doit être au moins 1."); return; } } catch (Exception e) { JOptionPane.showMessageDialog(this, "Nombre invalide."); return; } // Lancer les parties runArena(bot1Choice, bot2Choice, depth, nbParties); } /** * Lance les parties entre les deux bots. * * @param bot1Type type du bot 1 (Joueur 1) * @param bot2Type type du bot 2 (Joueur 2) * @param depth profondeur de recherche pour les bots Alpha-Beta/Divin * @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"); // Lancer les parties for (int i = 1; i <= nbParties; i++) { 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 tableModel.addRow(new Object[]{ "Partie " + i, bot1Type, bot2Type, winner }); } catch (Exception e) { tableModel.addRow(new Object[]{ "Partie " + i, bot1Type, bot2Type, "Erreur: " + e.getMessage() }); } } // Afficher un message de fin JOptionPane.showMessageDialog( this, "Toutes les parties sont terminées !", "Arène terminée", JOptionPane.INFORMATION_MESSAGE ); } /** * Crée un bot selon son type. * * @param botType type de bot ("Bot Idiot", "Bot Alpha-Beta", "Bot Divin") * @param player joueur contrôlé par ce bot (PLAYER1 ou PLAYER2) * @param depth profondeur de recherche pour Alpha-Beta/Divin * @return une instance de AbstractGamePlayer correspondant au type, ou null si le type est invalide */ private AbstractGamePlayer createBot(String botType, Player player, int depth) { if (botType.equals("Bot Idiot")) { return new IdiotBot(player); } else if (botType.equals("Bot Alpha-Beta")) { return new AlphaBetaBot(player, depth); } else if (botType.equals("Bot Divin")) { return new DivineBot(player, depth); } return null; } /** * Détermine le nom du gagnant selon le résultat. * * @param result résultat de la partie (WIN, LOSS, ou DRAW du point de vue de PLAYER1) * @param bot1Type nom du bot 1 * @param bot2Type nom du bot 2 * @return une chaîne indiquant le gagnant ou "Match nul" */ private String getWinnerName(Result result, String bot1Type, String bot2Type) { if (result == Result.WIN) { return bot1Type + " (Joueur 1)"; } else if (result == Result.LOSS) { return bot2Type + " (Joueur 2)"; } else { return "Match nul"; } } }