forked from menault/TD3_DEV51_Qualite_Algo
		
	Compare commits
	
		
			9 Commits
		
	
	
		
			6943bafd1d
			...
			gentil
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| dfa47463b1 | |||
| c3dc8f73ed | |||
| 3679e1a732 | |||
| 001cc1d32a | |||
| 3af3ed9e8a | |||
| d52b072c92 | |||
| 15061d6afd | |||
| baab5c7ce2 | |||
| 90645b7673 | 
							
								
								
									
										554
									
								
								res/hangman_words.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										554
									
								
								res/hangman_words.txt
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -2,39 +2,46 @@ import javax.swing.*;
 | 
				
			|||||||
import java.awt.*;
 | 
					import java.awt.*;
 | 
				
			||||||
import java.awt.event.*;
 | 
					import java.awt.event.*;
 | 
				
			||||||
import java.util.*;
 | 
					import java.util.*;
 | 
				
			||||||
 | 
					import java.util.Timer;
 | 
				
			||||||
 | 
					import java.util.TimerTask;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Hangman game GUI.
 | 
					 * Hangman GUI with difficulty selection, dynamic score, and timer.
 | 
				
			||||||
 * Variables/methods and comments in English.
 | 
					 * Uses WordManager for words.
 | 
				
			||||||
 * User-facing texts remain in French.
 | 
					 * User-facing texts remain in French.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
public class HangmanGUI extends JFrame {
 | 
					public class HangmanGUI extends JFrame {
 | 
				
