Compare commits

...

7 Commits

Author SHA1 Message Date
dfa47463b1 chore: remove unused files 2025-10-08 15:16:28 +02:00
c3dc8f73ed feat: timer, difficulty and score 2025-10-08 15:16:27 +02:00
3679e1a732 feat: manager that uses the words from the dictionnary in ~/res/ 2025-10-08 15:16:27 +02:00
001cc1d32a feat: dictionnaire de mots 2025-10-08 15:16:27 +02:00
3af3ed9e8a maj 2025-10-08 15:16:27 +02:00
d52b072c92 chameauuuuuu 2025-10-08 15:16:27 +02:00
15061d6afd bamba chameau 2025-10-08 15:16:27 +02:00
7 changed files with 366 additions and 119 deletions

View File

@@ -1,4 +1,4 @@
#FACILE
#EASY
banane
ceinture
maman
@@ -219,7 +219,7 @@ clef
terre
voisine
chapeau
#MOYEN
#MEDIUM
serpent
orage
bracelet
@@ -400,7 +400,7 @@ salon
siege
garage
poesie
#DIFFICILE
#HARD
adaptation
paradoxe
imaginatif

Binary file not shown.

View File

@@ -1,51 +0,0 @@
import java.io.*;
import java.util.*;
public class GestionMotsPendu {
private static final String CHEMIN_FICHIER = "../res/mots_pendu.txt";
private final Map<String, List<String>> motsParDifficulte = new HashMap<>();
public GestionMotsPendu() throws IOException {
motsParDifficulte.put("FACILE", new ArrayList<>());
motsParDifficulte.put("MOYEN", new ArrayList<>());
motsParDifficulte.put("DIFFICILE", new ArrayList<>());
chargerMots();
}
private void chargerMots() throws IOException {
try (BufferedReader reader = new BufferedReader(new FileReader(CHEMIN_FICHIER))) {
String ligne;
String section = "";
while ((ligne = reader.readLine()) != null) {
ligne = ligne.trim();
if (ligne.startsWith("#")) {
section = ligne.substring(1).toUpperCase();
} else if (!ligne.isEmpty() && motsParDifficulte.containsKey(section)) {
motsParDifficulte.get(section).add(ligne);
}
}
} catch (FileNotFoundException e) {
throw new IOException("Fichier introuvable : " + CHEMIN_FICHIER);
}
}
public String getMotAleatoire(int difficulte) {
String cle = convertirDifficulte(difficulte);
List<String> liste = motsParDifficulte.get(cle);
if (liste == null || liste.isEmpty()) return null;
Random rand = new Random();
return liste.get(rand.nextInt(liste.size()));
}
private String convertirDifficulte(int difficulte) {
return switch (difficulte) {
case 1 -> "FACILE";
case 2 -> "MOYEN";
case 3 -> "DIFFICILE";
default -> "FACILE"; // Valeur par défaut
};
}
}

306
src/HangmanGUI.java Normal file
View File

