8 Commits

12 changed files with 2124 additions and 0 deletions
+29
View File
@@ -0,0 +1,29 @@
# === Configuration ===
SRC_DIR = src
OUT_DIR = out
PACKAGE = fr/iut/Projet
MAIN_CLASS = fr.iut.Projet.Display
# === Règle principale ===
all: compile run
# === Compilation ===
compile:
@echo "Compilation du projet..."
@mkdir -p $(OUT_DIR)
# Compilation de tous les fichiers Java du package
@javac -d $(OUT_DIR) $(SRC_DIR)/$(PACKAGE)/*.java
# Copier Word.txt dans le dossier de sortie
@cp $(SRC_DIR)/$(PACKAGE)/Word.txt $(OUT_DIR)/$(PACKAGE)/
@echo "Compilation terminée."
# === Exécution ===
run:
@echo "Exécution du programme..."
@java -cp $(OUT_DIR) $(MAIN_CLASS)
# === Nettoyage ===
clean:
@echo "Suppression des fichiers compilés..."
@rm -rf $(OUT_DIR)
@echo "Nettoyage terminé."
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large Load Diff
+231
View File
@@ -0,0 +1,231 @@
package fr.iut.Projet;
import javax.swing.*;
import java.awt.*;
/**
* Classe qui représente l'interface graphique du jeu du pendu.
* Elle gère l'affichage du mot caché, des lettres incorrectes, des vies
* et permet de saisir des lettres. Un bouton permet de relancer le jeu.
*/
public class Action {
// Fenêtre principale du jeu
private JFrame gameFrame;
// Labels pour afficher le mot, les lettres incorrectes et les vies
private JLabel wordLabel;
private JLabel incorrectLettersLabel;
private JLabel livesLabel;
// Champ de saisie pour entrer une lettre
private JTextField letterInputField;
// Instance du jeu
private Random_word game;
/**
* Constructeur de la classe Action.
* Initialise le jeu, les composants graphiques et affiche la fenêtre.
*/
public Action() {
game = new Random_word();
initializeComponents();
layoutComponents();
letterInputField.addActionListener(e -> handleGuess());
gameFrame.setVisible(true);
}
// ==================== Initialisation des composants ====================
/**
* Initialise tous les composants graphiques :
* - Fenêtre principale
* - Labels pour le mot, les vies et les lettres incorrectes
* - Champ de saisie pour entrer les lettres
*/
private void initializeComponents() {
gameFrame = new JFrame("Hanging Man");
gameFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
gameFrame.setSize(600, 400);
wordLabel = new JLabel(game.getHiddenWord());
wordLabel.setFont(new Font("Arial", Font.BOLD, 32));
wordLabel.setHorizontalAlignment(SwingConstants.CENTER);
livesLabel = new JLabel("Lives: " + game.getLives());
livesLabel.setFont(new Font("Arial", Font.BOLD, 20));
livesLabel.setHorizontalAlignment(SwingConstants.CENTER);
incorrectLettersLabel = new JLabel("Incorrect letters: " + game.getIncorrectLetters());
incorrectLettersLabel.setFont(new Font("Arial", Font.PLAIN, 20));
incorrectLettersLabel.setHorizontalAlignment(SwingConstants.CENTER);
letterInputField = new JTextField(3);
letterInputField.setFont(new Font("Arial", Font.PLAIN, 24));
}
// ==================== Layout des composants ====================
/**
* Dispose les composants dans la fenêtre principale en utilisant GridBagLayout.
* Sépare la fenêtre en deux parties : le haut (mot et vies) et le bas (lettres incorrectes, saisie, bouton restart)
*/
private void layoutComponents() {
JPanel mainPanel = new JPanel(new GridBagLayout());
GridBagConstraints mainConstraints = new GridBagConstraints();
mainConstraints.gridx = 0;
mainConstraints.fill = GridBagConstraints.BOTH;
mainConstraints.insets = new Insets(5, 5, 5, 5);
JPanel topPanel = createTopPanel();
mainConstraints.gridy = 0;
mainConstraints.weighty = 3.0;
mainConstraints.weightx = 1.0;
mainPanel.add(topPanel, mainConstraints);
JPanel bottomPanel = createBottomPanel();
mainConstraints.gridy = 1;
mainConstraints.weighty = 1.0;
mainPanel.add(bottomPanel, mainConstraints);
gameFrame.add(mainPanel, BorderLayout.CENTER);
}
/**
* Crée le panneau supérieur avec :
* - Le label des vies (à gauche)
* - Le label du mot caché (à droite)
* @return JPanel configuré pour la partie supérieure
*/
private JPanel createTopPanel() {
JPanel topPanel = new JPanel(new GridBagLayout());
// Panel pour les vies
JPanel livesPanel = new JPanel(new GridBagLayout());
GridBagConstraints livesConstraints = new GridBagConstraints();
livesConstraints.anchor = GridBagConstraints.CENTER;
livesConstraints.fill = GridBagConstraints.NONE;
livesPanel.add(livesLabel, livesConstraints);
// Panel pour le mot
JPanel wordPanel = new JPanel(new GridBagLayout());
GridBagConstraints wordConstraints = new GridBagConstraints();
wordConstraints.anchor = GridBagConstraints.CENTER;
wordConstraints.fill = GridBagConstraints.NONE;
wordPanel.add(wordLabel, wordConstraints);
// Ajout des panels dans topPanel
GridBagConstraints leftConstraints = new GridBagConstraints();
leftConstraints.gridx = 0;
leftConstraints.weightx = 0.5;
leftConstraints.weighty = 1.0;
leftConstraints.fill = GridBagConstraints.BOTH;
topPanel.add(livesPanel, leftConstraints);
GridBagConstraints rightConstraints = new GridBagConstraints();
rightConstraints.gridx = 1;
rightConstraints.weightx = 0.5;
rightConstraints.weighty = 1.0;
rightConstraints.fill = GridBagConstraints.BOTH;
topPanel.add(wordPanel, rightConstraints);
return topPanel;
}
/**
* Crée le panneau inférieur avec :
* - Le label des lettres incorrectes
* - Le champ de saisie pour entrer une lettre
* - Le bouton "Restart" en bas à droite
* @return JPanel configuré pour la partie inférieure
*/
private JPanel createBottomPanel() {
JPanel bottomPanel = new JPanel();
bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.Y_AXIS));
// Label des lettres incorrectes
incorrectLettersLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
bottomPanel.add(incorrectLettersLabel);
// Champ de saisie
JLabel promptLabel = new JLabel("Enter a letter:");
promptLabel.setFont(new Font("Arial", Font.PLAIN, 16));
promptLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
JPanel inputRow = new JPanel(new FlowLayout(FlowLayout.CENTER, 5, 5));
inputRow.add(promptLabel);
inputRow.add(letterInputField);
inputRow.setAlignmentX(Component.CENTER_ALIGNMENT);
bottomPanel.add(Box.createVerticalStrut(10));
bottomPanel.add(inputRow);
// Bouton "Restart" en bas à droite
JButton restartButton = new JButton("Restart");
restartButton.addActionListener(new PlayButtonListener(gameFrame));
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
buttonPanel.add(restartButton);
bottomPanel.add(Box.createVerticalStrut(10));
bottomPanel.add(buttonPanel);
return bottomPanel;
}
// ==================== Gestion du jeu ====================
/**
* Gère la saisie d'une lettre par le joueur.
* Vérifie la validité de la lettre, met à jour l'affichage et termine le jeu si nécessaire.
*/
private void handleGuess() {
String inputText = letterInputField.getText();
letterInputField.setText("");
if (!isValidInput(inputText)) return;
char guessedLetter = inputText.charAt(0);
String message = game.guessLetter(guessedLetter);
updateUI();
if (game.isGameOver()) endGame(message);
}
/**
* Vérifie si la saisie de l'utilisateur est valide :
* - Une seule lettre
* - Caractère alphabétique
* @param inputText texte saisi par l'utilisateur
* @return true si la saisie est valide, false sinon
*/
private boolean isValidInput(String inputText) {
if (inputText.length() != 1 || !Character.isLetter(inputText.charAt(0))) {
JOptionPane.showMessageDialog(gameFrame, "Please enter a single letter!");
return false;
}
return true;
}
/**
* Met à jour l'affichage des labels :
* - Mot caché
* - Lettres incorrectes
* - Nombre de vies restantes
*/
private void updateUI() {
wordLabel.setText(game.getHiddenWord());
incorrectLettersLabel.setText("Incorrect letters: " + game.getIncorrectLetters());
livesLabel.setText("Lives: " + game.getLives());
}
/**
* Termine le jeu et affiche un message.
* Désactive le champ de saisie.
* @param message Message à afficher (victoire ou défaite)
*/
private void endGame(String message) {
JOptionPane.showMessageDialog(gameFrame, message);
letterInputField.setEditable(false);
}
}
+48
View File
@@ -0,0 +1,48 @@
package fr.iut.Projet;
import javax.swing.*;
import java.awt.*;
/**
* Classe Display représentant le menu principal du jeu "Hanging Man".
* Elle affiche le titre et le bouton Play.
*/
public class Display {
/**
* Méthode principale. Crée et affiche la fenêtre du menu principal.
* @param args Arguments de la ligne de commande (non utilisés)
*/
public static void main(String[] args) {
// Création de la fenêtre principale
JFrame frame = new JFrame("Hanging Man");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(1040, 1000);
frame.setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.Y_AXIS));
// Titre du jeu
JLabel text = new JLabel("Hanging Man");
text.setAlignmentX(Component.CENTER_ALIGNMENT);
text.setFont(new Font("Arial", Font.BOLD, 70));
// Bouton Play
JButton play = new JButton("Play");
play.setAlignmentX(Component.CENTER_ALIGNMENT);
play.setPreferredSize(new Dimension(300, 100));
play.setMaximumSize(new Dimension(300, 150));
play.setFont(new Font("Arial", Font.PLAIN, 36));
// Listener séparé pour gérer le clic sur Play
play.addActionListener(new PlayButtonListener(frame));
// Ajouter les composants avec de l'espace
frame.add(Box.createVerticalGlue());
frame.add(text);
frame.add(Box.createVerticalStrut(30));
frame.add(play);
frame.add(Box.createVerticalGlue());
// Affichage de la fenêtre
frame.setVisible(true);
}
}
+35
View File
@@ -0,0 +1,35 @@
package fr.iut.Projet;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* Classe PlayButtonListener qui gère le clic sur le bouton "Play" du menu.
* Lorsqu'on clique sur le bouton, cette classe ouvre la fenêtre du jeu
* et ferme la fenêtre principale.
*/
public class PlayButtonListener implements ActionListener {
/** Référence à la fenêtre principale du menu */
private JFrame parentFrame;
/**
* Constructeur de PlayButtonListener.
* @param frame La fenêtre principale à fermer après ouverture du jeu
*/
public PlayButtonListener(JFrame frame) {
this.parentFrame = frame;
}
/**
* Méthode appelée lorsque le bouton est cliqué.
* Ouvre la fenêtre du jeu et ferme la fenêtre principale.
* @param e L'événement déclenché par le clic
*/
@Override
public void actionPerformed(ActionEvent e) {
new Action(); // Ouvre la fenêtre du jeu
parentFrame.dispose(); // Ferme la fenêtre principale
}
}
+111
View File
@@ -0,0 +1,111 @@
package fr.iut.Projet;
import java.io.*;
import java.util.*;
public class Random_word {
private String secretWord;
private char[] hiddenWord;
private Set<Character> lettersGuessed;
private Set<Character> incorrectLetters;
private int lives;
/**
* Constructeur : sélectionne un mot aléatoire et initialise le jeu.
*/
public Random_word() {
this.secretWord = getRandomWord();
if (this.secretWord == null) {
throw new RuntimeException("Impossible de choisir un mot aléatoire !");
}
this.lives = 8;
this.hiddenWord = new char[secretWord.length()];
Arrays.fill(this.hiddenWord, '_');
this.lettersGuessed = new HashSet<>();
this.incorrectLetters = new HashSet<>();
}
/**
* Lit les mots dans "Word.txt" et retourne un mot aléatoire.
*/
private String getRandomWord() {
InputStream is = Random_word.class.getResourceAsStream("Word.txt");
if (is == null) return null;
String randomWord = null;
Random random = new Random();
try (BufferedReader br = new BufferedReader(new InputStreamReader(is))) {
String line;
int count = 0;
while ((line = br.readLine()) != null) {
line = line.trim();
if (!line.isEmpty()) {
count++;
if (random.nextInt(count) == 0) {
randomWord = line;
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
return randomWord != null ? randomWord.toLowerCase() : null;
}
/**
* Tente une lettre, met à jour l'état du jeu et retourne un message.
*/
public String guessLetter(char letter) {
letter = Character.toLowerCase(letter);
if (lettersGuessed.contains(letter) || incorrectLetters.contains(letter)) {
return "Vous avez déjà essayé cette lettre !";
}
if (secretWord.indexOf(letter) >= 0) {
lettersGuessed.add(letter);
for (int i = 0; i < secretWord.length(); i++) {
if (secretWord.charAt(i) == letter) {
hiddenWord[i] = letter;
}
}
if (isWon()) {
return "Félicitations ! Vous avez trouvé le mot : " + secretWord;
}
return "Bien joué !";
} else {
incorrectLetters.add(letter);
lives--;
if (lives <= 0) {
return "Vous avez perdu ! Le mot était : " + secretWord;
}
return "Mauvaise lettre ! Il vous reste " + lives + " vies.";
}
}
public String getHiddenWord() {
StringBuilder sb = new StringBuilder();
for (char c : hiddenWord) sb.append(c).append(' ');
return sb.toString().trim();
}
public String getIncorrectLetters() {
return incorrectLetters.toString();
}
public int getLives() {
return lives;
}
public boolean isGameOver() {
return lives <= 0 || isWon();
}
public boolean isWon() {
return secretWord.equals(String.valueOf(hiddenWord));
}
public String getSecretWord() {
return secretWord;
}
}
File diff suppressed because it is too large Load Diff