#!/usr/bin/env python3 import random, time N = 0 E = 1 S = 2 O = 3 ## Gestion de partie def créer_salle_random(): """ Créer une salle aléatoire @params void @return une salle, tuple de taille 4 """ res0 = True if random.random() * 100 > 50 else False res1 = True if random.random() * 100 > 50 else False res2 = True if random.random() * 100 > 50 else False res3 = True if random.random() * 100 > 50 else False return (res0, res1, res2, res3) def créer_dragon(pos): """ Créer un dragon dans la salle @pos @params pos, un tuple @return un dragon, dictionnaire """ niveau = 0 while niveau == 0: niveau = int(random.random() * 20) for dragon in dragons: if dragon["niveau"] == niveau: niveau = 0 break return { 'position' : pos, 'niveau' : niveau } def peupler_donjon(donjon, dragons): """ Créer l'état initial du donjon au début du jeu @params void @return void """ donjon.clear() dragons.clear() for i in range(TAILLE_DONJON): ligne = [] for j in range(TAILLE_DONJON): ligne.append(créer_salle_random()) if random.random() * 100 > 75: # 25% de chance dragons.append(créer_dragon((i,j))) donjon.append(ligne) def pivoter_donjon(donjon, position): """ Pivote la salle pointée par @position dans @donjon @params donjon, une liste contenant des salles position, un tuple identifiant une salle @return void """ x = position[0] y = position[1] donjon[x][y] = tuple([donjon[x][y][-1]] + list(donjon[x][y][:-1])) def connecte(donjon, pos0, pos1): """ Vérifie que les salles pointées par @pos0 et @pos1 dans @donjon sont adjacentes et connectées @params donjon, une liste contenant des salles pos0, un tuple identifiant une salle pos1, un tuple identifiant une salle @return booléen """ x0 = pos0[0] y0 = pos0[1] x1 = pos1[0] y1 = pos1[1] # On vérifie les limites if x0 < 0 or y0 < 0 or x1 < 0 or y1 < 0: return False if x0 >= len(donjon) or y0 >= len(donjon) or x1 >= len(donjon) or y1 >= len(donjon): return False # Calcul des distances axe0 = x0 - x1 axe1 = y0 - y1 distance = abs(axe0) + abs(axe1) # Vérifier l'adjacence if distance > 1: return False # Chercher point de connexion if axe1 == 0: if axe0 <= -1: # le pôle sud de pos1 touche le pôle nord de pos0 if donjon[x1][y1][S] and donjon[x0][y0][N]: return True elif axe0 >= 1: # le pôle sud de pos0 touche le pôle nord de pos1 if donjon[x0][y0][S] and donjon[x1][y1][N]: return True else: if axe1 <= -1: # le pôle est de pos1 touche le pôle ouest de pos0 if donjon[x1][y1][E] and donjon[x0][y0][O]: return True elif axe1 >= 1: # le pôle est de pos0 touche le pôle ouest de pos1 if donjon[x0][y0][E] and donjon[x1][y1][O]: return True return False def calcul_chemin(donjon, position, dragons, visite): """ Support récursif pour intention @params donjon, une liste contenant des salles position, un tuple identifiant une salle (dans laquelle l'aventurier se trouve) dragons, une liste de dragons @return booléen """ résultats = [] # Déjà visité if position in visite: return None else: visite.add(position) # Cas de base for dragon in dragons: if position == dragon["position"]: return ([position], dragon["niveau"]) # Test récursif des potentielles connexions x, y = position if connecte(donjon, position, (x+1,y)): résultats.append(calcul_chemin(donjon, (x+1,y), dragons, visite)) if connecte(donjon, position, (x-1,y)): résultats.append(calcul_chemin(donjon, (x-1,y), dragons, visite)) if connecte(donjon, position, (x,y+1)): résultats.append(calcul_chemin(donjon, (x,y+1), dragons, visite)) if connecte(donjon, position, (x,y-1)): résultats.append(calcul_chemin(donjon, (x,y-1), dragons, visite)) # Aucun couple dans résultats if résultats == [None] * len(résultats): return None else: niveau = 0 candidat = (0,0) for couple in résultats: if couple is None: continue if couple[1] > niveau: niveau = couple[1] candidat = (couple[0], couple[1]) return ([position] + candidat[0], candidat[1]) def intention(donjon, position, dragons): """ Calcule récursivement le chemin à parcourir jusqu'à un dragon du plus haut niveau accessible @params donjon, une liste contenant des salles position, un tuple identifiant une salle (dans laquelle l'aventurier se trouve) dragons, une liste de dragons @return liste, chemin à parcourir """ visite = set() return calcul_chemin(donjon, position, dragons, visite) def rencontre(aventurier, dragons): """ Vérifie si l'@aventurier est à la même position qu'un dragon de @dragons et agit en conséquence @params aventurier, dictionnaire représentant un aventurier dragons, liste de dragons (dictionnaires) @return void """ versus = False ennemi = None for dragon in dragons: if aventurier["position"] == dragon["position"]: versus = True ennemi = dragon # Un dragon sauvage apparaît ! if versus: if ennemi["niveau"] <= aventurier["niveau"]: # Victoire dragons.remove(ennemi) aventurier["niveau"] = aventurier["niveau"] + 1 else: # Décès aventurier["vivant"] = False def appliquer_chemin(aventurier, dragons, chemin): """ déplace l'aventurier @return rien """ ([(2, 1), (2, 0)], 16) position = chemin[0][0] chemin[0].remove(position) aventurier["position"] = position rencontre(aventurier, dragons) def fin_partie(aventurier, dragons): """ @return 1 si la partie est gagnée (tous les dragons ont été tués), -1 si la partie est perdue (l’aventurier a été tué), 0 si la partie continue. """ if len(dragons) == 0: return 1 elif not aventurier["vivant"]: return -1 else: return 0