def remObject(ID): """ Supprime un objet (du rendu et de la base des objets). :param string ID: ID de l'objet """ global positions, renderQueue, objects try: if objects[ID]["type"] == "Panel": if objects[ID]["childs"]: for o in objects[ID]["childs"]: remObject(o) positions[objects[ID]["layer"]].pop(ID, None) renderQueue[objects[ID]["layer"]].remove(ID) if objects[ID]["tkObjects"]: for o in objects[ID]["tkObjects"]: efface(o) objects.pop(ID, None) reDraw() # A corriger return positions[objects[ID]["layer"]].pop(ID, None) renderQueue[objects[ID]["layer"]].remove(ID) if objects[ID]["tkObjects"]: for o in objects[ID]["tkObjects"]: efface(o) objects.pop(ID, None) except KeyError as e: print("UI Warning: cannot remove unknown object", e)
def display_pion(p): """ Réaffiche le pion indiqué. :param int p: numéro du pion """ utk.efface("pion" + str(p)) name = lvl.pion_name[p] # Affichage de la magicienne en mode fantome if name == "magicienne" and lvl.ghost_mod: utk.image(lvl.pion_pos[p][0] // 2 * 40 + 20 + level_pos[0], lvl.pion_pos[p][1] // 2 * 40 + 20 + level_pos[1], "sprites/magicienne_ghost.gif", tag="pion" + str(p)) # Affichage des autres pions else: if "grenouille" in name: name = "grenouille" utk.image(lvl.pion_pos[p][0] // 2 * 40 + 20 + level_pos[0], lvl.pion_pos[p][1] // 2 * 40 + 20 + level_pos[1], "sprites/" + name + ".gif", tag="pion" + str(p)) # Affichage si le pion mange if name == lvl.eating: utk.image(lvl.pion_pos[p][0] // 2 * 40 + 20 + level_pos[0], lvl.pion_pos[p][1] // 2 * 40 + 20 + level_pos[1], "sprites/eating.gif", tag="pion" + str(p)) if name == "magicienne" and lvl.invisible: utk.image(lvl.pion_pos[p][0] // 2 * 40 + 20 + level_pos[0], lvl.pion_pos[p][1] // 2 * 40 + 20 + level_pos[1], "sprites/invisibility_circle.gif", tag="pion" + str(p))
def UIecranTitre(): """ Affiche l'écran titre, renvoie True si le joueur charge un ancienne partie, sinon False""" tk.texte(800, 100, 'MagicMaze, par Théodore Garcher et Simon Eveillé', ancrage = 'center') tk.rectangle(200, 200, 550, 350, couleur = 'black', remplissage = '#b9b9b9', epaisseur = 3) tk.texte(375, 275, "Nouvelle Partie", ancrage = 'center') tk.rectangle(200, 400, 550, 550, couleur = 'black', remplissage = '#b9b9b9', epaisseur = 3) tk.texte(375, 475, "Charger une partie", ancrage = 'center') tk.texte(800, 800, "Selectionnez le nombre de joueur avec ↑, ↓ et Entrée", ancrage = 'center' ) # Selecteur choix = False entreeClavier = None while entreeClavier != 'Return': tk.efface('selecteur') if not choix : tk.rectangle(190, 190, 560, 360, couleur = '#565656', remplissage = '', epaisseur = 4, tag = 'selecteur') else : tk.rectangle(190, 390, 560, 560, couleur = '#565656', remplissage = '', epaisseur = 4, tag = 'selecteur') entreeClavier = tk.attente_touche() if entreeClavier == 'Up': choix = False elif entreeClavier == 'Down': choix = True return choix
def display_selected_ingame(x, y, select_value, list_choice, tag_name="default"): """ Affiche le pion sélectionné en jeu. """ utk.efface(tag_name) utk.image(x + 20, y + 10, "sprites/select_arrow_up.gif", tag=tag_name) utk.image(x + 20, y + len(list_choice) * 40 + 30, "sprites/select_arrow_down.gif", tag=tag_name) for i in range(len(list_choice)): utk.rectangle(x, y + i * 40 + 20, x + 40, y + (i + 1) * 40 + 20, couleur="black", remplissage="cyan" * (i == select_value), epaisseur=2, tag=tag_name) utk.image(x + 20, y + i * 40 + 40, "sprites/" + list_choice[i] + ".gif", tag=tag_name)
def display_timer(x, y): """ Affiche le timer. Ne le met pas à jour. """ utk.efface("timer") if timer.timer_paused: utk.image(x + 50, y + 50, "sprites/hourglass_freeze.gif", tag="timer") else: utk.image(x + 50, y + 50, "sprites/hourglass.gif", tag="timer") if timer.timer > 0: utk.texte(x + 50, y + 110, str(int(timer.timer) // 60) + ":" + str(int(timer.timer % 60)), couleur="black", ancrage="center", police="Purisa", taille=28, tag="timer") else: utk.texte(x + 50, y + 110, "0:0", couleur="black", ancrage="center", police="Purisa", taille=28, tag="timer")
def render(text=None): """ Exécute toutes les actions liées à au rendu de l'interface, principalement la gestion des objets à dessiner puis supprimer de la pile d'affichage. :param string text: texte affiché au dessus de toute l'interface en bas à gauche (utilisé pour le compteur d'images par seconde) """ for r in renderRoutines.values(): r[0](*r[1]) buffer = getToRenderObjects() if buffer: for l in buffer: for ID in l: if objects[ID]["tkObjects"]: for t in objects[ID]["tkObjects"]: efface(t) if not objects[ID]["hidden"] or not objects[ID]["isChild"]: drawObject(ID) l.clear() setToRenderObjects(buffer) efface("fps") if text: texte(0, HEIGHT_WINDOW, str(text) + " fps", "white", ancrage="sw", tag="fps")
def afficherPlateau(matriceTerrain, mursHor, mursVer, infoPion ,listeGagnants, pionActif, debugActif, sortieActive, heureDebut, dureeTotalePartie, modifTemps, vortexActif, dicVortex, touchesPartie, touchesPartieParJoueur, matriceTuiles, modeTelekinesie, tuilesPosees, telekinesieIndexTuileActive, telekinesiesRestantes): """ Affiche le terrain en entier et l'interface. Args: matriceTerrain (list): matrice qui encode le terrain infoPion (list): Infos de position des pions listeGagnants (list): liste des pions ayant gagné Returns: None. """ #Calcul du temps restant tempsRestant = dureeTotalePartie-time()+heureDebut + modifTemps[0] tempsEcoule = dureeTotalePartie - tempsRestant # Renversement du sablier si un pion se trouve sur une case sablier if pionSurSablier(matriceTerrain, infoPion): if tempsRestant > tempsEcoule: modifTemps[0] += ((tempsRestant - tempsEcoule) * (-1)) else: modifTemps[0] += (tempsEcoule - tempsRestant) # Affichage de l'interface tk.rectangle(0, 0, 1300, 1000, couleur = 'black', remplissage = 'grey') if debugActif == 1: tk.texte(180, 700, "Mode debug activé\nO: Changer la vitesse\nP: Quitter mode debug", taille = 28,couleur = 'red') if sortieActive: tk.texte(1320, 50, "Sortie activée ! Rendez vous à la sortie !", taille = 24, couleur = 'light green') tk.texte(10, 10, "Backspace : Sauvegarder et quitter") affichagePionsInterface(touchesPartieParJoueur) affichageTouches(touchesPartieParJoueur) affichagePionActif(pionActif) # Affichage du terrain et des pions # listeCoordonnee = [tuple([ligne, colonne]) for ligne in range(len(matriceTerrain)) for colonne in range(len(matriceTerrain[0]))] # affichageCellulePlateau(listeCoordonnee, matriceTerrain) # affichageMurs(mursHor, mursVer) affichageTuiles(matriceTuiles) for pion in range(1,8): if pion not in listeGagnants: if pion in infoPion.keys(): afficherPion(pion, infoPion, matriceTuiles) if vortexActif != [0]: affichageVortexActif(pionActif[touchesPartie['vortex'][1]], vortexActif, dicVortex, matriceTuiles) if modeTelekinesie != [0]: affichageTelekinesie(tuilesPosees, telekinesieIndexTuileActive, telekinesiesRestantes) tk.mise_a_jour() # Gestion défaite if tempsRestant >= 0: # Partie en cours # Affichage du temps restant tk.efface('chronometre') tk.texte(1320, 10, str(int(tempsRestant))+" secondes restantes", taille = 24, tag = 'chronometre') return False, tempsRestant else: # Partie terminée return True, tempsRestant
def display_menu_selection(selected): """ Affiche la sélection du menu """ utk.efface("selection") utk.rectangle(win_size[0] / 2 - 150, selected * 40 + 105, win_size[0] / 2 + 150, selected * 40 + 135, couleur="grey", remplissage="grey", epaisseur=1, tag="selection")
def display_menu_choice(menu_choice): """ Affiche les différents choix du menu. """ utk.efface("choice") for i in range(len(menu_choice)): choice = menu_choice[i] if choice == "Nombre de joueur : ": choice += str(lvl.nbr_of_player) utk.texte(win_size[0] / 2, 120 + i * 40, choice, couleur="white", ancrage="center", police="Purisa", taille="16", tag="choice")
def UIchoixNbrJoueur(): """ Renvoie le nombre de joueur selectionné par l'utilisateur """ # Affichage de base tk.efface_tout() tk.texte(600, 100, "Selectionnez le nombre de joueur avec ↑, ↓ et Entrée", ancrage = 'center' ) tk.rectangle(200, 200, 450, 350, couleur = 'black', remplissage = '#b9b9b9', epaisseur = 3) tk.texte(325, 280, "1", ancrage = 'center', taille = 30) tk.rectangle(200, 400, 450, 550, couleur = 'black', remplissage = '#b9b9b9', epaisseur = 3) tk.texte(325, 480, "2", ancrage = 'center', taille = 30) tk.rectangle(200, 600, 450, 750, couleur = 'black', remplissage = '#b9b9b9', epaisseur = 3) tk.texte(325, 680, "3", ancrage = 'center', taille = 30) # Selecteur choix = 1 entreeClavier = None while entreeClavier != 'Return': tk.efface('selecteur') if choix == 1: tk.rectangle(190, 190, 460, 360, couleur = '#565656', remplissage = '', epaisseur = 4, tag = 'selecteur') elif choix == 2: tk.rectangle(190, 390, 460, 560, couleur = '#565656', remplissage = '', epaisseur = 4, tag = 'selecteur') elif choix == 3: tk.rectangle(190, 590, 460, 760, couleur = '#565656', remplissage = '', epaisseur = 4, tag = 'selecteur') entreeClavier = tk.attente_touche() if entreeClavier == 'Up': choix = choix-1 if choix > 1 else choix if entreeClavier == 'Down': choix = choix+1 if choix < 3 else choix return choix entree = None while entree != 'Escape': entree = tk.attente_touche() return
def solver_game(lab_path: str, game_type: str, display: bool) -> None: """ Start a new game where one of the solver tries to solve the game, and then demonstrate its solution if it can find one. :param lab_path: path of the file to parse to create the world. :param game_type: type of solver that the user wants to use (naive or minimal) :param display: set to True, the user will visualize all the computations steps made by the solver to find a solution. :return: None """ if game_type == "naive": solver = NaiveSolver() elif game_type == "minimal": solver = MinimalSolver() else: return usage() world = create_world_from_file(lab_path) initial_config = world.to_configuration() view.create_window(world) view.display(world) if solver.solve(world, display): print("Solution found (", len(solver.solution), "moves) !") solver.display_solution() world.load_configuration(initial_config) upemtk.texte(HEIGHT // 2, WIDTH // 2, "CLICK TO SEE SOLUTION", couleur='black', ancrage='center', taille=40, tag="click_to_display") upemtk.attend_clic_gauche() upemtk.efface("click_to_display") view.display(world) solver.play_game(world) display_result(world) else: print("No solution found...") upemtk.ferme_fenetre()
def _input(msg, reponse_defaut): """ meme fonction que input mais cette fois si s'affiche à l'écran et non sur la console :param str msg: message decrivant linput sur la fenetre :param str reponse_defaut: texte a afficher par defaut dans linput :return: saisie de lutilisateur au clavier (str) """ texte = reponse_defaut while True: ev = upemtk.donne_evenement() type_ev = upemtk.type_evenement(ev) if type_ev == "Touche": x = upemtk.touche(ev) if x == "Return": return texte elif x == "BackSpace": texte = texte[:-1] elif len(x) == 1 and len(texte) <= 18: texte += x elif x in dico_texte: texte += dico_texte[x] elif type_ev == "ClicGauche": return texte upemtk.efface("texte_input") upemtk.texte( var["dimension_fenetre"] // 2, var["dimension_fenetre"] // 2, texte, couleur="white", ancrage="center", tag="texte_input", ) upemtk.mise_a_jour()
def efface_discuss_icon(): utk.efface("discuss_icon")
def open_exit(): utk.efface("closed") utk.efface("to_steal")
def efface_selected_target(): utk.efface("target_select") utk.efface("target_select_confirmed")
def display_selected_target_confirmed(pos_case): utk.efface("target_select_confirmed") utk.image(pos_case[0] // 2 * 40 + 20 + level_pos[0], pos_case[1] // 2 * 40 + 20 + level_pos[1], "sprites/select_ingame_confirmed.gif", tag="target_select_confirmed")
def my_input(msg, type_retour, reponse_defaut=""): """ affichage de l'input :param str msg: message decrivant linput sur la fenetre :param str type_retour: ("int", "str") :param str reponse_defaut: texte a afficher par defaut dans linput :return: texte saisie par lutilisateur respectant le type voulu """ upemtk.rectangle( var["dimension_fenetre"] // 2 - 180, var["dimension_fenetre"] // 2 - 100, var["dimension_fenetre"] // 2 + 180, var["dimension_fenetre"] // 2 + 100, couleur="gray28", remplissage="gray", epaisseur=5, tag="cadre", ) while True: upemtk.texte( var["dimension_fenetre"] // 2, var["dimension_fenetre"] // 2 - 50, msg, couleur="white", ancrage="center", tag="msg", ) _var = _input(msg, reponse_defaut) if type_retour == "int": if _var.isdigit(): if int(_var) < 500 and int(_var) >= 0: upemtk.efface("msg") upemtk.efface("msg_erreur") upemtk.efface("texte_input") upemtk.efface("cadre") return int(_var) elif int(_var) == 0: upemtk.efface("msg_erreur") upemtk.texte( var["dimension_fenetre"] // 2, var["dimension_fenetre"] // 2 + 75, "Valeur trop petite", couleur="red", ancrage="center", police="impact", tag="msg_erreur", ) else: upemtk.efface("msg_erreur") upemtk.texte( var["dimension_fenetre"] // 2, var["dimension_fenetre"] // 2 + 75, "Valeur trop grande", couleur="red", ancrage="center", police="impact", tag="msg_erreur", ) else: upemtk.efface("msg_erreur") upemtk.texte( var["dimension_fenetre"] // 2, var["dimension_fenetre"] // 2 + 75, "Valeur entiere requis", couleur="red", ancrage="center", police="impact", tag="msg_erreur", ) else: upemtk.efface("msg") upemtk.efface("msg_erreur") upemtk.efface("texte_input") upemtk.efface("cadre") return _var
def efface_discuss(): utk.efface("discuss_icon") utk.efface("discuss_info")
def spell_target_selection(input): spell = lvl.spell_being_used p = lvl.player_using_spell control = lvl.controller[p] target = lvl.selected_spell_target target_id = None if input in control.keys(): if "select" in control[input]: select_delta = int(control[input].replace( "select player ", "").replace("select action ", "")) # Sélection pour le sort balai if spell == "balai": target_id = lvl.deactive_hourglass.index(target) target_id += select_delta if target_id >= len(lvl.deactive_hourglass): target_id = 0 lvl.selected_spell_target = lvl.deactive_hourglass[target_id] display.display_selected_target(lvl.selected_spell_target) # Sélection durant le sort grenouille if spell == "grenouille": target_id = lvl.pion_pos.index(target) while True: target_id += select_delta if target_id >= len(lvl.pion_name): target_id = 0 if target_id < 0: target_id = len(lvl.pion_name) - 1 if "garde" in lvl.pion_name[target_id]: lvl.selected_spell_target = lvl.pion_pos[target_id] break display.display_selected_target(lvl.selected_spell_target) # Sélection pour le sort echange if spell == "echange": target_id = lvl.get_index_pion_pos(target) while True: target_id += select_delta if target_id >= len(lvl.pion_name): target_id = 0 if target_id < 0: target_id = len(lvl.pion_name) - 1 if "grenouille" not in lvl.pion_name[ target_id] and target_id not in lvl.move_pion: lvl.selected_spell_target = lvl.pion_pos[target_id] break display.display_selected_target(lvl.selected_spell_target) # Sélection pour le sort teleportation if spell == "teleportation" and len(lvl.move_pion) == 0: target_id = lvl.get_index_pion_pos(target) while True: target_id += select_delta if target_id >= len(lvl.pion_name): target_id = 0 if target_id < 0: target_id = len(lvl.pion_name) - 1 if "grenouille" not in lvl.pion_name[ target_id] and target_id not in lvl.move_pion: lvl.selected_spell_target = lvl.pion_pos[target_id] break display.display_selected_target(lvl.selected_spell_target) # Sélection durant le sort grenouille if spell == "appat": target_id = lvl.get_index_pion_pos(target) if len(lvl.move_pion) == 0: while True: target_id += select_delta if target_id >= len(lvl.pion_name): target_id = 0 if target_id < 0: target_id = len(lvl.pion_name) - 1 if "garde" in lvl.pion_name[target_id]: lvl.selected_spell_target = lvl.pion_pos[target_id] break display.display_selected_target(lvl.selected_spell_target) else: y_start = target[1] y_end = len(lvl.level) * (select_delta == 1) - ( select_delta == -1) x_start = target[0] + select_delta * 2 x_end = len(lvl.level[0]) * (select_delta == 1) - ( select_delta == -1) for y in range(y_start, y_end, select_delta * 2): for x in range(x_start, x_end, select_delta * 2): if lvl.meanings[lvl.level[y][x]] == "McTrollald": lvl.selected_spell_target = (x, y) display.display_selected_target( lvl.selected_spell_target) return None x_start = (len(lvl.level[0]) - 1) * (select_delta == -1) + select_delta elif control[input] == "do action": # Effet du sort balai if spell == "balai": lvl.deactive_hourglass.remove(target) utk.efface("X_" + str(target[0]) + "_" + str(target[1])) display.efface_selected_target() spell_end_use() # Effet du sort grenouille if spell == "grenouille": target_id = lvl.pion_pos.index(target) lvl.pion_name[target_id] = "grenouille_" + lvl.pion_name[ target_id].split("_")[1] if lvl.selected_pion[p] == target_id: lvl.selected_pion[p] += 1 display.display_pion(target_id) spell_end_use() # Effet du sort echange if spell == "echange": target_id = lvl.get_index_pion_pos(target) if len(lvl.move_pion) == 0: lvl.move_pion.append(target_id) display.display_selected_target_confirmed(target) else: lvl.move_pion.append(target_id) lvl.pion_pos[lvl.move_pion[0]], lvl.pion_pos[ lvl.move_pion[1]] = lvl.pion_pos[ lvl.move_pion[1]], lvl.pion_pos[lvl.move_pion[0]] for pion in lvl.move_pion: display.display_pion(pion) spell_end_use() # Effet du sort teleportation if spell == "teleportation": target_id = lvl.get_index_pion_pos(target) if len(lvl.move_pion) == 0: lvl.move_pion.append(target_id) display.display_selected_target_confirmed(target) elif check_collision(target, target) and check_guard( lvl.pion_name[lvl.move_pion[0]], target): lvl.pion_pos[lvl.move_pion[0]] = target display.display_pion(lvl.move_pion[0]) spell_end_use() # Effet du sort appat if spell == "appat": if len(lvl.move_pion) == 0: target_id = lvl.get_index_pion_pos(target) lvl.move_pion.append(target_id) display.display_selected_target_confirmed(target) for y in range(len(lvl.level)): for x in range(len(lvl.level[y])): if lvl.meanings[lvl.level[y][x]] == "McTrollald": lvl.selected_spell_target = (x, y) display.display_selected_target( lvl.selected_spell_target) return None else: lvl.pion_pos[lvl.move_pion[0]] = target lvl.eating = lvl.pion_name[lvl.move_pion[0]] display.display_pion(lvl.move_pion[0]) spell_end_use() elif input in ("Up", "Down", "Left", "Right" ) and spell == "teleportation" and len(lvl.move_pion) != 0: vec_move_x = (input == "Right") * 2 - (input == "Left") * 2 vec_move_y = (input == "Down") * 2 - (input == "Up") * 2 new_pos = (target[0] + vec_move_x, target[1] + vec_move_y) if 0 <= new_pos[1] < len(lvl.level) and 0 <= new_pos[0] < len( lvl.level[0]): lvl.selected_spell_target = new_pos display.display_selected_target(lvl.selected_spell_target)