12 Commits

Author SHA1 Message Date
Clemence DUCREUX a7d9f17ba8 README.md 2025-10-08 14:51:14 +02:00
Clement JANNAIRE 9b7ed446b2 images 2025-10-08 14:48:28 +02:00
Clemence DUCREUX b707e37787 Réparation 2025-10-08 14:46:44 +02:00
Clemence DUCREUX 6f74af39d9 ? 2025-10-08 14:38:58 +02:00
Clemence DUCREUX 972ff65f63 Merge branch 'master' of https://grond.iut-fbleau.fr/jannaire/TD3_DEV51_DUCREUX_JANNAIRE 2025-10-08 14:36:29 +02:00
Clemence DUCREUX d74e119af3 README.md 2025-10-08 14:25:18 +02:00
Clement JANNAIRE d79aec8248 modification des images 2025-10-08 14:19:44 +02:00
Clement JANNAIRE b4c8b1d156 Erreur nom fichier 2025-10-08 12:14:42 +02:00
Clemence DUCREUX e0f727d76b correction 2025-10-08 12:13:04 +02:00
Clemence DUCREUX bd4a204d25 correction 2025-10-08 12:11:52 +02:00
Clemence DUCREUX fae2ecf2c8 Merge branch 'DUCREUX' 2025-10-08 12:05:11 +02:00
Clement JANNAIRE 93e31b0aac ajout du back et bibliotheque 2025-10-08 11:58:51 +02:00
22 changed files with 1049 additions and 5 deletions
+13
View File
@@ -0,0 +1,13 @@
package back;
/**
* Vérifie la validité des entrées utilisateur.
*/
public class Check {
/** Retourne vrai si la saisie est une seule lettre alphabétique */
public static boolean isLetter(String value) {
if (value == null) return false;
String trimmed = value.trim();
return trimmed.length() == 1 && Character.isLetter(trimmed.charAt(0));
}
}
+76
View File
@@ -0,0 +1,76 @@
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).
* Gère le mot, les lettres trouvées, et les conditions de 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;
public Game(String word, int maxErrors) {
this.word = word.toLowerCase();
this.maxErrors = maxErrors;
}
/** 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;
}
}
/** 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;
}
/** 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;
}
}
+6
View File
@@ -0,0 +1,6 @@
package back;
/**
* Résultat possible d'une tentative.
*/
public enum Result { HIT, MISS, ALREADY }
+85
View File
@@ -0,0 +1,85 @@
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<String> 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<String> 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<String> loadFromFileOrDefault() {
List<String> 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<String> readUtf8Lines(Path path) {
List<String> result = new ArrayList<>();
try (Stream<String> 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;
}
}
File diff suppressed because it is too large Load Diff
+7 -5
View File
@@ -95,9 +95,12 @@ public class GameUI {
Result res = game.play(c);
switch (res) {
case ALREADY -> JOptionPane.showMessageDialog(frame, "Lettre déjà utilisée.");
case HIT -> {} // rien, rafraîchissement visuel suffit
case MISS -> {} // idem
case ALREADY: JOptionPane.showMessageDialog(frame, "Lettre déjà utilisée.");
break;
case HIT:
break;
case MISS:
break;
}
input.setText("");
@@ -119,5 +122,4 @@ public class GameUI {
triedLabel.setText("Lettres essayées : " + String.join(", ", game.triedLetters()));
frame.repaint();
}
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

+27
View File
@@ -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 dune **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.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.