forked from menault/TD3_DEV51_Qualite_Algo
Compare commits
3 Commits
7d2a0a12f9
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 94da5d2099 | |||
| 4f38105062 | |||
| 92aa82e7c7 |
4
Makefile
4
Makefile
@@ -1,6 +1,7 @@
|
|||||||
# === Configuration ===
|
# === Configuration ===
|
||||||
SRC_DIR = src
|
SRC_DIR = src
|
||||||
OUT_DIR = out
|
OUT_DIR = out
|
||||||
|
Dictionary = fr/iut/Projet/Dictionary
|
||||||
PACKAGE = fr/iut/Projet
|
PACKAGE = fr/iut/Projet
|
||||||
MAIN_CLASS = fr.iut.Projet.Display
|
MAIN_CLASS = fr.iut.Projet.Display
|
||||||
|
|
||||||
@@ -14,7 +15,8 @@ compile:
|
|||||||
# Compilation de tous les fichiers Java du package
|
# Compilation de tous les fichiers Java du package
|
||||||
@javac -d $(OUT_DIR) $(SRC_DIR)/$(PACKAGE)/*.java
|
@javac -d $(OUT_DIR) $(SRC_DIR)/$(PACKAGE)/*.java
|
||||||
# Copier Word.txt dans le dossier de sortie
|
# Copier Word.txt dans le dossier de sortie
|
||||||
@cp $(SRC_DIR)/$(PACKAGE)/Word.txt $(OUT_DIR)/$(PACKAGE)/
|
@mkdir -p $(OUT_DIR)/$(Dictionary)
|
||||||
|
@cp $(SRC_DIR)/$(Dictionary)/*.txt $(OUT_DIR)/$(Dictionary)/
|
||||||
@echo "Compilation terminée."
|
@echo "Compilation terminée."
|
||||||
|
|
||||||
# === Exécution ===
|
# === Exécution ===
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
10194
out/fr/iut/Projet/Dictionary/EASY-FRENCH.txt
Normal file
10194
out/fr/iut/Projet/Dictionary/EASY-FRENCH.txt
Normal file
File diff suppressed because it is too large
Load Diff
999
out/fr/iut/Projet/Dictionary/HARD-FRENCH.txt
Normal file
999
out/fr/iut/Projet/Dictionary/HARD-FRENCH.txt
Normal file
File diff suppressed because it is too large
Load Diff
11090
out/fr/iut/Projet/Dictionary/MEDIUM-FRENCH.txt
Normal file
11090
out/fr/iut/Projet/Dictionary/MEDIUM-FRENCH.txt
Normal file
File diff suppressed because it is too large
Load Diff
Binary file not shown.
10194
out/fr/iut/Projet/EASY-FRENCH.txt
Normal file
10194
out/fr/iut/Projet/EASY-FRENCH.txt
Normal file
File diff suppressed because it is too large
Load Diff
BIN
out/fr/iut/Projet/GameTimer$1.class
Normal file
BIN
out/fr/iut/Projet/GameTimer$1.class
Normal file
Binary file not shown.
BIN
out/fr/iut/Projet/GameTimer.class
Normal file
BIN
out/fr/iut/Projet/GameTimer.class
Normal file
Binary file not shown.
999
out/fr/iut/Projet/HARD-FRENCH.txt
Normal file
999
out/fr/iut/Projet/HARD-FRENCH.txt
Normal file
File diff suppressed because it is too large
Load Diff
11090
out/fr/iut/Projet/MEDIUM-FRENCH.txt
Normal file
11090
out/fr/iut/Projet/MEDIUM-FRENCH.txt
Normal file
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -5,91 +5,141 @@ import java.awt.*;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Classe principale qui gère l'interface graphique du jeu du pendu.
|
* Classe principale qui gère l'interface graphique du jeu du pendu.
|
||||||
* <p>
|
*
|
||||||
* Cette classe crée la fenêtre du jeu, affiche le mot caché, les lettres incorrectes,
|
* Cette classe crée la fenêtre du jeu et affiche :
|
||||||
* le dessin du pendu (via {@link Affiche}), et permet à l'utilisateur de saisir des lettres.
|
* - le mot caché avec les lettres devinées,
|
||||||
* Elle gère également la logique de mise à jour et la fin de partie.
|
* - les lettres incorrectes,
|
||||||
* </p>
|
* - le dessin du pendu (via {@link Affiche}),
|
||||||
*
|
* - le timer affiché en haut à droite (via {@link GameTimer}),
|
||||||
* @author
|
* et permet à l'utilisateur de saisir des lettres.
|
||||||
* @version 1.0
|
* Elle gère également :
|
||||||
|
* - la logique de mise à jour de l'interface,
|
||||||
|
* - la fin de partie,
|
||||||
|
* - le redémarrage,
|
||||||
|
* - et le changement de difficulté en utilisant {@link PlayButtonListener}.
|
||||||
*/
|
*/
|
||||||
public class Action {
|
public class Action {
|
||||||
|
|
||||||
/** Fenêtre principale du jeu. */
|
/** Fenêtre principale du jeu */
|
||||||
private JFrame gameFrame;
|
private JFrame gameFrame;
|
||||||
|
|
||||||
/** Label affichant le mot caché avec les lettres découvertes. */
|
/** Label affichant le mot caché avec les lettres découvertes */
|
||||||
private JLabel wordLabel;
|
private JLabel wordLabel;
|
||||||
|
|
||||||
/** Label affichant la liste des lettres incorrectes. */
|
/** Label affichant les lettres incorrectes devinées par le joueur */
|
||||||
private JLabel incorrectLettersLabel;
|
private JLabel incorrectLettersLabel;
|
||||||
|
|
||||||
/** Champ de texte permettant à l'utilisateur d'entrer une lettre. */
|
/** Champ de texte pour saisir une lettre */
|
||||||
private JTextField letterInputField;
|
private JTextField letterInputField;
|
||||||
|
|
||||||
/** Instance du jeu, contenant la logique (mot, vies, lettres, etc.). */
|
/** Instance de la logique du jeu (mot secret, lettres, vies, etc.) */
|
||||||
private Random_word game;
|
private Random_word game;
|
||||||
|
|
||||||
/** Composant graphique qui affiche le dessin du pendu. */
|
/** Composant graphique représentant le pendu */
|
||||||
private Affiche affiche;
|
private Affiche affiche;
|
||||||
|
|
||||||
|
/** Timer qui compte le temps écoulé depuis le début du mot */
|
||||||
|
private GameTimer gameTimer;
|
||||||
|
|
||||||
|
/** Niveau de difficulté courant ("facile", "moyen", "difficile", "hell") */
|
||||||
|
private String difficulty;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructeur de la classe {@code Action}.
|
* Constructeur : initialise le jeu avec la difficulté choisie,
|
||||||
* <p>
|
* crée les composants graphiques et démarre le timer.
|
||||||
* Initialise le jeu, crée les composants graphiques, met en place la mise en page
|
*
|
||||||
* et affiche la fenêtre du jeu.
|
* @param difficulty Niveau de difficulté pour le mot à deviner
|
||||||
* </p>
|
|
||||||
*/
|
*/
|
||||||
public Action() {
|
public Action(String difficulty) {
|
||||||
game = new Random_word();
|
this.difficulty = difficulty;
|
||||||
|
|
||||||
|
// Création du jeu avec le mot choisi selon la difficulté
|
||||||
|
game = new Random_word(difficulty);
|
||||||
|
|
||||||
|
// Initialisation des composants graphiques
|
||||||
initializeComponents();
|
initializeComponents();
|
||||||
layoutComponents();
|
layoutComponents();
|
||||||
|
|
||||||
|
// Gestion de la saisie utilisateur
|
||||||
letterInputField.addActionListener(e -> handleGuess());
|
letterInputField.addActionListener(e -> handleGuess());
|
||||||
|
|
||||||
|
// Démarre le timer dès l'ouverture de la partie
|
||||||
|
gameTimer.start();
|
||||||
|
|
||||||
|
// Affiche la fenêtre du jeu
|
||||||
gameFrame.setVisible(true);
|
gameFrame.setVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==================== Initialisation ====================
|
// ==================== Initialisation des composants ====================
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialise tous les composants graphiques (labels, champs, boutons...).
|
* Initialise tous les composants graphiques du jeu :
|
||||||
|
* - fenêtre principale
|
||||||
|
* - dessin du pendu
|
||||||
|
* - labels pour le mot et les lettres incorrectes
|
||||||
|
* - champ de saisie
|
||||||
|
* - timer
|
||||||
*/
|
*/
|
||||||
private void initializeComponents() {
|
private void initializeComponents() {
|
||||||
gameFrame = new JFrame("Hanging Man");
|
gameFrame = new JFrame("Hanging Man - " + difficulty);
|
||||||
gameFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
gameFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
gameFrame.setSize(700, 500);
|
gameFrame.setSize(700, 500);
|
||||||
|
|
||||||
|
// Composant graphique pour dessiner le pendu
|
||||||
affiche = new Affiche();
|
affiche = new Affiche();
|
||||||
affiche.setPreferredSize(new Dimension(350, 400));
|
affiche.setPreferredSize(new Dimension(350, 400));
|
||||||
affiche.setBackground(Color.WHITE);
|
affiche.setBackground(Color.WHITE);
|
||||||
affiche.setOpaque(true);
|
affiche.setOpaque(true);
|
||||||
|
|
||||||
|
// Label affichant le mot caché
|
||||||
wordLabel = new JLabel(game.getHiddenWord());
|
wordLabel = new JLabel(game.getHiddenWord());
|
||||||
wordLabel.setFont(new Font("Arial", Font.BOLD, 32));
|
wordLabel.setFont(new Font("Arial", Font.BOLD, 32));
|
||||||
wordLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
wordLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
||||||
|
|
||||||
|
// Label affichant les lettres incorrectes
|
||||||
incorrectLettersLabel = new JLabel("Incorrect letters: " + game.getIncorrectLetters());
|
incorrectLettersLabel = new JLabel("Incorrect letters: " + game.getIncorrectLetters());
|
||||||
incorrectLettersLabel.setFont(new Font("Arial", Font.PLAIN, 20));
|
incorrectLettersLabel.setFont(new Font("Arial", Font.PLAIN, 20));
|
||||||
incorrectLettersLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
incorrectLettersLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
||||||
|
|
||||||
|
// Champ pour saisir une lettre
|
||||||
letterInputField = new JTextField(3);
|
letterInputField = new JTextField(3);
|
||||||
letterInputField.setFont(new Font("Arial", Font.PLAIN, 24));
|
letterInputField.setFont(new Font("Arial", Font.PLAIN, 24));
|
||||||
|
|
||||||
|
// Création du timer
|
||||||
|
gameTimer = new GameTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==================== Mise en page ====================
|
// ==================== Mise en page ====================
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dispose les composants graphiques dans la fenêtre selon un {@link BorderLayout}.
|
* Crée la mise en page principale avec un BorderLayout :
|
||||||
|
* - panneau gauche : dessin du pendu
|
||||||
|
* - panneau droit : mot, lettres incorrectes, champ de saisie, boutons et timer
|
||||||
*/
|
*/
|
||||||
private void layoutComponents() {
|
private void layoutComponents() {
|
||||||
JPanel mainPanel = new JPanel(new BorderLayout());
|
JPanel mainPanel = new JPanel(new BorderLayout());
|
||||||
|
mainPanel.add(createLeftPanel(), BorderLayout.WEST);
|
||||||
|
mainPanel.add(createRightPanel(), BorderLayout.CENTER);
|
||||||
|
gameFrame.add(mainPanel);
|
||||||
|
}
|
||||||
|
|
||||||
// --- panneau gauche : dessin du pendu ---
|
/** Crée le panneau gauche avec le dessin du pendu */
|
||||||
|
private JPanel createLeftPanel() {
|
||||||
JPanel leftPanel = new JPanel(new BorderLayout());
|
JPanel leftPanel = new JPanel(new BorderLayout());
|
||||||
leftPanel.add(affiche, BorderLayout.CENTER);
|
leftPanel.add(affiche, BorderLayout.CENTER);
|
||||||
mainPanel.add(leftPanel, BorderLayout.WEST);
|
return leftPanel;
|
||||||
|
}
|
||||||
|
|
||||||
// --- panneau droit : interface du jeu ---
|
/**
|
||||||
|
* Crée le panneau droit avec tous les éléments :
|
||||||
|
* - mot caché
|
||||||
|
* - lettres incorrectes
|
||||||
|
* - champ de saisie
|
||||||
|
* - bouton restart
|
||||||
|
* - bouton changement de difficulté
|
||||||
|
* - timer en haut à droite
|
||||||
|
*/
|
||||||
|
private JPanel createRightPanel() {
|
||||||
JPanel rightPanel = new JPanel(new GridBagLayout());
|
JPanel rightPanel = new JPanel(new GridBagLayout());
|
||||||
GridBagConstraints gbc = new GridBagConstraints();
|
GridBagConstraints gbc = new GridBagConstraints();
|
||||||
gbc.gridx = 0;
|
gbc.gridx = 0;
|
||||||
@@ -112,24 +162,34 @@ public class Action {
|
|||||||
inputRow.add(letterInputField);
|
inputRow.add(letterInputField);
|
||||||
rightPanel.add(inputRow, gbc);
|
rightPanel.add(inputRow, gbc);
|
||||||
|
|
||||||
// Bouton de redémarrage
|
// Bouton restart
|
||||||
gbc.gridy = 3;
|
gbc.gridy = 3;
|
||||||
JButton restartButton = new JButton("Restart");
|
JButton restartButton = new JButton("Restart");
|
||||||
restartButton.addActionListener(new PlayButtonListener(gameFrame));
|
restartButton.addActionListener(e -> restartGame());
|
||||||
rightPanel.add(restartButton, gbc);
|
rightPanel.add(restartButton, gbc);
|
||||||
|
|
||||||
mainPanel.add(rightPanel, BorderLayout.CENTER);
|
// Bouton changement de difficulté
|
||||||
gameFrame.add(mainPanel);
|
gbc.gridy = 4;
|
||||||
|
JButton changeDifficultyButton = new JButton("Changer la difficulté");
|
||||||
|
changeDifficultyButton.addActionListener(e -> showDifficultyDialog());
|
||||||
|
rightPanel.add(changeDifficultyButton, gbc);
|
||||||
|
|
||||||
|
// Timer en haut à droite
|
||||||
|
gbc.gridy = 5;
|
||||||
|
gbc.anchor = GridBagConstraints.NORTHEAST;
|
||||||
|
rightPanel.add(gameTimer.getTimerLabel(), gbc);
|
||||||
|
|
||||||
|
return rightPanel;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==================== Gestion du jeu ====================
|
// ==================== Gestion des actions ====================
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gère la saisie d'une lettre par le joueur.
|
* Traite la saisie d'une lettre par le joueur :
|
||||||
* <p>
|
* - vérifie la validité
|
||||||
* Vérifie la validité de la lettre, met à jour le jeu, l'affichage
|
* - met à jour le mot caché et lettres incorrectes
|
||||||
* et teste si la partie est terminée.
|
* - met à jour le pendu
|
||||||
* </p>
|
* - termine la partie si nécessaire
|
||||||
*/
|
*/
|
||||||
private void handleGuess() {
|
private void handleGuess() {
|
||||||
String inputText = letterInputField.getText();
|
String inputText = letterInputField.getText();
|
||||||
@@ -145,12 +205,7 @@ public class Action {
|
|||||||
if (game.isGameOver()) endGame(message);
|
if (game.isGameOver()) endGame(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Vérifie que le texte saisi est une seule lettre */
|
||||||
* Vérifie que la saisie de l'utilisateur est une seule lettre valide.
|
|
||||||
*
|
|
||||||
* @param inputText texte saisi dans le champ de saisie
|
|
||||||
* @return {@code true} si la saisie est valide, {@code false} sinon
|
|
||||||
*/
|
|
||||||
private boolean isValidInput(String inputText) {
|
private boolean isValidInput(String inputText) {
|
||||||
if (inputText.length() != 1 || !Character.isLetter(inputText.charAt(0))) {
|
if (inputText.length() != 1 || !Character.isLetter(inputText.charAt(0))) {
|
||||||
JOptionPane.showMessageDialog(gameFrame, "Please enter a single letter!");
|
JOptionPane.showMessageDialog(gameFrame, "Please enter a single letter!");
|
||||||
@@ -159,14 +214,7 @@ public class Action {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Met à jour les labels et le dessin du pendu */
|
||||||
* Met à jour les éléments de l'interface graphique :
|
|
||||||
* <ul>
|
|
||||||
* <li>le mot affiché,</li>
|
|
||||||
* <li>les lettres incorrectes,</li>
|
|
||||||
* <li>et le dessin du pendu selon les vies restantes.</li>
|
|
||||||
* </ul>
|
|
||||||
*/
|
|
||||||
private void updateUI() {
|
private void updateUI() {
|
||||||
wordLabel.setText(game.getHiddenWord());
|
wordLabel.setText(game.getHiddenWord());
|
||||||
incorrectLettersLabel.setText("Incorrect letters: " + game.getIncorrectLetters());
|
incorrectLettersLabel.setText("Incorrect letters: " + game.getIncorrectLetters());
|
||||||
@@ -174,12 +222,15 @@ public class Action {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Termine la partie en affichant un message selon le résultat (victoire ou défaite)
|
* Termine la partie :
|
||||||
* et empêche de nouvelles saisies.
|
* - arrête le timer
|
||||||
*
|
* - met à jour le dessin du pendu en cas de victoire/défaite
|
||||||
* @param message message à afficher dans une boîte de dialogue
|
* - affiche le message de fin
|
||||||
|
* - désactive le champ de saisie
|
||||||
*/
|
*/
|
||||||
private void endGame(String message) {
|
private void endGame(String message) {
|
||||||
|
gameTimer.stop();
|
||||||
|
|
||||||
if (game.isWon()) {
|
if (game.isWon()) {
|
||||||
affiche.setYouWin(true);
|
affiche.setYouWin(true);
|
||||||
} else {
|
} else {
|
||||||
@@ -189,4 +240,55 @@ public class Action {
|
|||||||
JOptionPane.showMessageDialog(gameFrame, message);
|
JOptionPane.showMessageDialog(gameFrame, message);
|
||||||
letterInputField.setEditable(false);
|
letterInputField.setEditable(false);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
/** Redémarre le jeu avec la même difficulté en utilisant PlayButtonListener */
|
||||||
|
private void restartGame() {
|
||||||
|
gameFrame.dispose();
|
||||||
|
JFrame tempFrame = new JFrame();
|
||||||
|
new PlayButtonListener(tempFrame, difficulty).actionPerformed(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Affiche une boîte de dialogue pour changer la difficulté,
|
||||||
|
* puis relance le jeu avec la nouvelle difficulté.
|
||||||
|
*/
|
||||||
|
private void showDifficultyDialog() {
|
||||||
|
String[] options = {"Facile", "Moyen", "Difficile", "Hell"};
|
||||||
|
|
||||||
|
int choice = JOptionPane.showOptionDialog(
|
||||||
|
gameFrame,
|
||||||
|
"Choisissez la difficulté :",
|
||||||
|
"Changer la difficulté",
|
||||||
|
JOptionPane.DEFAULT_OPTION,
|
||||||
|
JOptionPane.QUESTION_MESSAGE,
|
||||||
|
null,
|
||||||
|
options,
|
||||||
|
options[0]
|
||||||
|
);
|
||||||
|
|
||||||
|
if (choice >= 0) {
|
||||||
|
String newDifficulty;
|
||||||
|
switch (choice) {
|
||||||
|
case 0:
|
||||||
|
newDifficulty = "facile";
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
newDifficulty = "moyen";
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
newDifficulty = "difficile";
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
newDifficulty = "hell";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
newDifficulty = "moyen";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
gameFrame.dispose();
|
||||||
|
JFrame tempFrame = new JFrame();
|
||||||
|
new PlayButtonListener(tempFrame, newDifficulty).actionPerformed(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
10194
src/fr/iut/Projet/Dictionary/EASY-FRENCH.txt
Normal file
10194
src/fr/iut/Projet/Dictionary/EASY-FRENCH.txt
Normal file
File diff suppressed because it is too large
Load Diff
999
src/fr/iut/Projet/Dictionary/HARD-FRENCH.txt
Normal file
999
src/fr/iut/Projet/Dictionary/HARD-FRENCH.txt
Normal file
File diff suppressed because it is too large
Load Diff
11090
src/fr/iut/Projet/Dictionary/MEDIUM-FRENCH.txt
Normal file
11090
src/fr/iut/Projet/Dictionary/MEDIUM-FRENCH.txt
Normal file
File diff suppressed because it is too large
Load Diff
@@ -5,7 +5,7 @@ import java.awt.*;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Classe Display représentant le menu principal du jeu "Hanging Man".
|
* Classe Display représentant le menu principal du jeu "Hanging Man".
|
||||||
* Elle affiche le titre et le bouton Play.
|
* Elle affiche le titre et trois boutons de difficulté : Facile, Moyen et Difficile.
|
||||||
*/
|
*/
|
||||||
public class Display {
|
public class Display {
|
||||||
|
|
||||||
@@ -25,24 +25,41 @@ public class Display {
|
|||||||
text.setAlignmentX(Component.CENTER_ALIGNMENT);
|
text.setAlignmentX(Component.CENTER_ALIGNMENT);
|
||||||
text.setFont(new Font("Arial", Font.BOLD, 70));
|
text.setFont(new Font("Arial", Font.BOLD, 70));
|
||||||
|
|
||||||
// Bouton Play
|
// Création des boutons de difficulté
|
||||||
JButton play = new JButton("Play");
|
JButton easyButton = new JButton("Facile");
|
||||||
play.setAlignmentX(Component.CENTER_ALIGNMENT);
|
JButton mediumButton = new JButton("Moyen");
|
||||||
play.setPreferredSize(new Dimension(300, 100));
|
JButton hardButton = new JButton("Difficile");
|
||||||
play.setMaximumSize(new Dimension(300, 150));
|
JButton hellButton = new JButton("Hell");
|
||||||
play.setFont(new Font("Arial", Font.PLAIN, 36));
|
|
||||||
|
|
||||||
// Listener séparé pour gérer le clic sur Play
|
// Mise en forme des boutons
|
||||||
play.addActionListener(new PlayButtonListener(frame));
|
JButton[] buttons = { easyButton, mediumButton, hardButton, hellButton};
|
||||||
|
for (JButton button : buttons) {
|
||||||
|
button.setAlignmentX(Component.CENTER_ALIGNMENT);
|
||||||
|
button.setPreferredSize(new Dimension(300, 100));
|
||||||
|
button.setMaximumSize(new Dimension(300, 150));
|
||||||
|
button.setFont(new Font("Arial", Font.PLAIN, 36));
|
||||||
|
}
|
||||||
|
|
||||||
// Ajouter les composants avec de l'espace
|
// Ajout d'écouteurs (listeners)
|
||||||
|
easyButton.addActionListener(new PlayButtonListener(frame, "facile"));
|
||||||
|
mediumButton.addActionListener(new PlayButtonListener(frame, "moyen"));
|
||||||
|
hardButton.addActionListener(new PlayButtonListener(frame, "difficile"));
|
||||||
|
hellButton.addActionListener(new PlayButtonListener(frame, "hell"));
|
||||||
|
|
||||||
|
// Ajout des composants à la fenêtre
|
||||||
frame.add(Box.createVerticalGlue());
|
frame.add(Box.createVerticalGlue());
|
||||||
frame.add(text);
|
frame.add(text);
|
||||||
frame.add(Box.createVerticalStrut(30));
|
frame.add(Box.createVerticalStrut(50));
|
||||||
frame.add(play);
|
frame.add(easyButton);
|
||||||
|
frame.add(Box.createVerticalStrut(20));
|
||||||
|
frame.add(mediumButton);
|
||||||
|
frame.add(Box.createVerticalStrut(20));
|
||||||
|
frame.add(hardButton);
|
||||||
|
frame.add(Box.createVerticalStrut(20));
|
||||||
|
frame.add(hellButton);
|
||||||
frame.add(Box.createVerticalGlue());
|
frame.add(Box.createVerticalGlue());
|
||||||
|
|
||||||
// Affichage de la fenêtre
|
// Affichage de la fenêtre
|
||||||
frame.setVisible(true);
|
frame.setVisible(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
68
src/fr/iut/Projet/GameTimer.java
Normal file
68
src/fr/iut/Projet/GameTimer.java
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
package fr.iut.Projet;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Classe GameTimer qui gère le temps écoulé sur un mot.
|
||||||
|
*
|
||||||
|
* Affiche le temps en secondes dans un JLabel et peut être intégré
|
||||||
|
* à la fenêtre du jeu.
|
||||||
|
*/
|
||||||
|
public class GameTimer {
|
||||||
|
|
||||||
|
/** Label affichant le temps écoulé */
|
||||||
|
private JLabel timerLabel;
|
||||||
|
|
||||||
|
/** Timer Swing qui incrémente le temps chaque seconde */
|
||||||
|
private Timer timer;
|
||||||
|
|
||||||
|
/** Compteur de secondes écoulées */
|
||||||
|
private int secondsElapsed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructeur : crée le label et initialise le timer.
|
||||||
|
*/
|
||||||
|
public GameTimer() {
|
||||||
|
this.secondsElapsed = 0;
|
||||||
|
this.timerLabel = new JLabel("Temps : 0 s");
|
||||||
|
timerLabel.setHorizontalAlignment(SwingConstants.RIGHT);
|
||||||
|
|
||||||
|
// Timer qui déclenche l'action toutes les 1000ms (1 seconde)
|
||||||
|
this.timer = new Timer(1000, new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
secondsElapsed++;
|
||||||
|
timerLabel.setText("Temps : " + secondsElapsed + " s");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Démarre le timer */
|
||||||
|
public void start() {
|
||||||
|
secondsElapsed = 0;
|
||||||
|
timer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Arrête le timer */
|
||||||
|
public void stop() {
|
||||||
|
timer.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Remet le compteur à zéro */
|
||||||
|
public void reset() {
|
||||||
|
secondsElapsed = 0;
|
||||||
|
timerLabel.setText("Temps : 0 s");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return le JLabel contenant le temps écoulé */
|
||||||
|
public JLabel getTimerLabel() {
|
||||||
|
return timerLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return le temps écoulé en secondes */
|
||||||
|
public int getSecondsElapsed() {
|
||||||
|
return secondsElapsed;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,8 +5,8 @@ import java.awt.event.ActionEvent;
|
|||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Classe PlayButtonListener qui gère le clic sur le bouton "Play" du menu.
|
* Classe PlayButtonListener qui gère le clic sur les boutons de difficulté.
|
||||||
* Lorsqu'on clique sur le bouton, cette classe ouvre la fenêtre du jeu
|
* Lorsqu'on clique sur un bouton, elle ouvre la fenêtre du jeu avec le niveau choisi
|
||||||
* et ferme la fenêtre principale.
|
* et ferme la fenêtre principale.
|
||||||
*/
|
*/
|
||||||
public class PlayButtonListener implements ActionListener {
|
public class PlayButtonListener implements ActionListener {
|
||||||
@@ -14,22 +14,29 @@ public class PlayButtonListener implements ActionListener {
|
|||||||
/** Référence à la fenêtre principale du menu */
|
/** Référence à la fenêtre principale du menu */
|
||||||
private JFrame parentFrame;
|
private JFrame parentFrame;
|
||||||
|
|
||||||
|
/** Niveau de difficulté choisi */
|
||||||
|
private String difficulty;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructeur de PlayButtonListener.
|
* Constructeur de PlayButtonListener.
|
||||||
* @param frame La fenêtre principale à fermer après ouverture du jeu
|
* @param frame La fenêtre principale à fermer après ouverture du jeu
|
||||||
|
* @param difficulty Le niveau de difficulté choisi ("facile", "moyen" ou "difficile")
|
||||||
*/
|
*/
|
||||||
public PlayButtonListener(JFrame frame) {
|
public PlayButtonListener(JFrame frame, String difficulty) {
|
||||||
this.parentFrame = frame;
|
this.parentFrame = frame;
|
||||||
|
this.difficulty = difficulty;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Méthode appelée lorsque le bouton est cliqué.
|
* Méthode appelée lorsque le bouton est cliqué.
|
||||||
* Ouvre la fenêtre du jeu et ferme la fenêtre principale.
|
* Ouvre la fenêtre du jeu avec la difficulté sélectionnée
|
||||||
|
* et ferme la fenêtre principale.
|
||||||
* @param e L'événement déclenché par le clic
|
* @param e L'événement déclenché par le clic
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
new Action(); // Ouvre la fenêtre du jeu
|
// Passe la difficulté à la classe Action
|
||||||
parentFrame.dispose(); // Ferme la fenêtre principale
|
new Action(difficulty);
|
||||||
|
parentFrame.dispose(); // Ferme le menu principal
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,38 +3,105 @@ package fr.iut.Projet;
|
|||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Classe gérant la logique du jeu du pendu.
|
||||||
|
*
|
||||||
|
* Cette classe sélectionne un mot (ou une combinaison de mots) aléatoire
|
||||||
|
* selon la difficulté, conserve l'état du jeu (mot secret, lettres devinées,
|
||||||
|
* lettres incorrectes, nombre de vies) et fournit des méthodes pour deviner
|
||||||
|
* des lettres et vérifier l'état du jeu.
|
||||||
|
*/
|
||||||
public class Random_word {
|
public class Random_word {
|
||||||
|
|
||||||
|
/** Mot secret que le joueur doit deviner */
|
||||||
private String secretWord;
|
private String secretWord;
|
||||||
|
|
||||||
|
/** Tableau représentant le mot caché avec les lettres découvertes et espaces */
|
||||||
private char[] hiddenWord;
|
private char[] hiddenWord;
|
||||||
|
|
||||||
|
/** Lettres correctement devinées par le joueur */
|
||||||
private Set<Character> lettersGuessed;
|
private Set<Character> lettersGuessed;
|
||||||
|
|
||||||
|
/** Lettres incorrectes devinées par le joueur */
|
||||||
private Set<Character> incorrectLetters;
|
private Set<Character> incorrectLetters;
|
||||||
|
|
||||||
|
/** Nombre de vies restantes */
|
||||||
private int lives;
|
private int lives;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructeur : sélectionne un mot aléatoire et initialise le jeu.
|
* Constructeur : sélectionne un mot aléatoire selon la difficulté
|
||||||
|
* et initialise les structures du jeu.
|
||||||
|
*
|
||||||
|
* @param difficulty Niveau de difficulté ("facile", "moyen", "difficile", "hell")
|
||||||
|
* @throws RuntimeException si aucun mot n'a pu être choisi
|
||||||
*/
|
*/
|
||||||
public Random_word() {
|
public Random_word(String difficulty) {
|
||||||
this.secretWord = getRandomWord();
|
if (difficulty.equalsIgnoreCase("hell")) {
|
||||||
|
// En mode Hell, on choisit deux mots faciles et on les concatène avec un espace
|
||||||
|
String firstWord = getRandomWord("facile");
|
||||||
|
String secondWord = getRandomWord("facile");
|
||||||
|
|
||||||
|
if (firstWord == null || secondWord == null) {
|
||||||
|
throw new RuntimeException("Impossible de choisir deux mots pour le mode Hell !");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.secretWord = firstWord + " " + secondWord;
|
||||||
|
} else {
|
||||||
|
// Pour les autres difficultés, on choisit un seul mot correspondant
|
||||||
|
this.secretWord = getRandomWord(difficulty);
|
||||||
|
}
|
||||||
|
|
||||||
if (this.secretWord == null) {
|
if (this.secretWord == null) {
|
||||||
throw new RuntimeException("Impossible de choisir un mot aléatoire !");
|
throw new RuntimeException("Impossible de choisir un mot aléatoire !");
|
||||||
}
|
}
|
||||||
this.lives = 8;
|
|
||||||
|
this.lives = 8; // nombre de vies par défaut
|
||||||
this.hiddenWord = new char[secretWord.length()];
|
this.hiddenWord = new char[secretWord.length()];
|
||||||
Arrays.fill(this.hiddenWord, '_');
|
|
||||||
|
// Initialise le mot caché : underscore pour les lettres, espace conservé
|
||||||
|
for (int i = 0; i < secretWord.length(); i++) {
|
||||||
|
hiddenWord[i] = (secretWord.charAt(i) == ' ') ? ' ' : '_';
|
||||||
|
}
|
||||||
|
|
||||||
this.lettersGuessed = new HashSet<>();
|
this.lettersGuessed = new HashSet<>();
|
||||||
this.incorrectLetters = new HashSet<>();
|
this.incorrectLetters = new HashSet<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lit les mots dans "Word.txt" et retourne un mot aléatoire.
|
* Lit un fichier de mots correspondant à la difficulté et retourne un mot aléatoire.
|
||||||
|
*
|
||||||
|
* @param difficulty Niveau de difficulté
|
||||||
|
* @return mot aléatoire en minuscules
|
||||||
*/
|
*/
|
||||||
private String getRandomWord() {
|
private String getRandomWord(String difficulty) {
|
||||||
InputStream is = Random_word.class.getResourceAsStream("Word.txt");
|
String fileName;
|
||||||
if (is == null) return null;
|
|
||||||
|
// Sélection du fichier selon la difficulté
|
||||||
|
switch (difficulty.toLowerCase()) {
|
||||||
|
case "facile":
|
||||||
|
fileName = "/fr/iut/Projet/Dictionary/EASY-FRENCH.txt";
|
||||||
|
break;
|
||||||
|
case "moyen":
|
||||||
|
fileName = "/fr/iut/Projet/Dictionary/MEDIUM-FRENCH.txt";
|
||||||
|
break;
|
||||||
|
case "difficile":
|
||||||
|
fileName = "/fr/iut/Projet/Dictionary/HARD-FRENCH.txt";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
System.out.println("Difficulté inconnue, mode 'moyen' utilisé par défaut.");
|
||||||
|
fileName = "/fr/iut/Projet/Dictionary/MEDIUM-FRENCH.txt";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Récupère le fichier dans les ressources
|
||||||
|
InputStream is = Random_word.class.getResourceAsStream(fileName);
|
||||||
|
if (is == null) {
|
||||||
|
System.err.println("Fichier introuvable : " + fileName);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
String randomWord = null;
|
String randomWord = null;
|
||||||
Random random = new Random();
|
Random random = new Random();
|
||||||
|
|
||||||
try (BufferedReader br = new BufferedReader(new InputStreamReader(is))) {
|
try (BufferedReader br = new BufferedReader(new InputStreamReader(is))) {
|
||||||
String line;
|
String line;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
@@ -42,6 +109,7 @@ public class Random_word {
|
|||||||
line = line.trim();
|
line = line.trim();
|
||||||
if (!line.isEmpty()) {
|
if (!line.isEmpty()) {
|
||||||
count++;
|
count++;
|
||||||
|
// Choix aléatoire d'une ligne avec Reservoir Sampling
|
||||||
if (random.nextInt(count) == 0) {
|
if (random.nextInt(count) == 0) {
|
||||||
randomWord = line;
|
randomWord = line;
|
||||||
}
|
}
|
||||||
@@ -50,57 +118,77 @@ public class Random_word {
|
|||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
return randomWord != null ? randomWord.toLowerCase() : null;
|
return randomWord != null ? randomWord.toLowerCase() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tente une lettre, met à jour l'état du jeu et retourne un message.
|
* Tente une lettre proposée par le joueur.
|
||||||
|
* Met à jour l'état du jeu (mot caché, lettres incorrectes, vies restantes).
|
||||||
|
*
|
||||||
|
* @param letter lettre proposée
|
||||||
|
* @return message d'information pour le joueur (succès, erreur ou fin de partie)
|
||||||
*/
|
*/
|
||||||
public String guessLetter(char letter) {
|
public String guessLetter(char letter) {
|
||||||
letter = Character.toLowerCase(letter);
|
letter = Character.toLowerCase(letter);
|
||||||
|
|
||||||
|
// Vérifie si la lettre a déjà été essayée
|
||||||
if (lettersGuessed.contains(letter) || incorrectLetters.contains(letter)) {
|
if (lettersGuessed.contains(letter) || incorrectLetters.contains(letter)) {
|
||||||
return "Vous avez déjà essayé cette lettre !";
|
return "Vous avez déjà essayé cette lettre !";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Lettre correcte
|
||||||
if (secretWord.indexOf(letter) >= 0) {
|
if (secretWord.indexOf(letter) >= 0) {
|
||||||
lettersGuessed.add(letter);
|
lettersGuessed.add(letter);
|
||||||
|
|
||||||
|
// Remplace les underscores par la lettre devinée
|
||||||
for (int i = 0; i < secretWord.length(); i++) {
|
for (int i = 0; i < secretWord.length(); i++) {
|
||||||
if (secretWord.charAt(i) == letter) {
|
if (secretWord.charAt(i) == letter) {
|
||||||
hiddenWord[i] = letter;
|
hiddenWord[i] = letter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isWon()) {
|
if (isWon()) {
|
||||||
return "Félicitations ! Vous avez trouvé le mot : " + secretWord;
|
return "Félicitations ! Vous avez trouvé le mot : " + secretWord;
|
||||||
}
|
}
|
||||||
return "Bien joué !";
|
return "Bien joué !";
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
// Lettre incorrecte
|
||||||
incorrectLetters.add(letter);
|
incorrectLetters.add(letter);
|
||||||
lives--;
|
lives--;
|
||||||
|
|
||||||
if (lives <= 0) {
|
if (lives <= 0) {
|
||||||
return "Vous avez perdu ! Le mot était : " + secretWord;
|
return "Vous avez perdu ! Le mot était : " + secretWord;
|
||||||
}
|
}
|
||||||
|
|
||||||
return "Mauvaise lettre ! Il vous reste " + lives + " vies.";
|
return "Mauvaise lettre ! Il vous reste " + lives + " vies.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return le mot caché avec les lettres découvertes séparées par des espaces */
|
||||||
public String getHiddenWord() {
|
public String getHiddenWord() {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
for (char c : hiddenWord) sb.append(c).append(' ');
|
for (char c : hiddenWord) sb.append(c).append(' ');
|
||||||
return sb.toString().trim();
|
return sb.toString().trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return la liste des lettres incorrectes devinées */
|
||||||
public String getIncorrectLetters() {
|
public String getIncorrectLetters() {
|
||||||
return incorrectLetters.toString();
|
return incorrectLetters.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return nombre de vies restantes */
|
||||||
public int getLives() {
|
public int getLives() {
|
||||||
return lives;
|
return lives;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return true si le jeu est terminé (victoire ou défaite) */
|
||||||
public boolean isGameOver() {
|
public boolean isGameOver() {
|
||||||
return lives <= 0 || isWon();
|
return lives <= 0 || isWon();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return true si le mot est entièrement deviné */
|
||||||
public boolean isWon() {
|
public boolean isWon() {
|
||||||
for (char c : hiddenWord) {
|
for (char c : hiddenWord) {
|
||||||
if (c == '_') {
|
if (c == '_') {
|
||||||
@@ -110,6 +198,7 @@ public class Random_word {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return le mot secret */
|
||||||
public String getSecretWord() {
|
public String getSecretWord() {
|
||||||
return secretWord;
|
return secretWord;
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user