比較提交
	
		
			14 次程式碼提交
		
	
	
		
			93e31b0aac
			...
			ca5c12a7ba
		
	
	| 作者 | SHA1 | 日期 | |
|---|---|---|---|
| ca5c12a7ba | |||
| a7d9f17ba8 | |||
| 9b7ed446b2 | |||
| b707e37787 | |||
| 6f74af39d9 | |||
| 972ff65f63 | |||
| d74e119af3 | |||
| d79aec8248 | |||
| b4c8b1d156 | |||
| e0f727d76b | |||
| bd4a204d25 | |||
| fae2ecf2c8 | |||
| 7679f1f35b | |||
| fd393bfc85 | 
| @@ -7,7 +7,18 @@ import java.util.Set; | ||||
|  | ||||
| /** | ||||
|  * Logique principale du jeu du pendu (back). | ||||
|  * Gère le mot, les lettres trouvées, et les conditions de victoire/défaite. | ||||
|  * Ajoute un score et un chronomètre. | ||||
|  * | ||||
|  * Règles de score (simples) : | ||||
|  *  - Lettre correcte  : +10 points | ||||
|  *  - Lettre incorrecte:  -5 points (le score ne descend pas sous 0) | ||||
|  *  - Bonus victoire   : + (restant * 10) + bonus temps | ||||
|  *      * bonus temps = max(0, 60 - secondes) * 2   (jusqu'à 120 pts si < 60s) | ||||
|  *  - Défaite          : pas de bonus | ||||
|  * | ||||
|  * Chronomètre : | ||||
|  *  - Démarre à la création de la partie | ||||
|  *  - S'arrête définitivement à la fin (victoire/défaite) | ||||
|  */ | ||||
| public class Game { | ||||
|     private final String word; | ||||
| @@ -16,21 +27,32 @@ public class Game { | ||||
|     private final int maxErrors; | ||||
|     private int errors; | ||||
|  | ||||
|     // Score & chrono  | ||||
|     private int score = 0; | ||||
|     private long startNano;       // début de partie (System.nanoTime) | ||||
|     private long endNano = -1L;   // fin (sinon -1 = en cours) | ||||
|  | ||||
|     public Game(String word, int maxErrors) { | ||||
|         this.word = word.toLowerCase(); | ||||
|         this.maxErrors = maxErrors; | ||||
|         this.startNano = System.nanoTime(); // démarre le chrono à la création | ||||
|     } | ||||
|  | ||||
| /** Tente une lettre et renvoie le résultat */ | ||||
|     /** Tente une lettre et renvoie le résultat + ajuste le score */ | ||||
|     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); | ||||
|             addScore(10); | ||||
|             // Si la lettre trouvée fait gagner immédiatement, on finalise ici | ||||
|             if (isWin()) end(true); | ||||
|             return Result.HIT; | ||||
|         } else { | ||||
|             errors++; | ||||
|             addScore(-5); | ||||
|             if (isLose()) end(false); | ||||
|             return Result.MISS; | ||||
|         } | ||||
|     } | ||||
| @@ -62,7 +84,7 @@ public class Game { | ||||
|         return errors >= maxErrors; | ||||
|     } | ||||
|  | ||||
|     /** Renvoie le nombre d'erreurs actuelles */ | ||||
|     /** Nombre d'erreurs actuelles */ | ||||
|     public int getErrors() { return errors; } | ||||
|  | ||||
|     /** Liste les lettres déjà essayées */ | ||||
| @@ -73,4 +95,38 @@ public class Game { | ||||
|         for (Character ch : sorted) out.add(String.valueOf(ch)); | ||||
|         return out; | ||||
|     } | ||||
| } | ||||
|  | ||||
|     // -Score & Chrono | ||||
|  | ||||
|     /** Retourne le score courant */ | ||||
|     public int getScore() { return score; } | ||||
|  | ||||
|     /** Secondes écoulées depuis le début (si finie, temps figé) */ | ||||
|     public long getElapsedSeconds() { | ||||
|         long end = (endNano > 0L) ? endNano : System.nanoTime(); | ||||
|         long deltaNs = end - startNano; | ||||
|         if (deltaNs < 0) deltaNs = 0; | ||||
|         return deltaNs / 1_000_000_000L; | ||||
|     } | ||||
|  | ||||
|     /** Termine la partie (victoire/défaite) et applique le bonus si gagné */ | ||||
|     public void end(boolean win) { | ||||
|         if (endNano > 0L) return; // déjà terminé | ||||
|         endNano = System.nanoTime(); | ||||
|         if (win) { | ||||
|             int remaining = Math.max(0, maxErrors - errors); | ||||
|             int timeBonus = (int) Math.max(0, 60 - getElapsedSeconds()) * 2; | ||||
|             addScore(remaining * 10 + timeBonus); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // --- utilitaires privés --- | ||||
|     private void addScore(int delta) { | ||||
|         if (delta < 0) { | ||||
|             // lettre ratée => +1 erreur | ||||
|             errors++; | ||||
|         } | ||||
|         score += delta; | ||||
|         if (score < 0) score = 0; | ||||
|     } | ||||
| } | ||||
|   | ||||
							
								
								
									
										62
									
								
								Jeu_pendu/Front/Gallows.java
									
									
									
									
									
										一般檔案
									
								
							
							
						
						
									
										62
									
								
								Jeu_pendu/Front/Gallows.java
									
									
									
									
									
										一般檔案
									
								
							| @@ -0,0 +1,62 @@ | ||||
| package front; | ||||
|  | ||||
| import javax.swing.*; | ||||
| import java.awt.*; | ||||
| import java.io.File; | ||||
|  | ||||
| /** | ||||
|  * Gère les images du pendu (une par étape). | ||||
|  * - Charge les images depuis assets | ||||
|  */ | ||||
| public class Gallows { | ||||
|     /** Dossier d'assets relatif à la racine du projet */ | ||||
|     private static final String ASSETS_DIR = "assets" + File.separator + "images"; | ||||
|     /** Nombre d'étapes (0 = aucun membre, 7 = étape finale) */ | ||||
|     private static final int MAX_STAGE = 6; | ||||
|  | ||||
|     private static final ImageIcon[] ICONS = new ImageIcon[MAX_STAGE + 1]; | ||||
|  | ||||
|     static { | ||||
|         for (int i = 0; i <= MAX_STAGE; i++) { | ||||
|             String path = ASSETS_DIR + File.separator + i + ".png"; | ||||
|             File f = new File(path); | ||||
|             if (f.exists()) { | ||||
|                 ICONS[i] = new ImageIcon(path); | ||||
|             } else { | ||||
|                 // Placeholder si fichier manquant | ||||
|                 ICONS[i] = placeholder("Missing: " + i + ".png"); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Retourne l'icône correspondant au nombre d'erreurs. | ||||
|      */ | ||||
|     public static ImageIcon icon(int errors) { | ||||
|         int idx = Math.max(0, Math.min(errors, MAX_STAGE)); | ||||
|         return ICONS[idx]; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Crée une petite image placeholder (si un asset est manquant). | ||||
|      */ | ||||
|     private static ImageIcon placeholder(String text) { | ||||
|         int w = 320, h = 240; | ||||
|         Image img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); | ||||
|         Graphics2D g = (Graphics2D) img.getGraphics(); | ||||
|         g.setColor(Color.LIGHT_GRAY); | ||||
|         g.fillRect(0, 0, w, h); | ||||
|         g.setColor(Color.DARK_GRAY); | ||||
|         g.drawRect(0, 0, w - 1, h - 1); | ||||
|         g.drawString(text, 10, h / 2); | ||||
|         g.dispose(); | ||||
|         return new ImageIcon(img); | ||||
|     } | ||||
|  | ||||
|     // Import manquant pour BufferedImage | ||||
|     private static class BufferedImage extends java.awt.image.BufferedImage { | ||||
|         public BufferedImage(int width, int height, int imageType) { | ||||
|             super(width, height, imageType); | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										125
									
								
								Jeu_pendu/Front/GameUI.java
									
									
									
									
									
										一般檔案
									
								
							
							
						
						
									
										125
									
								
								Jeu_pendu/Front/GameUI.java
									
									
									
									
									
										一般檔案
									
								
							| @@ -0,0 +1,125 @@ | ||||
| package front; | ||||
|  | ||||
| import back.*; | ||||
| import javax.swing.*; | ||||
| import java.awt.*; | ||||
| import java.awt.event.ActionEvent; | ||||
|  | ||||
| /** | ||||
|  * Interface graphique (Swing) du jeu du pendu. | ||||
|  * - Affiche une image différente à chaque erreur. | ||||
|  * - Champ de saisie pour entrer une lettre. | ||||
|  * - Texte pour le mot masqué et les lettres essayées. | ||||
|  */ | ||||
| public class GameUI { | ||||
|     private JFrame frame; | ||||
|     private JLabel imgLabel; | ||||
|     private JLabel wordLabel; | ||||
|     private JLabel triedLabel; | ||||
|     private JTextField input; | ||||
|     private JButton tryBtn; | ||||
|     private JButton newGameBtn; | ||||
|  | ||||
|     private Game game; | ||||
|     private String currentWord; | ||||
|  | ||||
|     /** Affiche la fenêtre principale */ | ||||
|     public void show() { | ||||
|         setupUI(); | ||||
|         startNewGame(); | ||||
|         frame.setVisible(true); | ||||
|     } | ||||
|  | ||||
|     /** Initialise les composants Swing */ | ||||
|     private void setupUI() { | ||||
|         frame = new JFrame("Jeu du Pendu"); | ||||
|         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); | ||||
|         frame.setSize(520, 520); | ||||
|         frame.setLocationRelativeTo(null); | ||||
|         frame.setLayout(new BorderLayout(12, 12)); | ||||
|  | ||||
|         // Image du pendu | ||||
|         imgLabel = new JLabel("", SwingConstants.CENTER); | ||||
|         frame.add(imgLabel, BorderLayout.CENTER); | ||||
|  | ||||
|         // Panneau bas: saisie + actions | ||||
|         JPanel bottom = new JPanel(new BorderLayout(8, 8)); | ||||
|         JPanel inputPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); | ||||
|         input = new JTextField(5); | ||||
|         tryBtn = new JButton("Essayer"); | ||||
|         inputPanel.add(new JLabel("Lettre :")); | ||||
|         inputPanel.add(input); | ||||
|         inputPanel.add(tryBtn); | ||||
|  | ||||
|         newGameBtn = new JButton("Nouvelle partie"); | ||||
|         bottom.add(inputPanel, BorderLayout.WEST); | ||||
|         bottom.add(newGameBtn, BorderLayout.EAST); | ||||
|         frame.add(bottom, BorderLayout.SOUTH); | ||||
|  | ||||
|         // Panneau haut: mot + lettres essayées | ||||
|         JPanel top = new JPanel(); | ||||
|         top.setLayout(new BoxLayout(top, BoxLayout.Y_AXIS)); | ||||
|         wordLabel = new JLabel("Mot : "); | ||||
|         triedLabel = new JLabel("Lettres essayées : "); | ||||
|         wordLabel.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8)); | ||||
|         triedLabel.setBorder(BorderFactory.createEmptyBorder(0, 8, 8, 8)); | ||||
|         top.add(wordLabel); | ||||
|         top.add(triedLabel); | ||||
|         frame.add(top, BorderLayout.NORTH); | ||||
|  | ||||
|         // Actions | ||||
|         tryBtn.addActionListener(this::onTry); | ||||
|         input.addActionListener(this::onTry); | ||||
|         newGameBtn.addActionListener(e -> startNewGame()); | ||||
|     } | ||||
|  | ||||
|     /** Démarre une nouvelle partie */ | ||||
|     private void startNewGame() { | ||||
|         currentWord = Words.random(); | ||||
|         game = new Game(currentWord, 7); | ||||
|         input.setText(""); | ||||
|         input.requestFocusInWindow(); | ||||
|         refreshUI(); | ||||
|     } | ||||
|  | ||||
|     /** Gère le clic sur "Essayer" ou Entrée dans le champ */ | ||||
|     private void onTry(ActionEvent e) { | ||||
|         String text = input.getText(); | ||||
|         if (!Check.isLetter(text)) { | ||||
|             JOptionPane.showMessageDialog(frame, "Tape une seule lettre (A-Z)."); | ||||
|             input.requestFocusInWindow(); | ||||
|             input.selectAll(); | ||||
|             return; | ||||
|         } | ||||
|         char c = Character.toLowerCase(text.charAt(0)); | ||||
|         Result res = game.play(c); | ||||
|  | ||||
|         switch (res) { | ||||
|             case ALREADY: JOptionPane.showMessageDialog(frame, "Lettre déjà utilisée."); | ||||
|             break; | ||||
|             case HIT: | ||||
|             break; | ||||
|             case MISS: | ||||
|             break; | ||||
|         } | ||||
|  | ||||
|         input.setText(""); | ||||
|         refreshUI(); | ||||
|  | ||||
|         if (game.isWin()) { | ||||
|             refreshUI(); | ||||
|             JOptionPane.showMessageDialog(frame, "Bravo ! Le mot était : " + currentWord); | ||||
|         } else if (game.isLose()) { | ||||
|             refreshUI(); | ||||
|             JOptionPane.showMessageDialog(frame, "Perdu ! Le mot était : " + currentWord); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** Met à jour l'image et les textes selon l'état courant */ | ||||
|     private void refreshUI() { | ||||
|         imgLabel.setIcon(Gallows.icon(game.getErrors())); | ||||
|         wordLabel.setText("Mot : " + game.maskedWord()); | ||||
|         triedLabel.setText("Lettres essayées : " + String.join(", ", game.triedLetters())); | ||||
|         frame.repaint(); | ||||
|     } | ||||
| } | ||||
| @@ -1 +0,0 @@ | ||||
| blablabla | ||||
							
								
								
									
										17
									
								
								Jeu_pendu/Main/Main.java
									
									
									
									
									
										一般檔案
									
								
							
							
						
						
									
										17
									
								
								Jeu_pendu/Main/Main.java
									
									
									
									
									
										一般檔案
									
								
							| @@ -0,0 +1,17 @@ | ||||
| package main; | ||||
|  | ||||
| import front.GameUI; | ||||
|  | ||||
| /** | ||||
|  * Point d'entrée du programme. | ||||
|  * Lance l'interface graphique du jeu du pendu. | ||||
|  */ | ||||
| public class Main { | ||||
|     public static void main(String[] args) { | ||||
|         // Démarre l'UI Swing sur le thread de l'EDT | ||||
|         javax.swing.SwingUtilities.invokeLater(() -> { | ||||
|             GameUI ui = new GameUI(); | ||||
|             ui.show(); | ||||
|         }); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										
											二進制
										
									
								
								Jeu_pendu/assets/images/0.png
									
									
									
									
									
										一般檔案
									
								
							
							
						
						
									
										
											二進制
										
									
								
								Jeu_pendu/assets/images/0.png
									
									
									
									
									
										一般檔案
									
								
							
										
											未顯示二進位檔案。
										
									
								
							| 之後 寬度: | 高度: | 大小: 2.9 KiB | 
							
								
								
									
										
											二進制
										
									
								
								Jeu_pendu/assets/images/1.png
									
									
									
									
									
										一般檔案
									
								
							
							
						
						
									
										
											二進制
										
									
								
								Jeu_pendu/assets/images/1.png
									
									
									
									
									
										一般檔案
									
								
							
										
											未顯示二進位檔案。
										
									
								
							| 之後 寬度: | 高度: | 大小: 3.3 KiB | 
							
								
								
									
										
											二進制
										
									
								
								Jeu_pendu/assets/images/2.png
									
									
									
									
									
										一般檔案
									
								
							
							
						
						
									
										
											二進制
										
									
								
								Jeu_pendu/assets/images/2.png
									
									
									
									
									
										一般檔案
									
								
							
										
											未顯示二進位檔案。
										
									
								
							| 之後 寬度: | 高度: | 大小: 3.2 KiB | 
							
								
								
									
										
											二進制
										
									
								
								Jeu_pendu/assets/images/3.png
									
									
									
									
									
										一般檔案
									
								
							
							
						
						
									
										
											二進制
										
									
								
								Jeu_pendu/assets/images/3.png
									
									
									
									
									
										一般檔案
									
								
							
										
											未顯示二進位檔案。
										
									
								
							| 之後 寬度: | 高度: | 大小: 3.8 KiB | 
							
								
								
									
										
											二進制
										
									
								
								Jeu_pendu/assets/images/4.png
									
									
									
									
									
										一般檔案
									
								
							
							
						
						
									
										
											二進制
										
									
								
								Jeu_pendu/assets/images/4.png
									
									
									
									
									
										一般檔案
									
								
							
										
											未顯示二進位檔案。
										
									
								
							| 之後 寬度: | 高度: | 大小: 4.3 KiB | 
							
								
								
									
										
											二進制
										
									
								
								Jeu_pendu/assets/images/5.png
									
									
									
									
									
										一般檔案
									
								
							
							
						
						
									
										
											二進制
										
									
								
								Jeu_pendu/assets/images/5.png
									
									
									
									
									
										一般檔案
									
								
							
										
											未顯示二進位檔案。
										
									
								
							| 之後 寬度: | 高度: | 大小: 4.4 KiB | 
							
								
								
									
										
											二進制
										
									
								
								Jeu_pendu/assets/images/6.png
									
									
									
									
									
										一般檔案
									
								
							
							
						
						
									
										
											二進制
										
									
								
								Jeu_pendu/assets/images/6.png
									
									
									
									
									
										一般檔案
									
								
							
										
											未顯示二進位檔案。
										
									
								
							| 之後 寬度: | 高度: | 大小: 5.4 KiB | 
							
								
								
									
										27
									
								
								README.md
									
									
									
									
									
										一般檔案
									
								
							
							
						
						
									
										27
									
								
								README.md
									
									
									
									
									
										一般檔案
									
								
							| @@ -0,0 +1,27 @@ | ||||
| - **bibliothèque/mots.txt** → liste des mots à deviner (1 par ligne)   | ||||
| - **assets/images/** → images du pendu (de 0.png à 6.png)   | ||||
|  | ||||
| --- | ||||
|  | ||||
| ## Fonctionnalités | ||||
|   | ||||
| Affichage d’une **image différente du pendu** à chaque erreur   | ||||
| Lecture de mots depuis un **fichier externe** (`bibliothèque/mots.txt`)   | ||||
| Validation des entrées (une seule LETTRE à la fois)   | ||||
| Bouton **“Nouvelle partie”** pour rejouer sans relancer le programme   | ||||
| Messages de victoire / défaite | ||||
|  | ||||
| --- | ||||
|  | ||||
| ## Compilation et exécution | ||||
| Se placer préalablement dans Jeu_pendu | ||||
|  | ||||
| ### Compilation | ||||
| ```javac -d out $(find -name "*.java")``` | ||||
|  | ||||
| ### Exécution | ||||
| ```java -cp out main.Main``` | ||||
|  | ||||
| --- | ||||
|  | ||||
| Mini projet effectuer par Clément JANNAIRE et Clémence DUCREUX. | ||||
							
								
								
									
										
											二進制
										
									
								
								out/back/Check.class
									
									
									
									
									
										一般檔案
									
								
							
							
						
						
									
										
											二進制
										
									
								
								out/back/Check.class
									
									
									
									
									
										一般檔案
									
								
							
										
											未顯示二進位檔案。
										
									
								
							
							
								
								
									
										
											二進制
										
									
								
								out/back/Game.class
									
									
									
									
									
										一般檔案
									
								
							
							
						
						
									
										
											二進制
										
									
								
								out/back/Game.class
									
									
									
									
									
										一般檔案
									
								
							
										
											未顯示二進位檔案。
										
									
								
							
							
								
								
									
										
											二進制
										
									
								
								out/back/Result.class
									
									
									
									
									
										一般檔案
									
								
							
							
						
						
									
										
											二進制
										
									
								
								out/back/Result.class
									
									
									
									
									
										一般檔案
									
								
							
										
											未顯示二進位檔案。
										
									
								
							
							
								
								
									
										
											二進制
										
									
								
								out/back/Words.class
									
									
									
									
									
										一般檔案
									
								
							
							
						
						
									
										
											二進制
										
									
								
								out/back/Words.class
									
									
									
									
									
										一般檔案
									
								
							
										
											未顯示二進位檔案。
										
									
								
							
										
											未顯示二進位檔案。
										
									
								
							
							
								
								
									
										
											二進制
										
									
								
								out/front/Gallows.class
									
									
									
									
									
										一般檔案
									
								
							
							
						
						
									
										
											二進制
										
									
								
								out/front/Gallows.class
									
									
									
									
									
										一般檔案
									
								
							
										
											未顯示二進位檔案。
										
									
								
							
							
								
								
									
										
											二進制
										
									
								
								out/front/GameUI$1.class
									
									
									
									
									
										一般檔案
									
								
							
							
						
						
									
										
											二進制
										
									
								
								out/front/GameUI$1.class
									
									
									
									
									
										一般檔案
									
								
							
										
											未顯示二進位檔案。
										
									
								
							
							
								
								
									
										
											二進制
										
									
								
								out/front/GameUI.class
									
									
									
									
									
										一般檔案
									
								
							
							
						
						
									
										
											二進制
										
									
								
								out/front/GameUI.class
									
									
									
									
									
										一般檔案
									
								
							
										
											未顯示二進位檔案。
										
									
								
							
							
								
								
									
										
											二進制
										
									
								
								out/main/Main.class
									
									
									
									
									
										一般檔案
									
								
							
							
						
						
									
										
											二進制
										
									
								
								out/main/Main.class
									
									
									
									
									
										一般檔案
									
								
							
										
											未顯示二進位檔案。
										
									
								
							
		新增問題並參考
	
	封鎖使用者