def avancer_minotaure(minotaures: list, joueur: list, murs: list, carte: list, can, liste_image: list): """ Fonction permettant de faire avancer le(s) minotaure(s) grâce à l'algorithme de pathfinding. Suivant le niveau de difficulté, le minotaure va avancer d'un certain nombre de cases vers le joueur. Si le joueur est trop proche, celui-ci est éliminé. :param minotaures: La liste de minotaure :param joueur: La liste contenant le joueur :param murs: La liste contenant les murs :param carte : La liste de liste formant la grille du jeu :param can: Canvas (ignorez son fonctionnement), utile uniquement pour créer_image() :param liste_image : Liste contenant les références sur les images """ # Création des variables de coordonés du minautore x_minotaure: int = minotaures[0].x y_minotaure: int = minotaures[0].y # Création des variables de coordonés du minautore x_joueur: int = joueur[0].x y_joueur: int = joueur[0].y # Création des variables contenant l'emplacement initial du minautore et l'emplacement final (les coordonés initiale du joueur) start: list = [x_minotaure, y_minotaure] end: list = [x_joueur, y_joueur] # Création des prochaines coordonés du minautore. next_minotaure_x: int = 0 next_minotaure_y: int = 0 # Appele la fonction fournie dans outils.py qui va définir le chemin le plus court selon le niveau. newPath: list = pathfinder.search(murs, carte, 1, start, end) # Boucle parcourant les listes de liste et les listes for index, i in enumerate(newPath): # Si on trouve un chemin possible dans la liste, update les prochaines coordonés du minautore NIVEAU_DIFFICULTE = nombre de case parcourue par le minotaure if NIVEAU_DIFFICULTE in i: next_minotaure_x = i.index(NIVEAU_DIFFICULTE) next_minotaure_y = index # Si le joueur n'est pas a l'emplacement du déplacement du minotaure, avance le minotaure normalement. if any(NIVEAU_DIFFICULTE in line for line in newPath): minotaures.clear() minotaures.append(creer_personnage(next_minotaure_x, next_minotaure_y)) creer_image(can, x_minotaure, y_minotaure, liste_image[6]) # Sinon, se déplace a l'emplacement du joueur et le tue. else: minotaures.clear() global joueur_mort joueur_mort = True joueur.clear() minotaures.append(creer_personnage(x_joueur, y_joueur)) creer_image(can, x_minotaure, y_minotaure, liste_image[6])
def charger_niveau(joueur, caisses, cibles, murs, path): ''' Fonction permettant de charger depuis un fichier.txt et de remplir les différentes listes permettant le fonctionnement du jeu (joueur, caisses, murs, cibles) :param joueur: liste des personnages :param caisses: liste des caisses :param cibles: liste des cibles :param murs: liste des murs :param path: Chemin du fichier.txt :return: ''' listeEndroitsVides: list = [] fichier = open(path, 'r') lignes: list = fichier.readlines() cptLigne: int = 0 for ligne in lignes: y: int = int(Y_PREMIERE_CASE + DISTANCE_ENTRE_CASE / 2 + cptLigne * 32) cptColonnes: int = 0 for caractere in ligne: x: int = int(X_PREMIERE_CASE + DISTANCE_ENTRE_CASE / 2 + cptColonnes * 32) if caractere == '#': murs.append(creer_mur(x, y)) elif caractere == '@': joueur.append(creer_personnage(x, y)) elif caractere == '.': cibles.append(creer_cible(x, y)) elif caractere == '$': caisses.append(creer_caisse(x, y)) elif caractere == '-': listeEndroitsVides.append(creer_case_vide(x, y)) cptColonnes += 1 cptLigne += 1 fichier.close()
def charger_niveau(joueur: list, caisses: list, cibles: list, murs: list, path: str): """ Fonction permettant de charger depuis un fichier.txt et de remplir les différentes listes permettant le fonctionnement du jeu (joueur, caisses, murs, cibles) :param joueur: liste des personnages :param caisses: liste des caisses :param cibles: liste des cibles :param murs: liste des murs :param path: chemin du fichier.txt :return: """ # Lecture des lignes du fichier et stockage dans une matrice 2D x:y telle que 9:6 mx = [] cases_vides = [] x = y = 0 with open(path, 'r') as file_level: mx = file_level.readlines() mx = [row.rstrip('\n') for row in mx] # Recherche les differents éléments dans la matrice et crée l'image correspondante sur le board selon les fonctions outils données for i in range(len(mx)): x = int(X_PREMIERE_CASE + DISTANCE_ENTRE_CASE / 2 + i * 32) for j in range(len(mx[i])): y = int(Y_PREMIERE_CASE + DISTANCE_ENTRE_CASE / 2 + j *32) if mx[i][j] == '#': # Mur murs.append(creer_mur(x,y)) elif mx[i][j] == '-': # Case_vide cases_vides.append(creer_case_vide(x,y)) elif mx[i][j] == '.': # Cible cibles.append(creer_cible(x,y)) elif mx[i][j] == '$': # Caisse caisses.append(creer_caisse(x,y)) elif mx[i][j] == '@': # Personnage joueur.append(creer_personnage(x,y))
def effectuer_mouvement(coordonnee_destination, minotaures: list, murs: list, joueur: list, sorties: list, carte: list, can, liste_image: list, deplace_joueur_x: int, deplace_joueur_y: int): """ Fonction permettant d'effectuer le déplacement ou de ne pas l'effectuer si celui-ci n'est pas possible. Voir énoncé "Quelques règles". ----------Cette methode est appelée par mouvement.-------------- :param coordonnee_destination: variable CaseVide ayant possiblement des coordonnées identiques à une autre variable (murs, minotaure, casevide) :param minotaures: liste des minotaures :param murs: liste des murs :param joueur: liste des joueurs :param sorties: Liste des sorties :param carte: La liste de liste formant la grille du jeu :param can: Canvas (ignorez son fonctionnement), utile uniquement pour créer_image() :param liste_image: Liste contenant les références sur les images :param deplace_joueur_x: coordonnée en x à laquelle le joueur va être après le mouvement :param deplace_joueur_y: coordonnée en y à laquelle le joueur va être après le mouvement """ # Si la destination est un mur, fait avancer le minotaure. if coordonnee_destination in murs: avancer_minotaure(minotaures, joueur, murs, carte, can, liste_image) # Sinon, avance le joueur a la nouvelle destination else: # Supprime l'ancien dessin du joueur joueur.clear() # Si la destination n'est pas la sortie, avance l'image du joueur if coordonnee_destination not in sorties: joueur.append(creer_personnage(deplace_joueur_x, deplace_joueur_y)) # Si l'emplacement du joueur est la meme que celle du minotaure, tue le joueur et termine la partie. if deplace_joueur_x == minotaures[0].x and deplace_joueur_y == minotaures[0].y: joueur.clear() global joueur_mort joueur_mort = True
def effectuer_mouvement(coordonnee_destination, coordonnee_case_suivante, ancienne_caisse, caisses: list, murs: list, joueur: list, can, deplace_caisse_x: int, deplace_caisse_y: int, deplace_joueur_x: int, deplace_joueur_y: int, liste_image: list): """ Fonction permettant d'effectuer le déplacement ou de ne pas l'effectuer si celui-ci n'est pas possible. Voir énoncé "Quelques règles". Cette methode est appelée par mouvement. :param coordonnee_destination: variable CaseVide ayant possiblement des coordonnées identiques à une autre variable (murs, caisse, casevide) :param coordonnee_case_suivante: variable CaseVide ayant possiblement des coordonnées identiques à une autre variable (murs, caisse, casevide) mais représente la case après coordonnee_destination :param ancienne_caisse: variable utile pour supprimer l'ancienne caisse (après avoir déplacé celle-ci) :param caisses: liste des caisses :param murs: liste des murs :param joueur: liste des joueurs :param can: Canvas (ignorez son fonctionnement), utile uniquement pour créer_image() :param deplace_caisse_x: coordonnée à laquelle la caisse va être déplacée en x (si le joueur pousse une caisse) :param deplace_caisse_y: coordonnée à laquelle la caisse va être déplacée en y (si le joueur pousse une caisse) :param deplace_joueur_x: coordonnée en x à laquelle le joueur va être après le mouvement :param deplace_joueur_y: coordonnée en y à laquelle le joueur va être après le mouvement :param liste_image: liste des images (murs, caisses etc...) détaillée dans l'énoncé :return: """ if coordonnee_destination in caisses: if coordonnee_case_suivante in caisses or coordonnee_case_suivante in murs: pass else: player_x: int = coordonnee_x(joueur[0]) player_y: int = coordonnee_y(joueur[0]) joueur.append(creer_personnage(deplace_joueur_x, deplace_joueur_y)) creer_image(can, player_x, player_y, liste_image[6])
def effectuer_mouvement(coordonnee_destination, coordonnee_case_suivante, ancienne_caisse, caisses, murs, joueur, can, deplace_caisse_x, deplace_caisse_y, deplace_joueur_x, deplace_joueur_y, liste_image): ''' Fonction permettant d'effectuer le déplacement ou de ne pas l'effectuer si celui-ci n'est pas possible. Voir énoncé "Quelques règles". Cette methode est appelée par mouvement. :param coordonnee_destination: variable CaseVide ayant possiblement des coordonnées identiques à une autre variable (murs, caisse, casevide) :param coordonnee_case_suivante: variable CaseVide ayant possiblement des coordonnées identiques à une autre variable (murs, caisse, casevide) mais représente la case après coordonnee_destination :param ancienne_caisse: variable utile pour supprimer l'ancienne caisse (après avoir déplacé celle-ci) :param caisses: liste des caisses :param murs: liste des murs :param joueur: liste des joueurs :param can: Canvas (ignorez son fonctionnement), utile uniquement pour créer_image() :param deplace_caisse_x: coordonnée à laquelle la caisse va être déplacée en x (si le joueur pousse une caisse) :param deplace_caisse_y: coordonnée à laquelle la caisse va être déplacée en y (si le joueur pousse une caisse) :param deplace_joueur_x: coordonnée en x à laquelle le joueur va être après le mouvement :param deplace_joueur_y: coordonnée en y à laquelle le joueur va être après le mouvement :param liste_image: liste des images (murs, caisses etc...) détaillée dans l'énoncé :return: ''' if coordonnee_destination in murs: # si un mur alors je bouge pas pass elif coordonnee_destination in caisses: if coordonnee_case_suivante in caisses or coordonnee_case_suivante in murs: # si double caisse alors je bouge pas pass else: for c in caisses: if est_egal_a(c, ancienne_caisse): caisses.remove(c) joueur.append(creer_personnage(deplace_joueur_x, deplace_joueur_y)) ancien_joueur = joueur.pop(0) creer_image(can, coordonnee_x(ancien_joueur), coordonnee_y(ancien_joueur), liste_image[6]) caisses.append(creer_caisse(deplace_caisse_x, deplace_caisse_y)) else: joueur.append(creer_personnage(deplace_joueur_x, deplace_joueur_y)) ancien_joueur = joueur.pop(0) creer_image(can, coordonnee_x(ancien_joueur), coordonnee_y(ancien_joueur), liste_image[6])
def charger_niveau(carte: list, joueur: list, minotaures: list, sorties: list, murs: list, path: str): """ Fonction permettant de charger depuis un fichier.txt et de remplir les différentes listes permettant le fonctionnement du jeu (joueur, minotaures, murs, sorties) :param carte: liste de liste comportant toutes les entités (joueur, minotaures, murs, sorties). C'est la grille du jeu. :param joueur: liste contenant le joueur :param minotaures: liste des minotaures :param sorties: liste des sorties :param murs: liste des murs :param path: chemin du fichier.txt """ global joueur_mort joueur_mort = False # Ouverture du fichier. (level1,2,3.txt) with open(path, "r") as level: # Initialisation des variables nécessaires x: int = 0 y: int = 0 count: int = 0 # Recupueré toutes les lignes differentes grace au readline. texte = level.read() lignes = texte.split() # Prendre les lignes une par une for ligne in lignes: carte.append(list(ligne)) # prendre les characteres 1 par 1. for char in ligne: if char == "#": murs.append(creer_mur(x, y)) elif char == "$": minotaures.append(creer_minotaure(x, y)) elif char == "@": joueur.append((creer_personnage(x, y))) elif char == ".": sorties.append((creer_sortie(x, y))) x += 1 count += 1 # Incrémenter Y et remettre X a 0 quand on arrive a la fin de la ligne if count % len(ligne) == 0: x = 0 y += 1
def charger_niveau(joueur, caisses, cibles, murs, path): ''' Fonction permettant de charger depuis un fichier.txt et de remplir les différentes listes permettant le fonctionnement du jeu (joueur, caisses, murs, cibles) :param joueur: liste des personnages :param caisses: liste des caisses :param cibles: liste des cibles :param murs: liste des murs :param path: Chemin du fichier.txt :return: ''' # Vérification des paramètres if not os.path.isfile(path): return None elif joueur is None or caisses is None or cibles is None or murs is None: return None # Variables de départ c_dpt_x: int = DISTANCE_ENTRE_CASE // 2 c_dpt_y: int = DISTANCE_ENTRE_CASE // 2 # Déclaration de la coordonnée Y coord_y: int = Y_PREMIERE_CASE + c_dpt_y # Overture du fichier en mode lecture with open(path, 'r') as filin: # Lecture de chaque ligne du fichier for ligne in filin: # Calibrage des coordonnees X et Y coord_x = X_PREMIERE_CASE + c_dpt_x # Lecture et création de chaque élément de la ligne for element in ligne: if element == '#': murs.append(creer_mur(coord_x, coord_y)) elif element == '.': cibles.append(creer_cible(coord_x, coord_y)) elif element == '$': caisses.append(creer_caisse(coord_x, coord_y)) elif element == '@': joueur.append(creer_personnage(coord_x, coord_y)) # Calibrage de la coordonnée X à chaque intéraction coord_x = coord_x + DISTANCE_ENTRE_CASE # Calibrage de la coordonée Y a chaque intéraction coord_y = coord_y + DISTANCE_ENTRE_CASE
def charger_niveau(joueur, caisses, cibles, murs, path): ''' Fonction permettant de charger depuis un fichier.txt et de remplir les différentes listes permettant le fonctionnement du jeu (joueur, caisses, murs, cibles) :param joueur: liste des personnages :param caisses: liste des caisses :param cibles: liste des cibles :param murs: liste des murs :param path: Chemin du fichier.txt :return: ''' cpt_x: int = 0 cpt_y: int = 0 with open(path, "r") as filin: lignes: list = filin.readlines() for i in lignes: for j in i: if j == "#": # faire deux boucles imbriqués, 20, 20 est la position initiale un for pour x et un for pour y # 32 étant l'espace entre deu éléments. 20 + 0 * 32 /// 20 étant l'espace entre le fichier texte et le premier bloc # du coup 20 et 32 reste il n'y a juste le 0 qui va varier murs.append(creer_mur(X_PREMIERE_CASE + (DISTANCE_ENTRE_CASE * cpt_x), Y_PREMIERE_CASE + (DISTANCE_ENTRE_CASE * cpt_y))) elif j == ".": cibles.append(creer_cible(X_PREMIERE_CASE + (DISTANCE_ENTRE_CASE * cpt_x), Y_PREMIERE_CASE + (DISTANCE_ENTRE_CASE * cpt_y))) elif j == "$": caisses.append(creer_caisse(X_PREMIERE_CASE + (DISTANCE_ENTRE_CASE * cpt_x), Y_PREMIERE_CASE + (DISTANCE_ENTRE_CASE * cpt_y))) elif j == "@": joueur.append(creer_personnage(X_PREMIERE_CASE + (DISTANCE_ENTRE_CASE * cpt_x), Y_PREMIERE_CASE + (DISTANCE_ENTRE_CASE * cpt_y))) cpt_x += 1 cpt_y += 1 cpt_x = 0
def effectuer_mouvement(coordonnee_destination, coordonnee_case_suivante, ancienne_caisse, caisses, murs, joueur, can, deplace_caisse_x, deplace_caisse_y, deplace_joueur_x, deplace_joueur_y, liste_image): ''' Fonction permettant d'effectuer le déplacement ou de ne pas l'effectuer si celui-ci n'est pas possible. Voir énoncé "Quelques règles". Cette methode est appelée par mouvement. :param coordonnee_destination: variable CaseVide ayant possiblement des coordonnées identiques à une autre variable (murs, caisse, casevide) :param coordonnee_case_suivante: variable CaseVide ayant possiblement des coordonnées identiques à une autre variable (murs, caisse, casevide) mais représente la case après coordonnee_destination :param ancienne_caisse: variable utile pour supprimer l'ancienne caisse (après avoir déplacé celle-ci) :param caisses: liste des caisses :param murs: liste des murs :param joueur: liste des joueurs :param can: Canvas (ignorez son fonctionnement), utile uniquement pour créer_image() :param deplace_caisse_x: coordonnée à laquelle la caisse va être déplacée en x (si le joueur pousse une caisse) :param deplace_caisse_y: coordonnée à laquelle la caisse va être déplacée en y (si le joueur pousse une caisse) :param deplace_joueur_x: coordonnée en x à laquelle le joueur va être après le mouvement :param deplace_joueur_y: coordonnée en y à laquelle le joueur va être après le mouvement :param liste_image: liste des images (murs, caisses etc...) détaillée dans l'énoncé :return: ''' # Vérification des paramètres if caisses is None or murs is None or joueur is None or deplace_caisse_x is None or deplace_caisse_y is None \ or deplace_joueur_x is None or deplace_joueur_y is None or liste_image is None: return None # Booléens pour connaître la "nature" de la case destination ou la case qui suit la case destination case_dest_mur: bool = False case_suiv_mur: bool = False case_dest_caisse: bool = False case_suiv_caisse: bool = False for elt in murs: if est_egal_a(elt, coordonnee_destination): case_dest_mur = True break for elt in murs: if est_egal_a(elt, coordonnee_case_suivante): case_suiv_mur = True break for elt in caisses: if est_egal_a(elt, coordonnee_destination): case_dest_caisse = True break for elt in caisses: if est_egal_a(elt, coordonnee_case_suivante): case_suiv_caisse = True break # Selon les résultats obtenus plus haut, autorise le déplacement et fait les changements nécessaires sur les cases "touchées" if not case_dest_mur: if not (case_dest_caisse and (case_suiv_caisse or case_suiv_mur)): if case_dest_caisse: creer_image(can, deplace_caisse_x, deplace_caisse_y, liste_image[2]) caisses.remove(ancienne_caisse) caisses.append(creer_caisse(deplace_caisse_x, deplace_caisse_y)) creer_image(can, coordonnee_x(joueur[0]), coordonnee_y(joueur[0]), liste_image[6]) joueur[0] = creer_personnage(deplace_joueur_x, deplace_joueur_y) else: creer_image(can, coordonnee_x(joueur[0]), coordonnee_y(joueur[0]), liste_image[6]) joueur[0] = creer_personnage(deplace_joueur_x, deplace_joueur_y)