diff --git a/Makefile b/Makefile index 8833e5c..f6b0108 100644 --- a/Makefile +++ b/Makefile @@ -15,16 +15,22 @@ JCFLAGS = -encoding UTF-8 -implicit:none -cp $(OUT) -d $(OUT) CLASSFILES = Pendu.class \ Partie.class \ Fenetre.class \ - Dessin.class + Dessin.class \ + Mots.class \ + Event.class \ + LetterInputFilter.class \ + MenuDifficulte.class \ + Chronometre.class \ + Score.class # Dépendances -$(OUT)Pendu.class : $(IN)Pendu.java $(OUT)Partie.class $(OUT)Fenetre.class +$(OUT)Pendu.class : $(IN)Pendu.java $(OUT)Partie.class $(OUT)Fenetre.class $(OUT)Event.class $(OUT)MenuDifficulte.class $(OUT)Score.class $(JC) $(JCFLAGS) $< $(OUT)Partie.class : $(IN)Partie.java $(OUT)Mots.class $(JC) $(JCFLAGS) $< -$(OUT)Fenetre.class : $(IN)Fenetre.java $(OUT)Partie.class $(OUT)Dessin.class +$(OUT)Fenetre.class : $(IN)Fenetre.java $(OUT)Partie.class $(OUT)Dessin.class $(OUT)Chronometre.class $(OUT)Score.class $(JC) $(JCFLAGS) $< $(OUT)Dessin.class : $(IN)Dessin.java @@ -33,6 +39,21 @@ $(OUT)Dessin.class : $(IN)Dessin.java $(OUT)Mots.class : $(IN)Mots.java $(JC) $(JCFLAGS) $< +$(OUT)Event.class : $(IN)Event.java $(OUT)Fenetre.class $(OUT)LetterInputFilter.class + $(JC) $(JCFLAGS) $< + +$(OUT)LetterInputFilter.class : $(IN)LetterInputFilter.java $(OUT)Fenetre.class + $(JC) $(JCFLAGS) $< + +$(OUT)MenuDifficulte.class : $(IN)MenuDifficulte.java + $(JC) $(JCFLAGS) $< + +$(OUT)Chronometre.class : $(IN)Chronometre.java + $(JC) $(JCFLAGS) $< + +$(OUT)Score.class : $(IN)Score.java + $(JC) $(JCFLAGS) $< + # Commandes Pendu : $(OUT)Pendu.class diff --git a/bin/Chronometre.class b/bin/Chronometre.class new file mode 100644 index 0000000..4871647 Binary files /dev/null and b/bin/Chronometre.class differ diff --git a/bin/Dessin.class b/bin/Dessin.class new file mode 100644 index 0000000..60bf745 Binary files /dev/null and b/bin/Dessin.class differ diff --git a/bin/Event.class b/bin/Event.class new file mode 100644 index 0000000..d5dec5b Binary files /dev/null and b/bin/Event.class differ diff --git a/bin/Fenetre.class b/bin/Fenetre.class new file mode 100644 index 0000000..bc94053 Binary files /dev/null and b/bin/Fenetre.class differ diff --git a/bin/LetterInputFilter.class b/bin/LetterInputFilter.class new file mode 100644 index 0000000..7f7f63e Binary files /dev/null and b/bin/LetterInputFilter.class differ diff --git a/bin/MenuDifficulte.class b/bin/MenuDifficulte.class new file mode 100644 index 0000000..c6d76f0 Binary files /dev/null and b/bin/MenuDifficulte.class differ diff --git a/bin/Mots.class b/bin/Mots.class new file mode 100644 index 0000000..90a75e0 Binary files /dev/null and b/bin/Mots.class differ diff --git a/bin/Partie.class b/bin/Partie.class new file mode 100644 index 0000000..d544b32 Binary files /dev/null and b/bin/Partie.class differ diff --git a/bin/Pendu$GameLetterHandler.class b/bin/Pendu$GameLetterHandler.class new file mode 100644 index 0000000..2de8423 Binary files /dev/null and b/bin/Pendu$GameLetterHandler.class differ diff --git a/bin/Pendu.class b/bin/Pendu.class new file mode 100644 index 0000000..4b25948 Binary files /dev/null and b/bin/Pendu.class differ diff --git a/bin/Score.class b/bin/Score.class new file mode 100644 index 0000000..9ffeb11 Binary files /dev/null and b/bin/Score.class differ diff --git a/src/Partie.java b/src/Partie.java index f6421b5..84e2f8f 100644 --- a/src/Partie.java +++ b/src/Partie.java @@ -10,7 +10,7 @@ import java.util.Random; */ public class Partie { //Contantes - private static final byte REMAININGTRY = 11 ; + private static final byte REMAININGTRY = 6 ; private static final byte CARACTERCODESHIFT = 65 ; //Décalage ASCI > 'A' //Attributs diff --git a/src/Pendu.java b/src/Pendu.java index dcdcddc..cfebb1d 100644 --- a/src/Pendu.java +++ b/src/Pendu.java @@ -6,7 +6,7 @@ import java.util.function.Consumer; * Lie Fenetre (vue) et Partie (logique) via un handler. * Met à jour le dessin du pendu à chaque erreur. * - * @version 1.3 + * @version 1.4 * author Adrien * Date : 08-10-2025 * Licence : @@ -27,36 +27,54 @@ public class Pendu { Partie partie = new Partie(); - // Affichage initial du mot masqué (via Partie) - fenetre.getWordLabel().setText(partie.getMaskedWord()); + // Affichage initial du mot masqué (construit ici) + fenetre.getWordLabel().setText(buildMaskedWord(partie)); // Stage initial (0 erreur) if (fenetre.getDrawZone() instanceof Dessin) { ((Dessin) fenetre.getDrawZone()).setStage(0); } - // Handler : applique Partie puis met à jour l'UI (mot + dessin) - Consumer handler = new GameLetterHandler(fenetre, partie); + // On mémorise les essais initiaux pour calculer les erreurs = initialTries - remainingTry + final int initialTries = partie.getRemainingTry(); + + // Handler : applique Partie puis met à jour l'UI (mot + dessin + score) + Consumer handler = new GameLetterHandler(fenetre, partie, initialTries); // Branchement des événements clavier/bouton new Event(fenetre, handler); } + /** Construit la chaîne "_ _ A _ _" à partir de l'état de Partie (sans modifier Partie). */ + private static String buildMaskedWord(Partie partie) { + char[] word = partie.getSecretWord(); + boolean[] found = partie.getFoundLetters(); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < word.length; i++) { + sb.append(found[i] ? word[i] : '_'); + if (i < word.length - 1) sb.append(' '); + } + return sb.toString(); + } + /** * Handler de lettres : * - applique Partie.isAlreadyEntries - * - met à jour le mot affiché (Partie#getMaskedWord) - * - calcule le stage = MAX_STAGE - remainingTry et met à jour le Dessin + * - met à jour le mot affiché + * - calcule errors = initialTries - remainingTry, puis stage = min(errors, Dessin.MAX_STAGE) + * - met à jour le score * - gère la fin de partie */ private static class GameLetterHandler implements Consumer { private final Fenetre fenetre; private final Partie partie; + private final int initialTries; // essais au démarrage (peut être 11 avec ta Partie) private final Dessin dessinPanel; - GameLetterHandler(Fenetre fenetre, Partie partie) { + GameLetterHandler(Fenetre fenetre, Partie partie, int initialTries) { this.fenetre = fenetre; this.partie = partie; + this.initialTries = initialTries; this.dessinPanel = (fenetre.getDrawZone() instanceof Dessin) ? (Dessin) fenetre.getDrawZone() : null; } @@ -66,20 +84,20 @@ public class Pendu { boolean alreadyPlayed = partie.isAlreadyEntries(ch); // Mise à jour du mot - fenetre.getWordLabel().setText(partie.getMaskedWord()); + fenetre.getWordLabel().setText(buildMaskedWord(partie)); - // Erreurs -> stage pour le dessin + // Erreurs -> stage pour le dessin (borné à MAX_STAGE) + int errors = Math.max(0, initialTries - partie.getRemainingTry()); if (dessinPanel != null) { - int stage = Dessin.MAX_STAGE - partie.getRemainingTry(); + int stage = Math.min(errors, Dessin.MAX_STAGE); dessinPanel.setStage(stage); } - // Mise à jour du score courant (erreurs + temps actuel) + // Mise à jour du score courant (si tu utilises Score + Chronometre) long elapsed = (fenetre.getChronometre() != null) ? fenetre.getChronometre().getElapsedMillis() : 0L; - int errors = Dessin.MAX_STAGE - partie.getRemainingTry(); - int score = Score.compute(errors, elapsed); if (fenetre.getScoreLabel() != null) { + int score = Score.compute(errors, elapsed); fenetre.getScoreLabel().setText("Score : " + score); } @@ -94,10 +112,10 @@ public class Pendu { if (fenetre.getChronometre() != null) { fenetre.getChronometre().stop(); } - // Score final recalculé (au cas où une seconde vient de passer) + // Score final (si Score/Chronometre présents) long finalElapsed = (fenetre.getChronometre() != null) ? fenetre.getChronometre().getElapsedMillis() : elapsed; - int finalErrors = Dessin.MAX_STAGE - partie.getRemainingTry(); + int finalErrors = Math.max(0, initialTries - partie.getRemainingTry()); int finalScore = Score.compute(finalErrors, finalElapsed); boolean win = !fenetre.getWordLabel().getText().contains("_"); @@ -105,7 +123,7 @@ public class Pendu { ? "Bravo ! Mot trouvé : " : "Perdu ! Le mot était : ") + String.valueOf(partie.getSecretWord()) - + "\nScore : " + finalScore; + + (fenetre.getScoreLabel() != null ? "\nScore : " + finalScore : ""); JOptionPane.showMessageDialog(fenetre.getWindow(), msg);