forked from menault/TD3_DEV51_Qualite_Algo
		
	
		
			
				
	
	
		
			133 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			133 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
| package back;
 | |
| 
 | |
| import java.util.ArrayList;
 | |
| import java.util.HashSet;
 | |
| import java.util.List;
 | |
| import java.util.Set;
 | |
| 
 | |
| /**
 | |
|  * Logique principale du jeu du pendu (back).
 | |
|  * 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;
 | |
|     private final Set<Character> correct = new HashSet<>();
 | |
|     private final Set<Character> all = new HashSet<>();
 | |
|     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 + 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 {
 | |
|             addScore(-5);
 | |
|             if (isLose()) end(false);
 | |
|             return Result.MISS;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /** 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(' ');
 | |
|         }
 | |
|         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;
 | |
|     }
 | |
| 
 | |
|     /** Vérifie si le joueur a perdu */
 | |
|     public boolean isLose() {
 | |
|         return errors >= maxErrors;
 | |
|     }
 | |
| 
 | |
|     /** 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;
 | |
|     }
 | |
| 
 | |
|     // ---------- 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;
 | |
|     }
 | |
| }
 |