@@ -0,0 +1,306 @@
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.util.Timer;
import java.util.TimerTask;
/**
* Hangman GUI with difficulty selection, dynamic score, and timer.
* Uses WordManager for words.
* User-facing texts remain in French.
*/
public class HangmanGUI extends JFrame {
private WordManager manager;
private String secretWord;
private final Set<Character> found = new HashSet<>();
private final Set<Character> tried = new HashSet<>();
private int errors = 0;
private static final int MAX_ERRORS = 8;
private boolean gameOver = false;
// scoring and timing
private int baseScore = 200;
private int mistakePenalty = 15;
private double timePenaltyPerSecond = 1.0;
private long startTime;
// UI components
private final JLabel wordLbl = new JLabel("", SwingConstants.CENTER);
private final JLabel triedLbl = new JLabel("", SwingConstants.CENTER);
private final JLabel infoLbl = new JLabel("Entrez une lettre (a-z)", SwingConstants.CENTER);
private final JLabel scoreLbl = new JLabel("Score: 0", SwingConstants.CENTER);
private final JLabel timerLbl = new JLabel("Temps: 0s", SwingConstants.CENTER);
private final JTextField input = new JTextField();
private final JButton guessBtn = new JButton("Proposer");
private final HangPanel hangPanel = new HangPanel();
private final String[] difficulties = {"Facile", "Moyen", "Difficile"};
private final JComboBox<String> difficultyCombo = new JComboBox<>(difficulties);
private Timer timer;
/** Drawing panel for hangman */
private static class HangPanel extends JPanel {
private int errors = 0;
public void setErrors(int e) {
this.errors = Math.max(0, Math.min(e, MAX_ERRORS));
repaint();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D gg = (Graphics2D) g;
gg.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
int w = getWidth(), h = getHeight();
int baseY = h - 40;
if (errors >= 1) gg.drawLine(50, baseY, w - 50, baseY);
if (errors >= 2) gg.drawLine(100, baseY, 100, 60);
if (errors >= 3) gg.drawLine(100, 60, 220, 60);
if (errors >= 4) gg.drawLine(220, 60, 220, 90);
if (errors >= 5) gg.drawOval(200, 90, 40, 40);
if (errors >= 6) gg.drawLine(220, 130, 220, 200);
if (errors >= 7) {
gg.drawLine(220, 145, 190, 165);
gg.drawLine(220, 145, 250, 165);
}
if (errors >= 8) {
gg.drawLine(220, 200, 200, 240);
gg.drawLine(220, 200, 240, 240);
}
}
}
/** Entry point */
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
try {
HangmanGUI app = new HangmanGUI();
app.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
});
}
/** Constructor */
public HangmanGUI() throws Exception {
super("Jeu du Pendu");
manager = new WordManager();
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setSize(560, 620);
setLocationRelativeTo(null);
setupUI();
startGame();
}
/** Setup UI */
private void setupUI() {
wordLbl.setFont(new Font(Font.MONOSPACED, Font.BOLD, 28));
triedLbl.setFont(new Font("SansSerif", Font.PLAIN, 14));
infoLbl.setFont(new Font("SansSerif", Font.PLAIN, 14));
scoreLbl.setFont(new Font("SansSerif", Font.BOLD, 16));
timerLbl.setFont(new Font("SansSerif", Font.BOLD, 16));
JPanel top = new JPanel(new GridLayout(6, 1, 8, 8));
top.add(wordLbl);
top.add(triedLbl);
top.add(infoLbl);
JPanel scorePanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 20, 5));
scorePanel.add(scoreLbl);
scorePanel.add(timerLbl);
top.add(scorePanel);
JPanel diffPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
diffPanel.add(new JLabel("Difficulté:"));
diffPanel.add(difficultyCombo);
top.add(diffPanel);
JButton restartBtn = new JButton("Rejouer");
restartBtn.addActionListener(e -> startGame());
JPanel restartPanel = new JPanel();
restartPanel.add(restartBtn);
top.add(restartPanel);
JPanel controls = new JPanel(new BorderLayout(8, 8));
controls.add(input, BorderLayout.CENTER);
controls.add(guessBtn, BorderLayout.EAST);
hangPanel.setPreferredSize(new Dimension(500, 300));
JPanel center = new JPanel(new BorderLayout());
center.add(hangPanel, BorderLayout.CENTER);
JPanel main = new JPanel(new BorderLayout(10, 10));
main.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
main.add(top, BorderLayout.NORTH);
main.add(center, BorderLayout.CENTER);
main.add(controls, BorderLayout.SOUTH);
setContentPane(main);
guessBtn.addActionListener(e -> onGuess());
input.addActionListener(e -> onGuess());
addWindowListener(new WindowAdapter() {
@Override public void windowOpened(WindowEvent e) { input.requestFocusInWindow(); }
});
}
/** Start new game */
private void startGame() {
int diffIndex = difficultyCombo.getSelectedIndex(); // 0=Facile,1=Moyen,2=Difficile
int diffValue = diffIndex + 1;
secretWord = manager.getRandomWord(diffValue).toLowerCase(Locale.ROOT);
found.clear();
tried.clear();
errors = 0;
gameOver = false;
startTime = System.currentTimeMillis();
input.setText("");
input.setEditable(true);
guessBtn.setEnabled(true);
infoLbl.setText("Entrez une lettre (a-z)");
updateUIState();
if (timer != null) timer.cancel();
timer = new Timer(true);
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
SwingUtilities.invokeLater(() -> {
updateScoreLabel();
updateTimerLabel();
});
}
}, 0, 200);
}
/** Handle guess */
private void onGuess() {
if (gameOver) return;
String s = input.getText().trim().toLowerCase(Locale.ROOT);
if (s.length() != 1 || s.charAt(0) < 'a' || s.charAt(0) > 'z') {
infoLbl.setText("Veuillez entrer une seule lettre (a-z).");
input.selectAll();
input.requestFocusInWindow();
return;
}
char c = s.charAt(0);
if (tried.contains(c)) {
infoLbl.setText("Lettre déjà essayée : " + c);
input.selectAll();
input.requestFocusInWindow();
return;
}
tried.add(c);
boolean hit = false;
for (int i = 0; i < secretWord.length(); i++) {
if (secretWord.charAt(i) == c) {
found.add(c);
hit = true;
}
}
if (!hit) {
errors++;
infoLbl.setText("Mauvaise lettre : " + c);
} else {
infoLbl.setText("Bonne lettre : " + c);
}
updateUIState();
input.selectAll();
input.requestFocusInWindow();
}
/** Update UI */
private void updateUIState() {
wordLbl.setText(maskWord(secretWord, found));
triedLbl.setText("Lettres essayées : " + joinChars(tried));
hangPanel.setErrors(errors);
updateScoreLabel();
updateTimerLabel();
if (isWin(secretWord, found)) {
infoLbl.setText("Bravo ! Vous avez trouvé le mot : " + secretWord);
wordLbl.setText(spaced(secretWord));
gameOver = true;
disableInput();
} else if (errors >= MAX_ERRORS) {
infoLbl.setText("Perdu ! Le mot était : " + secretWord);
wordLbl.setText(spaced(secretWord));
gameOver = true;
disableInput();
}
}
/** Update dynamic score */
private void updateScoreLabel() {
long elapsedMillis = System.currentTimeMillis() - startTime;
double elapsedSeconds = elapsedMillis / 1000.0;
int score = (int) (baseScore - errors * mistakePenalty - elapsedSeconds * timePenaltyPerSecond);
scoreLbl.setText("Score: " + Math.max(score, 0));
}
/** Update dynamic timer */
private void updateTimerLabel() {
long elapsedMillis = System.currentTimeMillis() - startTime;
int seconds = (int) (elapsedMillis / 1000);
timerLbl.setText("Temps: " + seconds + "s");
}
/** Disable input after end */
private void disableInput() {
input.setEditable(false);
guessBtn.setEnabled(false);
if (timer != null) timer.cancel();
}
private String maskWord(String secret, Set<Character> foundSet) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < secret.length(); i++) {
char ch = secret.charAt(i);
char lc = Character.toLowerCase(ch);
if (Character.isLetter(lc) && !foundSet.contains(lc)) sb.append('_');
else sb.append(ch);
if (i < secret.length() - 1) sb.append(' ');
}
return sb.toString();
}
private boolean isWin(String secret, Set<Character> foundSet) {
for (int i = 0; i < secret.length(); i++) {
char lc = Character.toLowerCase(secret.charAt(i));
if (Character.isLetter(lc) && !foundSet.contains(lc)) return false;
}
return true;
}
private String joinChars(Set<Character> set) {
java.util.List<Character> list = new ArrayList<>(set);
Collections.sort(list);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < list.size(); i++) {
sb.append(list.get(i));
if (i < list.size() - 1) sb.append(' ');
}
return sb.toString();
}
private String spaced(String s) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
sb.append(s.charAt(i));
if (i < s.length() - 1) sb.append(' ');
}
return sb.toString();
}
}