			||||||
    private final String[] words = {
 | 
					    private WordManager manager;
 | 
				
			||||||
        "ordinateur","voiture","maison","soleil","lumiere",
 | 
					 | 
				
			||||||
        "fromage","chocolat","montagne","riviere","plage",
 | 
					 | 
				
			||||||
        "oiseau","papillon","musique","chateau","livre",
 | 
					 | 
				
			||||||
        "telephone","aventure","mystere","foret","fleur",
 | 
					 | 
				
			||||||
        "chapeau","nuage","horloge","chaise","fenetre",
 | 
					 | 
				
			||||||
        "paysage","bouteille","parapluie","clavier","souris",
 | 
					 | 
				
			||||||
        "brouillard","village","histoire","cerise","pomme",
 | 
					 | 
				
			||||||
        "banane","poisson","arbre","cascade","cheval"
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private String secretWord;
 | 
					    private String secretWord;
 | 
				
			||||||
    private final Set<Character> found = new HashSet<>();
 | 
					    private final Set<Character> found = new HashSet<>();
 | 
				
			||||||
    private final Set<Character> tried = new HashSet<>();
 | 
					    private final Set<Character> tried = new HashSet<>();
 | 
				
			||||||
    private int errors = 0;
 | 
					    private int errors = 0;
 | 
				
			||||||
    private static final int MAX_ERRORS = 8; // 8 steps: base, post, beam, rope, head, body, arms, legs
 | 
					    private static final int MAX_ERRORS = 8;
 | 
				
			||||||
    private boolean gameOver = false;        // indicates if the game is finished
 | 
					    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 wordLbl = new JLabel("", SwingConstants.CENTER);
 | 
				
			||||||
    private final JLabel triedLbl = 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 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 JTextField input = new JTextField();
 | 
				
			||||||
    private final JButton guessBtn = new JButton("Proposer");
 | 
					    private final JButton guessBtn = new JButton("Proposer");
 | 
				
			||||||
    private final HangPanel hangPanel = new HangPanel();
 | 
					    private final HangPanel hangPanel = new HangPanel();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /** Drawing panel for the hangman, progressive according to error count. */
 | 
					    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 static class HangPanel extends JPanel {
 | 
				
			||||||
        private int errors = 0;
 | 
					        private int errors = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -50,25 +57,18 @@ public class HangmanGUI extends JFrame {
 | 
				
			|||||||
            gg.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
 | 
					            gg.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            int w = getWidth(), h = getHeight();
 | 
					            int w = getWidth(), h = getHeight();
 | 
				
			||||||
            int baseY = h - 40; // ground level
 | 
					            int baseY = h - 40;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (errors >= 1) gg.drawLine(50, baseY, w - 50, baseY);
 | 
					            if (errors >= 1) gg.drawLine(50, baseY, w - 50, baseY);
 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (errors >= 2) gg.drawLine(100, baseY, 100, 60);
 | 
					            if (errors >= 2) gg.drawLine(100, baseY, 100, 60);
 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (errors >= 3) gg.drawLine(100, 60, 220, 60);
 | 
					            if (errors >= 3) gg.drawLine(100, 60, 220, 60);
 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (errors >= 4) gg.drawLine(220, 60, 220, 90);
 | 
					            if (errors >= 4) gg.drawLine(220, 60, 220, 90);
 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (errors >= 5) gg.drawOval(200, 90, 40, 40);
 | 
					            if (errors >= 5) gg.drawOval(200, 90, 40, 40);
 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (errors >= 6) gg.drawLine(220, 130, 220, 200);
 | 
					            if (errors >= 6) gg.drawLine(220, 130, 220, 200);
 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (errors >= 7) {
 | 
					            if (errors >= 7) {
 | 
				
			||||||
                gg.drawLine(220, 145, 190, 165);
 | 
					                gg.drawLine(220, 145, 190, 165);
 | 
				
			||||||
                gg.drawLine(220, 145, 250, 165);
 | 
					                gg.drawLine(220, 145, 250, 165);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (errors >= 8) {
 | 
					            if (errors >= 8) {
 | 
				
			||||||
                gg.drawLine(220, 200, 200, 240);
 | 
					                gg.drawLine(220, 200, 200, 240);
 | 
				
			||||||
                gg.drawLine(220, 200, 240, 240);
 | 
					                gg.drawLine(220, 200, 240, 240);
 | 
				
			||||||
@@ -76,40 +76,63 @@ public class HangmanGUI extends JFrame {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /** Entry point: create and show the game window. */
 | 
					    /** Entry point */
 | 
				
			||||||
    public static void main(String[] args) {
 | 
					    public static void main(String[] args) {
 | 
				
			||||||
        SwingUtilities.invokeLater(() -> {
 | 
					        SwingUtilities.invokeLater(() -> {
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
                HangmanGUI app = new HangmanGUI();
 | 
					                HangmanGUI app = new HangmanGUI();
 | 
				
			||||||
                app.setVisible(true);
 | 
					                app.setVisible(true);
 | 
				
			||||||
 | 
					            } catch (Exception e) {
 | 
				
			||||||
 | 
					                e.printStackTrace();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /** Constructor: window setup, UI setup, and start the game. */
 | 
					    /** Constructor */
 | 
				
			||||||
    public HangmanGUI() {
 | 
					    public HangmanGUI() throws Exception {
 | 
				
			||||||
        super("Jeu du Pendu");
 | 
					        super("Jeu du Pendu");
 | 
				
			||||||
 | 
					        manager = new WordManager();
 | 
				
			||||||
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
 | 
					        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
 | 
				
			||||||
        setSize(520, 520);
 | 
					        setSize(560, 620);
 | 
				
			||||||
        setLocationRelativeTo(null);
 | 
					        setLocationRelativeTo(null);
 | 
				
			||||||
        setupUI();
 | 
					        setupUI();
 | 
				
			||||||
        startGame();
 | 
					        startGame();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /** Prepare the layout and interactions. */
 | 
					    /** Setup UI */
 | 
				
			||||||
    private void setupUI() {
 | 
					    private void setupUI() {
 | 
				
			||||||
        wordLbl.setFont(new Font(Font.MONOSPACED, Font.BOLD, 28));
 | 
					        wordLbl.setFont(new Font(Font.MONOSPACED, Font.BOLD, 28));
 | 
				
			||||||
        triedLbl.setFont(new Font("SansSerif", Font.PLAIN, 14));
 | 
					        triedLbl.setFont(new Font("SansSerif", Font.PLAIN, 14));
 | 
				
			||||||
        infoLbl.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(3, 1, 8, 8));
 | 
					        JPanel top = new JPanel(new GridLayout(6, 1, 8, 8));
 | 
				
			||||||
        top.add(wordLbl);
 | 
					        top.add(wordLbl);
 | 
				
			||||||
        top.add(triedLbl);
 | 
					        top.add(triedLbl);
 | 
				
			||||||
        top.add(infoLbl);
 | 
					        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));
 | 
					        JPanel controls = new JPanel(new BorderLayout(8, 8));
 | 
				
			||||||
        controls.add(input, BorderLayout.CENTER);
 | 
					        controls.add(input, BorderLayout.CENTER);
 | 
				
			||||||
        controls.add(guessBtn, BorderLayout.EAST);
 | 
					        controls.add(guessBtn, BorderLayout.EAST);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        hangPanel.setPreferredSize(new Dimension(480, 300));
 | 
					        hangPanel.setPreferredSize(new Dimension(500, 300));
 | 
				
			||||||
        JPanel center = new JPanel(new BorderLayout());
 | 
					        JPanel center = new JPanel(new BorderLayout());
 | 
				
			||||||
        center.add(hangPanel, BorderLayout.CENTER);
 | 
					        center.add(hangPanel, BorderLayout.CENTER);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -128,24 +151,40 @@ public class HangmanGUI extends JFrame {
 | 
				
			|||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /** Start a  game. */
 | 
					    /** Start new game */
 | 
				
			||||||
    private void startGame() {
 | 
					    private void startGame() {
 | 
				
			||||||
        secretWord = pickWord();
 | 
					        int diffIndex = difficultyCombo.getSelectedIndex(); // 0=Facile,1=Moyen,2=Difficile
 | 
				
			||||||
 | 
					        int diffValue = diffIndex + 1;
 | 
				
			||||||
 | 
					        secretWord = manager.getRandomWord(diffValue).toLowerCase(Locale.ROOT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        found.clear();
 | 
					        found.clear();
 | 
				
			||||||
        tried.clear();
 | 
					        tried.clear();
 | 
				
			||||||
        errors = 0;
 | 
					        errors = 0;
 | 
				
			||||||
        gameOver = false;
 | 
					        gameOver = false;
 | 
				
			||||||
 | 
					        startTime = System.currentTimeMillis();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        input.setText("");
 | 
					        input.setText("");
 | 
				
			||||||
        input.setEditable(true);
 | 
					        input.setEditable(true);
 | 
				
			||||||
        guessBtn.setEnabled(true);
 | 
					        guessBtn.setEnabled(true);
 | 
				
			||||||
        infoLbl.setText("Entrez une lettre (a-z)");
 | 
					        infoLbl.setText("Entrez une lettre (a-z)");
 | 
				
			||||||
        updateUIState();
 | 
					        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 a guess: validate input, update state, check for end of game. */
 | 
					    /** Handle guess */
 | 
				
			||||||
    private void onGuess() {
 | 
					    private void onGuess() {
 | 
				
			||||||
        if (gameOver) return; // block input after game end
 | 
					        if (gameOver) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        String s = input.getText().trim().toLowerCase(Locale.ROOT);
 | 
					        String s = input.getText().trim().toLowerCase(Locale.ROOT);
 | 
				
			||||||
        if (s.length() != 1 || s.charAt(0) < 'a' || s.charAt(0) > 'z') {
 | 
					        if (s.length() != 1 || s.charAt(0) < 'a' || s.charAt(0) > 'z') {
 | 
				
			||||||
@@ -165,7 +204,7 @@ public class HangmanGUI extends JFrame {
 | 
				
			|||||||
        tried.add(c);
 | 
					        tried.add(c);
 | 
				
			||||||
        boolean hit = false;
 | 
					        boolean hit = false;
 | 
				
			||||||
        for (int i = 0; i < secretWord.length(); i++) {
 | 
					        for (int i = 0; i < secretWord.length(); i++) {
 | 
				
			||||||
            if (Character.toLowerCase(secretWord.charAt(i)) == c) {
 | 
					            if (secretWord.charAt(i) == c) {
 | 
				
			||||||
                found.add(c);
 | 
					                found.add(c);
 | 
				
			||||||
                hit = true;
 | 
					                hit = true;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -182,15 +221,17 @@ public class HangmanGUI extends JFrame {
 | 
				
			|||||||
        input.requestFocusInWindow();
 | 
					        input.requestFocusInWindow();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /** Refresh labels/drawing and handle end-of-game. */
 | 
					    /** Update UI */
 | 
				
			||||||
    private void updateUIState() {
 | 
					    private void updateUIState() {
 | 
				
			||||||
        wordLbl.setText(maskWord(secretWord, found));
 | 
					        wordLbl.setText(maskWord(secretWord, found));
 | 
				
			||||||
        triedLbl.setText("Lettres essayées : " + joinChars(tried));
 | 
					        triedLbl.setText("Lettres essayées : " + joinChars(tried));
 | 
				
			||||||
        hangPanel.setErrors(errors);
 | 
					        hangPanel.setErrors(errors);
 | 
				
			||||||
 | 
					        updateScoreLabel();
 | 
				
			||||||
 | 
					        updateTimerLabel();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (isWin(secretWord, found)) {
 | 
					        if (isWin(secretWord, found)) {
 | 
				
			||||||
            infoLbl.setText("Bravo ! Vous avez trouvé le mot : " + secretWord);
 | 
					            infoLbl.setText("Bravo ! Vous avez trouvé le mot : " + secretWord);
 | 
				
			||||||
            wordLbl.setText(spaced(secretWord)); // pretty display of the word
 | 
					            wordLbl.setText(spaced(secretWord));
 | 
				
			||||||
            gameOver = true;
 | 
					            gameOver = true;
 | 
				
			||||||
            disableInput();
 | 
					            disableInput();
 | 
				
			||||||
        } else if (errors >= MAX_ERRORS) {
 | 
					        } else if (errors >= MAX_ERRORS) {
 | 
				
			||||||
@@ -199,25 +240,30 @@ public class HangmanGUI extends JFrame {
 | 
				
			|||||||
            gameOver = true;
 | 
					            gameOver = true;
 | 
				
			||||||
            disableInput();
 | 
					            disableInput();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					 | 
				
			||||||
        // force UI refresh
 | 
					 | 
				
			||||||
        revalidate();
 | 
					 | 
				
			||||||
        repaint();
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /** Disable controls after the game ends. */
 | 
					    /** 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() {
 | 
					    private void disableInput() {
 | 
				
			||||||
        input.setEditable(false);
 | 
					        input.setEditable(false);
 | 
				
			||||||
        guessBtn.setEnabled(false);
 | 
					        guessBtn.setEnabled(false);
 | 
				
			||||||
 | 
					        if (timer != null) timer.cancel();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /** Pick a random word. */
 | 
					 | 
				
			||||||
    private String pickWord() {
 | 
					 | 
				
			||||||
        Random rnd = new Random();
 | 
					 | 
				
			||||||
        return words[rnd.nextInt(words.length)].toLowerCase(Locale.ROOT);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /** Build the masked word based on found letters. */
 | 
					 | 
				
			||||||
    private String maskWord(String secret, Set<Character> foundSet) {
 | 
					    private String maskWord(String secret, Set<Character> foundSet) {
 | 
				
			||||||
        StringBuilder sb = new StringBuilder();
 | 
					        StringBuilder sb = new StringBuilder();
 | 
				
			||||||
        for (int i = 0; i < secret.length(); i++) {
 | 
					        for (int i = 0; i < secret.length(); i++) {
 | 
				
			||||||
@@ -230,7 +276,6 @@ public class HangmanGUI extends JFrame {
 | 
				
			|||||||
        return sb.toString();
 | 
					        return sb.toString();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /** True if all letters have been found. */
 | 
					 | 
				
			||||||
    private boolean isWin(String secret, Set<Character> foundSet) {
 | 
					    private boolean isWin(String secret, Set<Character> foundSet) {
 | 
				
			||||||
        for (int i = 0; i < secret.length(); i++) {
 | 
					        for (int i = 0; i < secret.length(); i++) {
 | 
				
			||||||
            char lc = Character.toLowerCase(secret.charAt(i));
 | 
					            char lc = Character.toLowerCase(secret.charAt(i));
 | 
				
			||||||
@@ -239,7 +284,6 @@ public class HangmanGUI extends JFrame {
 | 
				
			|||||||
        return true;
 | 
					        return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /** Sort and join letters for display. */
 | 
					 | 
				
			||||||
    private String joinChars(Set<Character> set) {
 | 
					    private String joinChars(Set<Character> set) {
 | 
				
			||||||
        java.util.List<Character> list = new ArrayList<>(set);
 | 
					        java.util.List<Character> list = new ArrayList<>(set);
 | 
				
			||||||
        Collections.sort(list);
 | 
					        Collections.sort(list);
 | 
				
			||||||
@@ -251,7 +295,6 @@ public class HangmanGUI extends JFrame {
 | 
				
			|||||||
        return sb.toString();
 | 
					        return sb.toString();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /** Add spaces between letters for nicer reading. */
 | 
					 | 
				
			||||||
    private String spaced(String s) {
 | 
					    private String spaced(String s) {
 | 
				
			||||||
        StringBuilder sb = new StringBuilder();
 | 
					        StringBuilder sb = new StringBuilder();
 | 
				
			||||||
        for (int i = 0; i < s.length(); i++) {
 | 
					        for (int i = 0; i < s.length(); i++) {
 | 
				
			||||||
							
								
								
									
										57
									
								
								src/WordManager.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								src/WordManager.java
									
									
									
									
									
										Normal 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
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user