Python, système de sauvegarde.

M.E - Modifié le 21 mars 2024 à 12:58
mamiemando Messages postés 33446 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 20 décembre 2024 - 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

def ajouter_carte(carte):
    joueur = entry_joueur.get()
    if joueur:
        cartes_joueur.setdefault(joueur, []).append(carte)
        update_cartes_joueur(joueur)

def calculer_score(cartes):
    score = 0
    for carte in cartes:
        score += calculer_carte(carte)
    return score

def calculer_carte(carte):
    if carte in ["+4", "joker"]:
        return 50
    elif carte == "Spéciale":
        return 20
    elif carte.isdigit():
        return int(carte)
    else:
        return 0

def update_affichage():
    affichage_scores.delete(1.0, tk.END)
    for joueur, score in scores.items():
        affichage_scores.insert(tk.END, f"{joueur}: {score}\n")

def update_cartes_joueur(joueur):
    cartes_restantes = cartes_joueur.get(joueur, [])
    entry_cartes.delete(0, tk.END)
    entry_cartes.insert(tk.END, " ".join(cartes_restantes))

def ajouter_joueur():
    new_player = entry_nouveau_joueur.get()
    if new_player and new_player not in players_list:
        players_list.append(new_player)
        combo_joueurs['values'] = players_list
        combo_joueurs.set(new_player)
    entry_nouveau_joueur.delete(0, tk.END)

def on_select(event):
    selected_player = combo_joueurs.get()
    if selected_player:
        entry_joueur.delete(0, tk.END)
        entry_joueur.insert(tk.END, selected_player)

def assign_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é")

def on_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}")

def enregistrer_score():
    global score_enregistre
    joueur = entry_joueur.get()
    cartes_restantes = cartes_joueur.get(joueur, [])

    if joueur and cartes_restantes and not 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 = 0
for 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 += 1
    if 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.

A voir également:

2 réponses

yg_be Messages postés 23405 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 20 décembre 2024 Ambassadeur 1 557
20 mars 2024 à 15:27

bonjoue,

as-tu une question à propos de ce travail?

0
mamiemando Messages postés 33446 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 20 décembre 2024 7 812
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

0
yg_be Messages postés 23405 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 20 décembre 2024 1 557
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.

0
mamiemando Messages postés 33446 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 20 décembre 2024 7 812 > yg_be Messages postés 23405 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 20 décembre 2024
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 :-)

0

D'accord, merci pour votre aide.

0
mamiemando Messages postés 33446 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 20 décembre 2024 7 812 > M.E
25 mars 2024 à 12:33

As-tu d'autres question ou ton problème est résolu ?

0