250 lines
6.7 KiB
Python
250 lines
6.7 KiB
Python
#!/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
|