diff --git a/config.json b/config.json index bad191c..d3e7fad 100644 --- a/config.json +++ b/config.json @@ -1,6 +1,11 @@ { - "Difficulté": {"Value": "Normal", "Available": ["Facile", "Normal", "Difficile"]}, - "Vie": {"Value": 3, "Available": [1,2,3,4,5,6,7,8,9,10]}, - "Temps": {"Value": 180, "Available": [30,45,60,75,90,105,120,135,150,165,180,195,210,225,240,255,270,285,300,315,330,345,360,375,390,405,420,435,450,465,480,495,510,525,540,555,570,585,600]}, - "Bonus de temps": {"Value": 30, "Available": [0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150,160,170,180]} + "Difficulté": {"Value": "Normal", "Available": ["Facile", "Normal", "Difficile"]}, + "Vie": {"Value": 3, "Available": [1,2,3,4,5,6,7,8,9,10]}, + "Temps": {"Value": 180, "Available": [30,45,60,75,90,105,120,135,150,165,180,195,210,225,240,255,270,285,300,315,330,345,360,375,390,405,420,435,450,465,480,495,510,525,540,555,570,585,600]}, + "Bonus de temps": {"Value": 30, "Available": [0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150,160,170,180]}, + "Bonus de vie": {"Value": 0, "Available": [0,1,2,3,4,5]}, + "Max. Vie": {"Value": 5, "Available": [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]}, + "Module négligeable": {"Value": 0, "Available": [0,1,2,3,4,5,6,7,8,9,10]}, + "Mode daltonien": {"Value": "Aucun", "Available": ["Protanopie", "Deutéranopie", "Tritanopie"]}, + "Max. Score sauv.": {"Value": 30, "Available": [5,10,15,20,25,30,45,50,75,100,150,200,300]} } diff --git a/main.pyw b/main.pyw index 3d62c56..c9cf2b9 100644 --- a/main.pyw +++ b/main.pyw @@ -37,16 +37,25 @@ class AppClass(): # Classe du "moteur" du jeu } # On créer un dictionnaire qui associe toute les options proposé à leur fonction respective. MainMenu_Keys = list(MainMenu_Option.keys()) # On créer une liste qui ne contient que les clé du dictionnaire, permettant d'utiliser des index numériques. - classModule["display"].write(MainMenu_Keys[selected]) # On affiche le texte sur l'écran + prefix = "< " + suffix = " >" + + if selected == 0: + func_up = "pass" # Si on est à la première option, ne fait rien + prefix = " " - if selected == 0: func_up = "pass" # Si on est à la première option, ne fait rien else: func_up = lambda: self.MainMenu(selected = selected - 1) # sinon, remonte - if selected == len(MainMenu_Keys) - 1: func_down = "pass" # Si on est à la dernière option, ne fait rien + if selected == len(MainMenu_Keys) - 1: + func_down = "pass" # Si on est à la dernière option, ne fait rien + suffix = " " + else: func_down = lambda: self.MainMenu(selected = selected + 1) # sinon, descend func_right = MainMenu_Option[MainMenu_Keys[selected]] # Renvoie la fonction associé à l'option selectionné + classModule["display"].write(prefix + MainMenu_Keys[selected] + suffix) # On affiche le texte sur l'écran + classModule["simon"].bind(UpCmd = func_up, DownCmd = func_down, LeftCmd = "pass", RightCmd = func_right) @@ -70,14 +79,23 @@ class AppClass(): # Classe du "moteur" du jeu SettingsMenu_Keys = list(self.config.keys()) # On créer une liste qui ne contient que les clé du dictionnaire, permettant d'utiliser des index numériques. selected_name = SettingsMenu_Keys[selected] - classModule["display"].write(selected_name) # On affiche le texte sur l'écran + prefix = "< " + suffix = " >" + + if selected == 0: + func_up = "pass" # Si on est à la première option, ne fait rien + prefix = " " - if selected == 0: func_up = "pass" # Si on est à la première option, ne fait rien else: func_up = lambda: self.settings(selected = selected - 1) # sinon, remonte - if selected == len(SettingsMenu_Keys) - 1: func_down = "pass" # Si on est à la dernière option, ne fait rien + if selected == len(SettingsMenu_Keys) - 1: + func_down = "pass" # Si on est à la dernière option, ne fait rien + suffix = " " + else: func_down = lambda: self.settings(selected = selected + 1) # sinon, descend + classModule["display"].write(prefix + selected_name + suffix) # On affiche le texte sur l'écran + selected_value = self.config[selected_name]["Available"].index(self.config[selected_name]["Value"]) # Valeur de l'index de la valeur déjà défini dans les paramètres func_right = lambda: self.modif_settings(selected_name = selected_name, selected = selected_value) # Renvoie la fonction associé à l'option selectionné func_left = lambda: self.MainMenu(selected = 1) @@ -85,21 +103,30 @@ class AppClass(): # Classe du "moteur" du jeu classModule["simon"].bind(UpCmd = func_up, DownCmd = func_down, LeftCmd = func_left, RightCmd = func_right) - def modif_settings(self, selected_name, selected = 0): + def modif_settings(self, selected_name, selected = 0): # selected_name -> nom de la variable que l'on change # selected -> valeur actuellement sélectionné # On créer une liste qui ne contient que les clé du dictionnaire, permettant d'utiliser des index numériques. ModifSettingsMenu_Keys = self.config[selected_name]["Available"] - classModule["display"].write(ModifSettingsMenu_Keys[selected]) # On affiche le texte sur l'écran + prefix = "< " + suffix = " >" + + if selected == 0: + func_up = "pass" # Si on est à la première option, ne fait rien + prefix = " " - if selected == 0: func_up = "pass" # Si on est à la première option, ne fait rien else: func_up = lambda: self.modif_settings(selected_name = selected_name, selected = selected - 1) - if selected == len(ModifSettingsMenu_Keys) - 1: func_down = "pass" # Si on est à la dernière option, ne fait rien + if selected == len(ModifSettingsMenu_Keys) - 1: + func_down = "pass" # Si on est à la dernière option, ne fait rien + suffix = " " + else: func_down = lambda: self.modif_settings(selected_name = selected_name, selected = selected + 1) # sinon, descend + classModule["display"].write(prefix + str(ModifSettingsMenu_Keys[selected]) + suffix) # On affiche le texte sur l'écran + func_right = lambda: self.save_settings(selected_name = selected_name, selected = ModifSettingsMenu_Keys[selected]) - func_left = lambda: self.settings(selected = 0) + func_left = lambda: self.settings(selected = list(self.config.keys()).index(selected_name)) # On renvoie le joueur sur le menu de l'option qu'il est en train d'éditer classModule["simon"].bind(UpCmd = func_up, DownCmd = func_down, LeftCmd = func_left, RightCmd = func_right) @@ -111,7 +138,7 @@ class AppClass(): # Classe du "moteur" du jeu with open(r"config.pickle", "wb") as file: pickle.dump(self.config, file) - self.settings(selected = 0) + self.settings(selected = list(self.config.keys()).index(selected_name)) # On renvoie le joueur sur le menu de l'option qu'il est en train d'éditer def load_settings(self): # Lire le fichier pickle -> self.config @@ -122,6 +149,7 @@ class AppClass(): # Classe du "moteur" du jeu with open(r"config.json","rb") as file: self.config = json.load(file) + def leave(self): Fen.destroy() exit() diff --git a/module/button.py b/module/button.py index 41b0f27..51c6628 100644 --- a/module/button.py +++ b/module/button.py @@ -72,6 +72,9 @@ class button(): classModule["display"].PenalityLife() + def reset(self): + self.big_but.config(command = "pass") + classModule["button"] = button() # 2 - Le bouton doit être relié à la fonction "check" diff --git a/module/display.py b/module/display.py index 107b8d9..65c928f 100644 --- a/module/display.py +++ b/module/display.py @@ -5,7 +5,7 @@ class display(): self.frame = LabelFrame(Fen, text = "Display") # On créer une sous-fenêtre self.frame.grid(row = 1, column = 1, sticky = "NEWS") # On l'affiche - self.label = Label(self.frame, text = "ici on affichera le texte") + self.label = Label(self.frame, text = "chargement du chrono") self.label.grid(row = 1, column = 1, sticky = "NEWS") def write(self, text): @@ -28,15 +28,25 @@ class display(): else: self.write("%02i:%02i" % (self.minute, self.second)) - if self.time > 0: + if self.time <= 45: # Clignotement du chrono + if self.time % 2 == 0: self.label.config(foreground = "indianred", background = "gold") + else: self.label.config(foreground = "gold", background = "indianred") + + else: + self.label.config(foreground = "black", background = "SystemButtonFace") + + if self.time > 0: # Vérification que le joueur n'ai pas dépassé le temps imparti self.chrono_event = Fen.after(1000, self.chrono) - else: self.Lose() # Perdu par manque de temps + + else: + self.Lose() # Perdu par manque de temps + def start(self): self.PenalityAnimation = False self.DefuseAnimation = False - self.time = 181 # En lanceant le chrono, une seconde est immédiatement supprimée + self.time = App.config["Temps"]["Value"] + 1 # En lanceant le chrono, une seconde est immédiatement supprimée self.chrono() @@ -52,6 +62,8 @@ class display(): Fen.after_cancel(self.chrono_event) # On désactive le chrono self.write(random.choice(["GG", "Bravo", "Félicitation"])) + self.reset_all() + else: self.DefuseAnimation = True @@ -67,6 +79,17 @@ class display(): def Lose(self): Fen.after_cancel(self.chrono_event) # On désactive le chrono self.write(random.choice(["Perdu", "Dommage", "Try again"])) - # Réitialiser tout les modules + + self.reset_all() + + + def reset_all(self): # Cette fonction demande à tous les autres modules de se réinitialiser + for module in classModule: + classModule[module].reset() + + + def reset(self): # Cette fonction est appelé a chaque fin de partie pour réinitialiser ce module + self.label.config(foreground = "black", background = "SystemButtonFace") + Fen.after(7500, lambda: App.MainMenu()) # On laisse le joueur devant le message de victoire / défaite pendant 7.5 secondes classModule["display"] = display() diff --git a/module/morse.py b/module/morse.py index 78c01dd..faef28d 100644 --- a/module/morse.py +++ b/module/morse.py @@ -29,7 +29,6 @@ class morse(): self.frame.grid_rowconfigure(1, weight = 1) # tout les objets seront centré horizontalement self.frame.grid_columnconfigure(1, weight = 1) # tout les objets seront centré verticalement - self.morse = Label(self.frame, text = "", background = "lightgray", relief = SUNKEN, width = 2, height = 1) self.morse.grid(row = 1, column = 1) @@ -42,12 +41,17 @@ class morse(): self.SelectFen.protocol('WM_DELETE_WINDOW', lambda: "pass") # Rend la fenêtre non fermable self.HideSymbol() + self.ready = Label(self.SelectFen, text = "Lancer une partie pour\nafficher les symboles") + self.ready.grid(row = 1, column = 1) + + def start(self): self.defuse = False self.SelectButton.config(command = self.ShowSymbol) # mot à afficher en morse ###### + self.ready.grid_forget() Img_random = list(range(1, 13)) # On créer une liste allant de 1 à 12 random.shuffle(Img_random) # On la mélange self.dico_PNG = {} # On créer un dico pour garder en mémoire toute les images @@ -82,18 +86,18 @@ class morse(): if self.word_morse[index] == ".": self.morse.config(background = "yellow") Fen.after(250, lambda: self.morse.config(background = "lightgray")) - Fen.after(750, lambda: self.LedMorse(index + 1)) # 500 ms d'attente entre les signaux, plus les 250ms ou elle reste allumé afin de séparer les points et les virgules entre eux + self.Led_event = Fen.after(750, lambda: self.LedMorse(index + 1)) # 500 ms d'attente entre les signaux, plus les 250ms ou elle reste allumé afin de séparer les points et les virgules entre eux elif self.word_morse[index] == "-": self.morse.config(background = "yellow") Fen.after(1000, lambda: self.morse.config(background = "lightgray")) - Fen.after(1500, lambda: self.LedMorse(index + 1)) + self.Led_event = Fen.after(1500, lambda: self.LedMorse(index + 1)) elif self.word_morse[index] == " ": - Fen.after(2000, lambda: self.LedMorse(index + 1)) + self.Led_event = Fen.after(2000, lambda: self.LedMorse(index + 1)) else: - Fen.after(4000, lambda: self.LedMorse(index = 0)) + self.Led_event = Fen.after(4000, lambda: self.LedMorse(index = 0)) @@ -117,5 +121,13 @@ class morse(): classModule["display"].PenalityLife() + def reset(self): + self.morse.config(background = "lightgray") + for Num_img in self.dico_But: + self.dico_But[Num_img].destroy() + + self.ready.grid(row = 1, column = 1) + Fen.after_cancel(self.Led_event) + classModule["morse"] = morse() diff --git a/module/safe.py b/module/safe.py index c0488f8..bdaf046 100644 --- a/module/safe.py +++ b/module/safe.py @@ -79,7 +79,10 @@ class safe(): classModule["display"].PenalityLife() - + def reset(self): + self.label.config(background = "lightgray") # On éteint la LED + self.scale.config(command = lambda: "pass") # Désactive la mise à jour du curseur + self.Valid_but.config(command = lambda: "pass") # Désactive le bouton diff --git a/module/simon.py b/module/simon.py index 6d9d9ab..85370f3 100644 --- a/module/simon.py +++ b/module/simon.py @@ -89,20 +89,16 @@ class simon(): def sequence_choice(self, frame = 0): if frame <= self.Step: self.Sequence_step = self.Sequence[frame] - if self.Sequence_step == "Up": - self.dico_but[self.Sequence_step].config(background = "green") - elif self.Sequence_step == "Left": - self.dico_but[self.Sequence_step].config(background = "blue") - elif self.Sequence_step == "Right": - self.dico_but[self.Sequence_step].config(background = "red") - elif self.Sequence_step == "Down": - self.dico_but[self.Sequence_step].config(background = "yellow") + if self.Sequence_step == "Up": self.dico_but[self.Sequence_step].config(background = "green") + elif self.Sequence_step == "Left": self.dico_but[self.Sequence_step].config(background = "blue") + elif self.Sequence_step == "Right": self.dico_but[self.Sequence_step].config(background = "red") + elif self.Sequence_step == "Down": self.dico_but[self.Sequence_step].config(background = "yellow") else: frame = -1 Fen.after(1000, lambda: self.reset_all()) - Fen.after(1500, lambda: self.sequence_choice(frame + 1)) + self.Event_sequence = Fen.after(1500, lambda: self.sequence_choice(frame + 1)) def check(self, Button): @@ -130,7 +126,9 @@ class simon(): classModule["display"].checkDefuse() self.bind(LeftCmd = lambda: "pass", RightCmd = lambda: "pass", UpCmd = lambda: "pass", DownCmd = lambda: "pass") - + def reset(self): + Fen.after_cancel(self.Event_sequence) + self.bind(LeftCmd = lambda: "pass", RightCmd = lambda: "pass", UpCmd = lambda: "pass", DownCmd = lambda: "pass") classModule["simon"] = simon() diff --git a/module/wire.py b/module/wire.py index 439bc9a..24de5f8 100644 --- a/module/wire.py +++ b/module/wire.py @@ -48,15 +48,17 @@ class wire(): def start(self): # Code qui choisi des led qui doivent s'allumé, etc... self.defuse = False # Le module n'est pas désamorçer. + self.Blink_Event = {} for wire in self.dico_wire: # Pour chaque câbles, ... + self.Blink_Event[wire] = None self.dico_wire[wire]["WIRE"].config(command = lambda led = "%s" % wire: self.cut_wire(led = led)) # ... On le rend sécable. self.dico_wire[wire]["LIT"] = random.choice(["Off", "On", "Blink"]) if self.dico_wire[wire]["LIT"] == "On": self.dico_wire[wire]["LED"].config(background = "yellow") if self.dico_wire[wire]["LIT"] == "Blink": - self.dico_wire[wire]["LED"].config(background = "green") + self.blink_led(wire) self.wrong_cut = 0 # Compte le nombre de fils que le joueur n'aurait dû pas coupé avant @@ -66,6 +68,13 @@ class wire(): if "button" in classModule: classModule["button"].def_condition() # Puisque le module "button" a besoin de l'état des LEDs pour fonctionner, on l'éxécute après leur définition + def blink_led(self, wire, state = False): + if state: self.dico_wire[wire]["LED"].config(background = "yellow") + else: self.dico_wire[wire]["LED"].config(background = "lightgray") + + self.Blink_Event[wire] = Fen.after(750, lambda: self.blink_led(wire, not(state)) ) + + def cut_wire(self, led): #coupe les cables self.dico_wire[led]["WIRE"].config(command = lambda: "pass") self.dico_wire[led]["WIRE"].config(text = "--------- ---------") @@ -114,6 +123,13 @@ class wire(): # Si tout les fils ont été coupé correctement, alors le module est considéré comme étant désamorçer module.defuse = True # Si une erreur est détecté, on vérifie si elle vient du fait que l'on a mal coupé le fil où si c'est le reste des câbles à désamorçer + def reset(self): + for led in self.dico_wire: + if self.Blink_Event[led] != None: Fen.after_cancel(self.Blink_Event[led]) # On désactive le clignotement + + self.dico_wire[led]["LED"].config(background = "lightgray") # On rend chaque led éteinte + self.dico_wire[led]["WIRE"].config(text = "---------------------", command = lambda: "pass") # On répare tout les fils + self.dico_wire[led]["CUT"] = False # Les fils ne sont plus coupé classModule["wire"] = wire() # On ajoute le module à la liste des modules