2025-10-08 12:10:29 +02:00
|
|
|
"""
|
|
|
|
Importation des bibliothèques :
|
|
|
|
- tkinter : bibliothèque graphique
|
|
|
|
- random : permet de tirer au hasard un mot
|
|
|
|
- string et unicodedata : manipuler les mots
|
|
|
|
"""
|
2025-10-08 11:56:11 +02:00
|
|
|
from tkinter import *
|
|
|
|
from tkinter import ttk
|
|
|
|
import random
|
|
|
|
import string
|
|
|
|
import unicodedata
|
|
|
|
|
2025-10-08 12:10:29 +02:00
|
|
|
"""
|
|
|
|
Initialisation de la fenêtre (titre, taille)
|
|
|
|
"""
|
2025-10-08 11:56:11 +02:00
|
|
|
root = Tk()
|
2025-10-08 12:10:29 +02:00
|
|
|
root.title("Trouve le mot ou tu crèves !")
|
2025-10-08 11:56:11 +02:00
|
|
|
screen_width = root.winfo_screenwidth()
|
|
|
|
screen_height = root.winfo_screenheight()
|
|
|
|
root.geometry(f"{screen_width}x{screen_height}")
|
|
|
|
|
2025-10-08 12:10:29 +02:00
|
|
|
"""
|
|
|
|
Variable pour le nombre de tentatives échouées
|
|
|
|
"""
|
2025-10-08 11:56:11 +02:00
|
|
|
numberErrors = 0
|
|
|
|
|
|
|
|
|
2025-10-08 12:10:29 +02:00
|
|
|
"""
|
|
|
|
Texte pour l'affichage du jeu
|
|
|
|
"""
|
|
|
|
titre = ttk.Label(root, text="Jeu du Pendu", font=("Arial", 24))
|
|
|
|
titre.pack(side="top", fill="x", pady=20)
|
|
|
|
titre.config(anchor="center")
|
|
|
|
score = ttk.Label(root, text=f"Nombre d'erreur : {numberErrors}", font=("Arial", 24))
|
|
|
|
score.pack(side="bottom", fill="x", pady=20)
|
|
|
|
score.config(anchor="center")
|
2025-10-08 11:56:11 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
2025-10-08 12:10:29 +02:00
|
|
|
"""
|
|
|
|
Selectionne un mot au hasard dans le fichier mots.txt.
|
|
|
|
"""
|
2025-10-08 11:56:11 +02:00
|
|
|
def SelectAWord():
|
|
|
|
with open("mots.txt", 'r', encoding='utf-8') as f:
|
|
|
|
content = f.read()
|
|
|
|
words = content.split()
|
|
|
|
return random.choice(words)
|
|
|
|
|
2025-10-08 12:10:29 +02:00
|
|
|
|
|
|
|
"""
|
|
|
|
Cette fonction permet de créer une case dans le pack parent donné en paramètre. Cela correspond à une lettre.
|
|
|
|
"""
|
2025-10-08 11:56:11 +02:00
|
|
|
def create_case(parent):
|
|
|
|
case = Frame(parent, width=40, height=40)
|
|
|
|
case.pack_propagate(False)
|
|
|
|
case.pack(side=LEFT, padx=2)
|
|
|
|
|
|
|
|
canvas = Canvas(case, width=40, height=40, highlightthickness=0)
|
|
|
|
canvas.pack(fill=BOTH, expand=True)
|
|
|
|
canvas.create_line(0, 39, 40, 39, fill="black", width=2)
|
|
|
|
|
|
|
|
label = Label(case, text="", font=("Arial", 20))
|
|
|
|
label.place(relx=0.5, rely=0.5, anchor=CENTER)
|
|
|
|
|
2025-10-08 12:10:29 +02:00
|
|
|
return label
|
2025-10-08 11:56:11 +02:00
|
|
|
|
2025-10-08 12:10:29 +02:00
|
|
|
|
|
|
|
"""
|
|
|
|
Cette fonction est activé lors d'un clique sur une lettre. Elle prend en paramètre la lettre et le bouton selectionné.
|
|
|
|
Cette fonction permet de déterminer aussi quand le jeu est terminé ou non en mettant à jour le nombre d'erreur ou le mot.
|
|
|
|
"""
|
2025-10-08 11:56:11 +02:00
|
|
|
def letterClick(letter, button):
|
|
|
|
global numberErrors
|
|
|
|
global cases_labels
|
2025-10-08 12:10:29 +02:00
|
|
|
button.config(state=DISABLED)
|
2025-10-08 11:56:11 +02:00
|
|
|
indices = [i for i, l in enumerate(wordSelect) if l == letter]
|
|
|
|
if indices:
|
|
|
|
for i in indices:
|
|
|
|
cases_labels[i].config(text=letter)
|
|
|
|
allFound = all(lbl.cget("text") != "" for lbl in cases_labels)
|
|
|
|
if allFound:
|
|
|
|
endGame(True)
|
|
|
|
else:
|
|
|
|
numberErrors=numberErrors+1
|
|
|
|
score.config(text=f"Nombre d'erreur : {numberErrors}")
|
|
|
|
if numberErrors > 6:
|
|
|
|
endGame(False)
|
|
|
|
|
2025-10-08 12:10:29 +02:00
|
|
|
"""
|
|
|
|
Cette fonction supprime l'affichage du jeu pour afficher la fin de jeu.
|
|
|
|
"""
|
2025-10-08 11:56:11 +02:00
|
|
|
def endGame(victoire):
|
|
|
|
global wordSelect
|
|
|
|
for widget in root.winfo_children():
|
|
|
|
widget.destroy()
|
|
|
|
msg = wordSelect
|
|
|
|
if victoire:
|
|
|
|
texte = f"{msg}\n \n GAGNE !"
|
|
|
|
else:
|
|
|
|
texte = f"{msg}\n \nPERDU !"
|
|
|
|
lbl = Label(root, text=texte, font=("Arial", 48), justify="center")
|
|
|
|
lbl.pack(expand=True)
|
|
|
|
|
|
|
|
|
2025-10-08 12:10:29 +02:00
|
|
|
"""
|
|
|
|
Normalise le mot qui a été tirer au sort pour retirer les accents.
|
|
|
|
"""
|
2025-10-08 11:56:11 +02:00
|
|
|
wordSelect = SelectAWord().upper()
|
|
|
|
wordNormalize = unicodedata.normalize('NFKD', wordSelect)
|
|
|
|
wordNormalize = ''.join(c for c in wordNormalize if not unicodedata.combining(c))
|
|
|
|
wordSelect = wordNormalize
|
|
|
|
|
2025-10-08 12:10:29 +02:00
|
|
|
"""
|
|
|
|
Contient les cases du mot (chaque lettre)
|
|
|
|
"""
|
|
|
|
cases_labels = []
|
2025-10-08 11:56:11 +02:00
|
|
|
frame_cases = Frame(root)
|
|
|
|
frame_cases.pack(pady=20)
|
|
|
|
for _ in wordSelect:
|
|
|
|
lbl = create_case(frame_cases)
|
|
|
|
cases_labels.append(lbl)
|
|
|
|
|
|
|
|
|
2025-10-08 12:10:29 +02:00
|
|
|
|
|
|
|
"""
|
|
|
|
Via l'import string, ici on récupère l'alphabet et on crée les cases correspondantes pour que le joueur puisse sélectionner
|
|
|
|
une lettres
|
|
|
|
"""
|
2025-10-08 11:56:11 +02:00
|
|
|
frame_buttons = Frame(root)
|
|
|
|
frame_buttons.pack(pady=20)
|
|
|
|
for letter in string.ascii_uppercase:
|
|
|
|
btn = Button(frame_buttons, text=letter, width=3, height=1)
|
|
|
|
btn.pack(side=LEFT, padx=2)
|
|
|
|
btn.config(command=lambda l=letter, b=btn: letterClick(l, b))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
root.mainloop()
|