Binary file not shown.

View File

@@ -1,65 +0,0 @@
import java.io.IOException;
import java.util.*;
public class TestPendu {
public static void main(String[] args) {
try {
Scanner scanner = new Scanner(System.in);
GestionMotsPendu gestion = new GestionMotsPendu();
System.out.println("Bienvenue dans le jeu du pendu !");
System.out.println("Choisissez la difficulté : 1 = Facile, 2 = Moyen, 3 = Difficile");
int difficulte = scanner.nextInt();
scanner.nextLine(); // consommer la fin de ligne
String mot = gestion.getMotAleatoire(difficulte);
if (mot == null) {
System.out.println("Erreur : aucun mot disponible pour cette difficulté.");
return;
}
char[] motCache = new char[mot.length()];
Arrays.fill(motCache, '_');
Set<Character> lettresDevinees = new HashSet<>();
int erreurs = 0;
int maxErreurs = 6;
while (erreurs < maxErreurs && new String(motCache).contains("_")) {
System.out.println("\nMot : " + new String(motCache));
System.out.println("Erreurs : " + erreurs + "/" + maxErreurs);
System.out.print("Devinez une lettre : ");
String input = scanner.nextLine().toLowerCase();
if (input.isEmpty()) continue;
char lettre = input.charAt(0);
if (lettresDevinees.contains(lettre)) {
System.out.println("Vous avez déjà essayé cette lettre !");
continue;
}
lettresDevinees.add(lettre);
if (mot.indexOf(lettre) >= 0) {
for (int i = 0; i < mot.length(); i++) {
if (mot.charAt(i) == lettre) motCache[i] = lettre;
}
System.out.println("Bien joué !");
} else {
erreurs++;
System.out.println("Raté !");
}
}
if (new String(motCache).equals(mot)) {
System.out.println("\nFélicitations ! Vous avez trouvé le mot : " + mot);
} else {
System.out.println("\nVous avez perdu ! Le mot était : " + mot);
}
scanner.close();
} catch (IOException e) {
System.err.println("Erreur lors du chargement des mots : " + e.getMessage());
}
}
}

