forked from menault/TD3_DEV51_Qualite_Algo
		
	Merge branch 'JANNAIRE'
This commit is contained in:
		| @@ -1,76 +1,155 @@ | ||||
| package back; | ||||
| package front; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.HashSet; | ||||
| import java.util.List; | ||||
| import java.util.Set; | ||||
| import back.*; | ||||
|  | ||||
| import javax.swing.*; | ||||
| import java.awt.*; | ||||
| import java.awt.event.ActionEvent; | ||||
|  | ||||
| /** | ||||
|  * Logique principale du jeu du pendu (back). | ||||
|  * Gère le mot, les lettres trouvées, et les conditions de victoire/défaite. | ||||
|  * Interface graphique du jeu du pendu. | ||||
|  * (Toutes les méthodes ≤ 50 lignes) | ||||
|  */ | ||||
| public class Game { | ||||
|     private final String word; | ||||
|     private final Set<Character> correct = new HashSet<>(); | ||||
|     private final Set<Character> all = new HashSet<>(); | ||||
|     private final int maxErrors; | ||||
|     private int errors; | ||||
| public class GameUI { | ||||
|     private JFrame frame; | ||||
|     private JLabel imgLabel, wordLabel, triedLabel, scoreLabel, timeLabel; | ||||
|     private JTextField input; | ||||
|     private JButton tryBtn, newGameBtn; | ||||
|     private Game game; | ||||
|     private String currentWord; | ||||
|     private Timer timer; | ||||
|  | ||||
|     public Game(String word, int maxErrors) { | ||||
|         this.word = word.toLowerCase(); | ||||
|         this.maxErrors = maxErrors; | ||||
|     /** Lance la fenêtre et démarre une partie */ | ||||
|     public void show() { | ||||
|         setupWindow(); | ||||
|         setupLayout(); | ||||
|         setupActions(); | ||||
|         startNewGame(); | ||||
|         frame.setVisible(true); | ||||
|     } | ||||
|  | ||||
| /** Tente une lettre et renvoie le résultat */ | ||||
|     public Result play(char letter) { | ||||
|         char c = Character.toLowerCase(letter); | ||||
|         if (all.contains(c)) return Result.ALREADY; | ||||
|         all.add(c); | ||||
|         if (word.indexOf(c) >= 0) { | ||||
|             correct.add(c); | ||||
|             return Result.HIT; | ||||
|         } else { | ||||
|             errors++; | ||||
|             return Result.MISS; | ||||
|     /** Crée la fenêtre principale */ | ||||
|     private void setupWindow() { | ||||
|         frame = new JFrame("Jeu du Pendu"); | ||||
|         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); | ||||
|         frame.setSize(560, 560); | ||||
|         frame.setLocationRelativeTo(null); | ||||
|         frame.setLayout(new BorderLayout(12, 12)); | ||||
|     } | ||||
|  | ||||
|     /** Construit les composants et le layout */ | ||||
|     private void setupLayout() { | ||||
|         imgLabel = new JLabel("", SwingConstants.CENTER); | ||||
|         frame.add(imgLabel, BorderLayout.CENTER); | ||||
|  | ||||
|         wordLabel = new JLabel("Mot : "); | ||||
|         triedLabel = new JLabel("Lettres essayées : "); | ||||
|         scoreLabel = new JLabel("Score : 0"); | ||||
|         timeLabel = new JLabel("Temps : 0s"); | ||||
|  | ||||
|         JPanel top = new JPanel(new GridLayout(2, 1)); | ||||
|         top.add(buildTopLine(wordLabel, scoreLabel)); | ||||
|         top.add(buildTopLine(triedLabel, timeLabel)); | ||||
|         frame.add(top, BorderLayout.NORTH); | ||||
|  | ||||
|         JPanel bottom = new JPanel(new BorderLayout(8, 8)); | ||||
|         JPanel inputPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); | ||||
|         input = new JTextField(5); | ||||
|         tryBtn = new JButton("Essayer"); | ||||
|         newGameBtn = new JButton("Nouvelle partie"); | ||||
|         inputPanel.add(new JLabel("Lettre :")); | ||||
|         inputPanel.add(input); | ||||
|         inputPanel.add(tryBtn); | ||||
|         bottom.add(inputPanel, BorderLayout.WEST); | ||||
|         bottom.add(newGameBtn, BorderLayout.EAST); | ||||
|         frame.add(bottom, BorderLayout.SOUTH); | ||||
|     } | ||||
|  | ||||
|     /** Crée une ligne du haut avec 2 labels */ | ||||
|     private JPanel buildTopLine(JLabel left, JLabel right) { | ||||
|         JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT)); | ||||
|         panel.add(left); | ||||
|         panel.add(Box.createHorizontalStrut(24)); | ||||
|         panel.add(right); | ||||
|         return panel; | ||||
|     } | ||||
|  | ||||
|     /** Ajoute les actions et le timer */ | ||||
|     private void setupActions() { | ||||
|         tryBtn.addActionListener(this::onTry); | ||||
|         input.addActionListener(this::onTry); | ||||
|         newGameBtn.addActionListener(e -> startNewGame()); | ||||
|         timer = new Timer(1000, e -> refreshStatsOnly()); | ||||
|     } | ||||
|  | ||||
|     /** Démarre une nouvelle partie */ | ||||
|     private void startNewGame() { | ||||
|         currentWord = Words.random(); | ||||
|         game = new Game(currentWord, 7); | ||||
|         input.setText(""); | ||||
|         input.requestFocusInWindow(); | ||||
|         if (!timer.isRunning()) timer.start(); | ||||
|         refreshUI(); | ||||
|     } | ||||
|  | ||||
|     /** Gère le clic ou l'appui sur Entrée */ | ||||
|     private void onTry(ActionEvent e) { | ||||
|         String text = input.getText(); | ||||
|         if (!Check.isLetter(text)) { | ||||
|             showMsg("Tape une seule lettre (A-Z)."); | ||||
|             input.requestFocusInWindow(); | ||||
|             input.selectAll(); | ||||
|             return; | ||||
|         } | ||||
|         Result res = game.play(Character.toLowerCase(text.charAt(0))); | ||||
|         handleResult(res); | ||||
|         input.setText(""); | ||||
|         refreshUI(); | ||||
|         checkEnd(); | ||||
|     } | ||||
|  | ||||
|     /** Réagit selon le résultat d'une tentative */ | ||||
|     private void handleResult(Result res) { | ||||
|         switch (res) { | ||||
|             case ALREADY: | ||||
|                 showMsg("Lettre déjà utilisée."); | ||||
|                 break; | ||||
|             case HIT: | ||||
|             case MISS: | ||||
|                 break; // rien, juste refresh | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** Retourne le mot masqué avec les lettres trouvées */ | ||||
|     public String maskedWord() { | ||||
|         StringBuilder sb = new StringBuilder(); | ||||
|         for (int i = 0; i < word.length(); i++) { | ||||
|             char c = word.charAt(i); | ||||
|             if (!Character.isLetter(c)) sb.append(c); | ||||
|             else if (correct.contains(c)) sb.append(c); | ||||
|             else sb.append('_'); | ||||
|             if (i < word.length() - 1) sb.append(' '); | ||||
|     /** Vérifie si la partie est finie */ | ||||
|     private void checkEnd() { | ||||
|         if (game.isWin() || game.isLose()) { | ||||
|             timer.stop(); | ||||
|             game.end(game.isWin()); | ||||
|             String msg = (game.isWin() ? "Bravo !" : "Perdu !") | ||||
|                     + " Le mot était : " + currentWord | ||||
|                     + "\nScore final : " + game.getScore() | ||||
|                     + "\nTemps : " + game.getElapsedSeconds() + "s"; | ||||
|             showMsg(msg); | ||||
|         } | ||||
|         return sb.toString(); | ||||
|     } | ||||
|  | ||||
|     /** Vérifie si le joueur a gagné */ | ||||
|     public boolean isWin() { | ||||
|         for (int i = 0; i < word.length(); i++) { | ||||
|             char c = word.charAt(i); | ||||
|             if (Character.isLetter(c) && !correct.contains(c)) return false; | ||||
|         } | ||||
|         return true; | ||||
|     /** Met à jour tout l'affichage */ | ||||
|     private void refreshUI() { | ||||
|         imgLabel.setIcon(Gallows.icon(game.getErrors())); | ||||
|         wordLabel.setText("Mot : " + game.maskedWord()); | ||||
|         triedLabel.setText("Lettres essayées : " + String.join(", ", game.triedLetters())); | ||||
|         refreshStatsOnly(); | ||||
|         frame.repaint(); | ||||
|     } | ||||
|  | ||||
|     /** Vérifie si le joueur a perdu */ | ||||
|     public boolean isLose() { | ||||
|         return errors >= maxErrors; | ||||
|     /** Met à jour uniquement score + chrono */ | ||||
|     private void refreshStatsOnly() { | ||||
|         scoreLabel.setText("Score : " + game.getScore()); | ||||
|         timeLabel.setText("Temps : " + game.getElapsedSeconds() + "s"); | ||||
|     } | ||||
|  | ||||
|     /** Renvoie le nombre d'erreurs actuelles */ | ||||
|     public int getErrors() { return errors; } | ||||
|  | ||||
|     /** Liste les lettres déjà essayées */ | ||||
|     public List<String> triedLetters() { | ||||
|         List<Character> sorted = new ArrayList<>(all); | ||||
|         sorted.sort(Character::compareTo); | ||||
|         List<String> out = new ArrayList<>(); | ||||
|         for (Character ch : sorted) out.add(String.valueOf(ch)); | ||||
|         return out; | ||||
|     /** Affiche une boîte de message */ | ||||
|     private void showMsg(String msg) { | ||||
|         JOptionPane.showMessageDialog(frame, msg); | ||||
|     } | ||||
| } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user