M.E
-
Modifié le 21 mars 2024 à 12:58
mamiemando
Messages postés33540Date d'inscriptionjeudi 12 mai 2005StatutModérateurDernière intervention21 février 2025
-
25 mars 2024 à 12:33
Bonjour,
J'ai créé un carnet de note pour le UNO, afin de compter les points en fin de partie mais j'aimerais un système de sauvegarde (comme expliqué ci-dessous), je n'ai pas réussi à le coder, donc j'espère que quelqu'un de plus expérimenté que moi va réussir.
Dans le code ci-dessous j'aimerais ajouter un système de sauvegarde automatique, qui au démarrage propose le choix de recommencer une nouvelle partie ou bien de charger la précédente partie ou bien de choisir parmi les sauvegardes.
Pour cela, il faudra créer un système de sauvegarde automatique puis créer une page qui s'ouvre avant l'application, (tant que la première page n'est pas fermer l'application ne se lance pas), pour proposer de lancer une nouvelle partie ou de charger la précédente ou de prendre une partie sauvegardé (la partie sera sauvegardé grace à un bouton dans l'app principale).
import tkinter as tk
from tkinter import ttk
from ttkthemes import ThemedStyle
from PIL import Image, ImageTk
defajouter_carte(carte):
joueur = entry_joueur.get()if joueur:
cartes_joueur.setdefault(joueur,[]).append(carte)update_cartes_joueur(joueur)defcalculer_score(cartes):
score =0for carte in cartes:
score +=calculer_carte(carte)return score
defcalculer_carte(carte):if carte in["+4","joker"]:return50elif carte =="Spéciale":return20elif carte.isdigit():returnint(carte)else:return0defupdate_affichage():
affichage_scores.delete(1.0, tk.END)for joueur, score in scores.items():
affichage_scores.insert(tk.END, f"{joueur}: {score}\n")defupdate_cartes_joueur(joueur):
cartes_restantes = cartes_joueur.get(joueur,[])
entry_cartes.delete(0, tk.END)
entry_cartes.insert(tk.END," ".join(cartes_restantes))defajouter_joueur():
new_player = entry_nouveau_joueur.get()if new_player and new_player notin players_list:
players_list.append(new_player)
combo_joueurs['values']= players_list
combo_joueurs.set(new_player)
entry_nouveau_joueur.delete(0, tk.END)defon_select(event):
selected_player = combo_joueurs.get()if selected_player:
entry_joueur.delete(0, tk.END)
entry_joueur.insert(tk.END, selected_player)defassign_card_value(image_index):
card_values ={0:"0",1:"1",2:"2",3:"3",4:"4",5:"5",6:"6",7:"7",8:"8",9:"9",10:"+4",11:"joker",12:"Spéciale",13:"Spéciale",14:"Spéciale"}return card_values.get(image_index,"Valeur par défaut si l'index n'est pas trouvé")defon_button_click(image_index):
joueur = entry_joueur.get()try:if joueur:
carte =assign_card_value(image_index)
cartes_joueur.setdefault(joueur,[])if carte in["+4","joker","Spéciale"]:
cartes_joueur[joueur].append(carte)update_cartes_joueur(joueur)elif carte.isdigit():
cartes_joueur[joueur].append(carte)update_cartes_joueur(joueur)except KeyError as e:print(f"Erreur: Clé manquante - {e}")except Exception as e:print(f"Erreur: {e}")defenregistrer_score():global score_enregistre
joueur = entry_joueur.get()
cartes_restantes = cartes_joueur.get(joueur,[])if joueur and cartes_restantes andnot score_enregistre:
score =calculer_score(cartes_restantes)
scores[joueur]= scores.get(joueur,0)+ score
update_affichage()
score_enregistre = True
cartes_joueur[joueur].clear()
score_enregistre = False
root = tk.Tk()
root.title("Carnet de notes UNO")
scores ={}
cartes_joueur ={}
players_list =[]
score_enregistre = False
style =ThemedStyle(root)
style.set_theme("arc")
frame_principal = ttk.Frame(root, padding="20")
frame_principal.pack()
label_joueur = ttk.Label(frame_principal, text="Nom du Joueur :", foreground="black")
label_joueur.grid(row=0, column=0, padx=5, pady=5)
entry_joueur = ttk.Entry(frame_principal)
entry_joueur.grid(row=0, column=1, padx=5, pady=5)
label_nouveau_joueur = ttk.Label(frame_principal, text="Nouveau Joueur :", foreground="black")
label_nouveau_joueur.grid(row=0, column=2, padx=5, pady=5)
entry_nouveau_joueur = ttk.Entry(frame_principal)
entry_nouveau_joueur.grid(row=0, column=3, padx=5, pady=5)
style.configure("TButton", foreground="black")
button_ajouter_joueur = ttk.Button(frame_principal, text="Ajouter Joueur", command=ajouter_joueur)
button_ajouter_joueur.grid(row=0, column=4, padx=5, pady=5)
combo_joueurs = ttk.Combobox(frame_principal, values=players_list)
combo_joueurs.grid(row=0, column=1, padx=5, pady=5)
combo_joueurs.bind("<<ComboboxSelected>>", on_select)
label_choix_carte = ttk.Label(frame_principal, text="Sélectionnez une carte :", foreground="black")
label_choix_carte.grid(row=1, column=0, columnspan=4, padx=5, pady=5)
images_paths =[
r"C:\Users\miche\Documents\Code\Programme\UNO\Image des cartes\0.png",
r"C:\Users\miche\Documents\Code\Programme\UNO\Image des cartes\1.png",
r"C:\Users\miche\Documents\Code\Programme\UNO\Image des cartes\2.jpg",
r"C:\Users\miche\Documents\Code\Programme\UNO\Image des cartes\3.jpg",
r"C:\Users\miche\Documents\Code\Programme\UNO\Image des cartes\4.jpg",
r"C:\Users\miche\Documents\Code\Programme\UNO\Image des cartes\5.jpg",
r"C:\Users\miche\Documents\Code\Programme\UNO\Image des cartes\6.png",
r"C:\Users\miche\Documents\Code\Programme\UNO\Image des cartes\7.png",
r"C:\Users\miche\Documents\Code\Programme\UNO\Image des cartes\8.jpg",
r"C:\Users\miche\Documents\Code\Programme\UNO\Image des cartes\9.png",
r"C:\Users\miche\Documents\Code\Programme\UNO\Image des cartes\+4.png",
r"C:\Users\miche\Documents\Code\Programme\UNO\Image des cartes\joker.jpg",
r"C:\Users\miche\Documents\Code\Programme\UNO\Image des cartes\+2.png",
r"C:\Users\miche\Documents\Code\Programme\UNO\Image des cartes\Passe.png",
r"C:\Users\miche\Documents\Code\Programme\UNO\Image des cartes\Changement_de_sens.png"]
row =2
column =0
image_index =0for img_path in images_paths:
image = Image.open(img_path)
image = image.resize((50,75))
photo = ImageTk.PhotoImage(image)
button = ttk.Button(frame_principal, image=photo, command=lambda idx=image_index:on_button_click(idx))
button.image = photo
button.grid(row=row, column=column, padx=5, pady=5)
column +=1if column >3:
column =0
row +=1
image_index +=1
label_cartes = ttk.Label(frame_principal, text="Cartes restantes du Joueur :", foreground="black")
label_cartes.grid(row=row +1, column=0, columnspan=4, padx=5, pady=5)
entry_cartes = ttk.Entry(frame_principal)
entry_cartes.grid(row=row +2, column=0, columnspan=4, padx=5, pady=5)
style.configure("TButton", foreground="black")
button_enregistrer = ttk.Button(frame_principal, text="Enregistrer Score", command=enregistrer_score)
button_enregistrer.grid(row=row +3, column=0, columnspan=4, padx=5, pady=5)
affichage_scores = tk.Text(frame_principal, height=10, width=30)
affichage_scores.grid(row=row +4, column=0, columnspan=4, padx=5, pady=5)
root.mainloop()
Merci de votre lecture, et merci à se qui m'aideront, bonne journée.
yg_be
Messages postés23476Date d'inscriptionlundi 9 juin 2008StatutContributeurDernière intervention20 février 2025Ambassadeur1 568 20 mars 2024 à 15:27
mamiemando
Messages postés33540Date d'inscriptionjeudi 12 mai 2005StatutModérateurDernière intervention21 février 20257 828 21 mars 2024 à 13:09
Bonjour,
La manière la plus simple est de sauver la structure de données de ton choix (état de la partie, carnet de scores...) soit en JSON, soit en pickle. Les deux choix se défendent et on leurs propres contraintes :
pickle est plus compact, mais est spécifique à python et à quelques contraintes auxquelles tu ne devrais pas être confronté. De plus c'est un binaire donc tu ne peux pas l'ouvrir avec un éditeur texte
json est un format texte assez universelle, moins compact, et qui impose quelques contraintes auxquelles tu pourrais être confronté (tout n'est pas JSON-isable).
En pickle :
import pickle
from pathlib import Path
path =Path("sauverarde.pkl")
data ={1:"a",2:"b"}# Sauver data dans le fichier pickle
with open(path,"wb") as f_pkl:
pickle.dump(data, file=f_pkl)# Charger les données du fichier pickle dans d
with open(path,"rb") as f_pkl:
d = pickle.load(f_pkl)print(d)
En json :
import json
from pathlib import Path
path =Path("sauverarde.json")
data ={1:"a",2:"b"}# Sauver data dans le fichier pickle
with open(path,"w") as f_json:
json.dump(data, fp=f_json)# Charger les données du fichier pickle dans d
with open(path,"r") as f_json:
d = json.load(f_json)print(d)
À toi ensuite de répartir ces commandes en fonction des événements levés par ton implication (par exemple, clique sur le bouton "Sauver", "Charger", ...).
Bonne chance
yg_be
Messages postés23476Date d'inscriptionlundi 9 juin 2008StatutContributeurDernière intervention20 février 20251 568 21 mars 2024 à 13:36
Le défi, ici, réside dans l'utilisation de tkinter:
L'état de la partie est partiellement dans les objets de tkinter. Pour permettre le sauvetage, il faut donc modifier le code afin que tous les éléments composant l'état de la partie soient également mémorisés hors de tkinter
Après chargement, il faut recréer l'environnement tkinter tel qu'il était. Il faut donc modifier le code pour réaliser cela.
C'est probablement assez simple à réaliser par celui qui a créé le code existant. Plus compliqué sans compréhension de ce que fait le code existant.
mamiemando
Messages postés33540Date d'inscriptionjeudi 12 mai 2005StatutModérateurDernière intervention21 février 20257 828
>
yg_be
Messages postés23476Date d'inscriptionlundi 9 juin 2008StatutContributeurDernière intervention20 février 2025 21 mars 2024 à 14:03
Entièrement d'accord, c'est pour ça que je suis resté sur les principes de base (comment sauver une structure de données et la recharger) et ensuite c'est à M-E de faire sa cuisine :-)