57
src/WordManager.java Normal file
View File

@@ -0,0 +1,57 @@
import java.io.*;
import java.util.*;
public class WordManager {
// --- Constant: path to word file ---
private static final String WORD_FILE = "../res/hangman_words.txt";
// --- Map to store words by difficulty ---
private final Map<String, List<String>> wordsByDifficulty = new HashMap<>();
// --- Constructor ---
public WordManager() throws IOException {
wordsByDifficulty.put("EASY", new ArrayList<>());
wordsByDifficulty.put("MEDIUM", new ArrayList<>());
wordsByDifficulty.put("HARD", new ArrayList<>());
loadWords(); // automatically load words when created
}
// --- Load words from the file ---
private void loadWords() throws IOException {
try (BufferedReader reader = new BufferedReader(new FileReader(WORD_FILE))) {
String line;
String section = "";
while ((line = reader.readLine()) != null) {
line = line.trim();
if (line.startsWith("#")) {
section = line.substring(1).toUpperCase(); // read difficulty section
} else if (!line.isEmpty() && wordsByDifficulty.containsKey(section)) {
wordsByDifficulty.get(section).add(line);
}
}
} catch (FileNotFoundException e) {
throw new IOException("File not found: " + WORD_FILE);
}
}
// --- Get a random word based on difficulty (1 = Easy, 2 = Medium, 3 = Hard) ---
public String getRandomWord(int difficulty) {
String key = difficultyToKey(difficulty);
List<String> list = wordsByDifficulty.get(key);
if (list == null || list.isEmpty()) return null;
Random rand = new Random();
return list.get(rand.nextInt(list.size()));
}
// --- Convert int to difficulty key ---
private String difficultyToKey(int difficulty) {
return switch (difficulty) {
case 1 -> "EASY";
case 2 -> "MEDIUM";
case 3 -> "HARD";
default -> "EASY"; // default difficulty
};
}
}