From 4987c35bc48bc46ed5281013cab3f4d31320359c Mon Sep 17 00:00:00 2001 From: lecointre Date: Tue, 7 Apr 2026 16:21:33 +0200 Subject: [PATCH] Compteur mines --- ControleurJeu.java | 26 ++++++++++++++++++++ FenetreJeu.java | 61 ++++++++++++++++++++-------------------------- Grille.java | 40 ++++++++++++++---------------- 3 files changed, 70 insertions(+), 57 deletions(-) create mode 100644 ControleurJeu.java diff --git a/ControleurJeu.java b/ControleurJeu.java new file mode 100644 index 0000000..85b2070 --- /dev/null +++ b/ControleurJeu.java @@ -0,0 +1,26 @@ +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class ControleurJeu implements ActionListener { + + private FenetreJeu fenetre; + + public ControleurJeu(FenetreJeu f) { + this.fenetre = f; + } + + @Override + public void actionPerformed(ActionEvent e) { + // Si la partie est finie, le bouton sert à retourner au menu + if (fenetre.getGrille().isPartieTerminee()) { + this.fenetre.dispose(); + MenuPrincipal nouveauMenu = new MenuPrincipal(); + nouveauMenu.setVisible(true); + } + // Sinon (partie en cours), c'est bien le bouton "Sauver et Quitter" + else { + System.out.println("Sauvegarde de la partie en cours... (Bientôt implémenté)"); + System.exit(0); + } + } +} diff --git a/FenetreJeu.java b/FenetreJeu.java index b0004bf..2276b32 100644 --- a/FenetreJeu.java +++ b/FenetreJeu.java @@ -1,13 +1,12 @@ import javax.swing.*; import java.awt.*; -/** - * Fenêtre principale pendant une partie de Démineur. - */ public class FenetreJeu extends JFrame { private Grille grille; private JButton[][] boutons; + private JLabel labelCompteur; + private JButton btnActionBas; // NOUVEAU : On garde le bouton en mémoire public FenetreJeu(Grille g) { super("Démineur - Partie en cours"); @@ -18,6 +17,11 @@ public class FenetreJeu extends JFrame { this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setLayout(new BorderLayout()); + this.labelCompteur = new JLabel("Mines restantes : " + g.getMinesRestantes()); + this.labelCompteur.setHorizontalAlignment(SwingConstants.CENTER); + this.labelCompteur.setFont(new Font("Arial", Font.BOLD, 16)); + this.add(this.labelCompteur, BorderLayout.NORTH); + JPanel panneauGrille = new JPanel(); panneauGrille.setLayout(new GridLayout(g.getLignes(), g.getColonnes())); @@ -28,32 +32,36 @@ public class FenetreJeu extends JFrame { JButton boutonCase = new JButton(""); this.boutons[i][j] = boutonCase; panneauGrille.add(boutonCase); - boutonCase.addMouseListener(controleurSouris); } } this.add(panneauGrille, BorderLayout.CENTER); - JButton btnSauverQuitter = new JButton("Sauver et Quitter"); - this.add(btnSauverQuitter, BorderLayout.SOUTH); + // --- MODIFICATION DU BOUTON DU BAS --- + this.btnActionBas = new JButton("Sauver et Quitter"); + this.add(this.btnActionBas, BorderLayout.SOUTH); ControleurJeu controleurQuitter = new ControleurJeu(this); - btnSauverQuitter.addActionListener(controleurQuitter); + this.btnActionBas.addActionListener(controleurQuitter); } - public JButton getBouton(int l, int c) { - return this.boutons[l][c]; + // --- NOUVEAUX OUTILS --- + public JButton getBouton(int l, int c) { return this.boutons[l][c]; } + public Grille getGrille() { return this.grille; } // Permet au contrôleur de lire la grille + + public void changerBoutonEnRetourMenu() { + this.btnActionBas.setText("Retour au Menu"); + } + + public void mettreAJourCompteur() { + this.labelCompteur.setText("Mines restantes : " + this.grille.getMinesRestantes()); } - /** - * Met à jour le visuel d'un bouton en fonction de l'état de sa Case logique. - */ public void rafraichirCase(int l, int c) { Case caseLogique = this.grille.getCase(l, c); JButton btn = this.boutons[l][c]; if (caseLogique.isRevelee()) { btn.setEnabled(false); - if (caseLogique.isMinee()) { btn.setText("M"); btn.setBackground(Color.RED); @@ -73,10 +81,6 @@ public class FenetreJeu extends JFrame { } } - /** - * Rafraîchit l'affichage de tous les boutons de la grille d'un seul coup. - * Indispensable après une réaction en chaîne. - */ public void rafraichirTouteLaGrille() { for (int i = 0; i < grille.getLignes(); i++) { for (int j = 0; j < grille.getColonnes(); j++) { @@ -84,38 +88,25 @@ public class FenetreJeu extends JFrame { } } } - /** - * Affiche la grille de fin de partie en cas de défaite, comme demandé dans le sujet. - * @param lExplose la ligne de la mine qui a fait BOUM - * @param cExplose la colonne de la mine qui a fait BOUM - */ + public void afficherDefaite(int lExplose, int cExplose) { for (int i = 0; i < grille.getLignes(); i++) { for (int j = 0; j < grille.getColonnes(); j++) { - Case c = grille.getCase(i, j); JButton btn = boutons[i][j]; - - // On désactive le bouton pour empêcher de cliquer dessus btn.setEnabled(false); - // 1. La case dont la mine a "sauté" if (i == lExplose && j == cExplose) { btn.setText("BOUM"); btn.setBackground(Color.RED); - } - // 2. Les cases minées non marquées (les bombes oubliées) - else if (c.isMinee() && c.getMarqueur() != 1) { + } else if (c.isMinee() && c.getMarqueur() != 1) { btn.setText("M"); btn.setBackground(Color.ORANGE); - } - // 3. Les cases marquées non minées (les fausses pistes) - else if (!c.isMinee() && c.getMarqueur() == 1) { - btn.setText("X"); // Un X pour dire "Erreur" + } else if (!c.isMinee() && c.getMarqueur() == 1) { + btn.setText("X"); btn.setBackground(Color.YELLOW); } - // Si la case ne rentre pas dans ces cas, on la laisse tranquille } } } -} // <--- L'accolade finale est bien ici maintenant ! +} diff --git a/Grille.java b/Grille.java index 6ab5a95..37b9afa 100644 --- a/Grille.java +++ b/Grille.java @@ -1,15 +1,12 @@ import java.io.Serializable; import java.util.Random; -/** - * Représente le plateau de jeu contenant les cases. - */ public class Grille implements Serializable { private Case[][] plateau; private int lignes; private int colonnes; private int mines; - private boolean partieTerminee; // <--- LE FAMEUX VERROU ! + private boolean partieTerminee; public Grille(int l, int c, int m) { this.lignes = l; @@ -29,16 +26,25 @@ public class Grille implements Serializable { calculerVoisins(); } - // --- Les Getters et Setters --- public int getLignes() { return this.lignes; } public int getColonnes() { return this.colonnes; } public Case getCase(int l, int c) { return this.plateau[l][c]; } - - // <--- LES DEUX MÉTHODES QUI TE MANQUAIENT ICI ---> public boolean isPartieTerminee() { return this.partieTerminee; } public void setPartieTerminee(boolean terminee) { this.partieTerminee = terminee; } - // --- Les algorithmes du jeu --- + // --- NOUVELLE MÉTHODE : Calcul des mines restantes --- + public int getMinesRestantes() { + int drapeaux = 0; + for (int i = 0; i < this.lignes; i++) { + for (int j = 0; j < this.colonnes; j++) { + if (this.plateau[i][j].getMarqueur() == 1) { // 1 = étoile + drapeaux++; + } + } + } + return this.mines - drapeaux; + } + private void placerMines() { Random rand = new Random(); int minesPlacees = 0; @@ -76,16 +82,9 @@ public class Grille implements Serializable { public boolean revelerCase(int l, int c) { Case caseCliquee = this.plateau[l][c]; - - if (caseCliquee.isRevelee() || caseCliquee.getMarqueur() == 1) { - return false; - } - + if (caseCliquee.isRevelee() || caseCliquee.getMarqueur() == 1) return false; caseCliquee.setRevelee(true); - - if (caseCliquee.isMinee()) { - return true; - } + if (caseCliquee.isMinee()) return true; if (caseCliquee.getNbMinesVoisines() == 0) { for (int di = -1; di <= 1; di++) { @@ -105,12 +104,9 @@ public class Grille implements Serializable { int casesRevelees = 0; for (int i = 0; i < this.lignes; i++) { for (int j = 0; j < this.colonnes; j++) { - if (this.plateau[i][j].isRevelee()) { - casesRevelees++; - } + if (this.plateau[i][j].isRevelee()) casesRevelees++; } } - int casesVidesTotales = (this.lignes * this.colonnes) - this.mines; - return casesRevelees == casesVidesTotales; + return casesRevelees == ((this.lignes * this.colonnes) - this.mines); } }