package back; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.security.SecureRandom; import java.util.ArrayList; import java.util.List; import java.util.stream.Stream; /** * Fournit les mots pour le jeu. * - Lit d'abord "bibliothèque/mots.txt" (UTF-8), 1 mot par ligne. * - Ignore les lignes vides et celles qui commencent par '#'. * - Si le fichier est introuvable ou vide, bascule sur une liste par défaut. */ public class Words { /** Chemin du fichier de mots (relatif à la racine du projet). */ private static final Path WORDS_PATH = Paths.get("Bibliotheque", "mots.txt"); /** Liste de secours si le fichier n'est pas disponible. */ private static final List DEFAULT = List.of( "algorithm", "variable", "function", "interface", "inheritance", "exception", "compiler", "database", "network", "architecture", "iteration", "recursion", "encryption", "framework", "protocol" ); /** RNG partagé et cache des mots chargés. */ private static final SecureRandom RNG = new SecureRandom(); private static volatile List CACHE = null; /** * Retourne un mot choisi au hasard depuis le fichier ou la liste par défaut. * Déclenche un chargement paresseux (lazy-load) si nécessaire. */ public static String random() { ensureLoaded(); return CACHE.get(RNG.nextInt(CACHE.size())); } /** * Recharge les mots depuis le fichier. Utile si modification de mots.txt à chaud. */ public static synchronized void reload() { CACHE = loadFromFileOrDefault(); } /** Garantit que le cache est initialisé. */ private static void ensureLoaded() { if (CACHE == null) { synchronized (Words.class) { if (CACHE == null) { CACHE = loadFromFileOrDefault(); } } } } /** Tente de charger depuis le fichier, sinon renvoie la liste par défaut. */ private static List loadFromFileOrDefault() { List fromFile = readUtf8Lines(WORDS_PATH); if (fromFile.isEmpty()) return DEFAULT; return fromFile; } /** * Lit toutes les lignes UTF-8 depuis le chemin fourni, * en filtrant vides et commentaires (# ...). */ private static List readUtf8Lines(Path path) { List result = new ArrayList<>(); try (Stream lines = Files.lines(path, StandardCharsets.UTF_8)) { lines.map(String::trim) .filter(s -> !s.isEmpty()) .filter(s -> !s.startsWith("#")) .forEach(result::add); } catch (IOException e) { // Silencieux : on basculera sur DEFAULT } return result; } /* Retourne la liste complète des mots disponibles */ public static List all() { ensureLoaded(); return new ArrayList<>(CACHE); } /* Petit utilitaire pour afficher un mot masqué dans les messages */ public static String hiddenWord(Game g) { return g.maskedWord().replace(' ', '_'); } }