1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296
| # -*- coding: utf-8 *-*
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# (un peu inspiré des règles D20)
# V0.9 - maj 06/08/2012
# dernière modif : refonte du system de perso
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
import time
import random
import bisect # utilisé dans Rencontre_aleatoire()
# from math import sqrt
class Perso():
"Création d'un perso"
def __init__(self, name = "lambda", Race = "humain", hp = 10, strength = 3, \
dext = 3, ca = 0, armure = 0, arme = "arme1", level = 1, xp = 0, Desc = "un humain"):
self.name = name
self.Race = Race # voir list.creatures()
self.hp = hp
self.strength = strength
self.dext = dext
self.ca = ca # sera calculé avec calcul_ca()
self.armure = armure
self.arme = arme # voir table_armes() de Item()
self.level = level # A FAIRE
self.xp = xp # A FAIRE
self.Desc = Desc # utilisé lors de print divers (à voir)
# chargemment des personnages via pickle -- A FAIRE
#nom de la créature : {Race,HP,Strength,Dextérité,CA,Armure,Arme,Level,XP,Decription}
self.liste_creatures = {\
"Karadoc": {"Race": "Humain", "hp": 50, "strength": 8, \
"dext": 2, "ca": 0, "armure": 5, "arme": 'arme3', \
"level": 1, "xp": 0, "Desc": "un humain"}, \
# -----------
"Perceval": {"Race": "Humain", "hp": 50, "strength": 8, \
"dext": 2, "ca": 0, "armure": 5, "arme": 'arme3', \
"level": 1, "xp": 0, "Desc": "un humain"}, \
# -----------
"Orc": {"Race": "Orc", "hp": 15, "strength": 4, \
"dext": 2, "ca": 0, "armure": 2, "arme": 'arme2', \
"level": 1, "xp": 0, "Desc": "un Orc"}, \
# -----------
"Sanglier": {"Race": "Sanglier", "hp": 20, "strength": 4, \
"dext": 2, "ca": 0, "armure": 2, "arme": 'arme4', \
"level": 1, "xp": 0, "Desc": "un sanglier"}, \
# -----------
"Vampire": {"Race": "Mort vivant", "hp": 30, "strength": 2, \
"dext": 5, "ca": 0, "armure": 0, "arme": 'arme5', \
"level": 1, "xp": 0, "Desc": "un vampire"}, \
# -----------
"Squelette": {"Race": "Mort vivant", "hp": 15, "strength": 5, \
"dext": 1, "ca": 0, "armure": 3, "arme": 'arme2', \
"level": 1, "xp": 0, "Desc": "un squelette"}, \
# -----------
"Elf franchement éfféminé": {"Race": "Elf", "hp": 18, "strength": 2, \
"dext": 6, "ca": 0, "armure": 2, "arme": 'arme1', \
"level": 1, "xp": 0, "Desc": "un elf franchement éfféminé"}, \
}
def calcul_ca(self):
# D20 : Permet de calculer la CA (classe d'armure)
# Sera utilié pour déterminer quelle puissance est nécessaire pour porter un coup
# 10 + Armure + Dextérité
self.ca = 10 + self.armure + self.dext
print "%s CA : %s" % (self.name, self.ca)
def donne_xp(self, ennemi_level):
# Ajoute de l'expérience au personnage - A FAIRE
#level = 500 * level * (level + 1)
pass
def level_up(self):
#Fait monter le personnage d'un niveau - A FAIRE
self.table_xp = {1: 0, 2: 100, 3: 500}
pass
def chargement_perso(self): # A supprimer
# on récupère la liste des personnages et monstres disponibles
self.liste_races = [] # contiendra les races disponibles
self.liste_choix_restreint = [] # n'autoriser que ces races à être utilisées
# On récupère la liste des personnages via pickle -- A faire
# on créé la liste de choix de races selon celles dispo
# et selon la restriction de la liste liste_choix_restreint[]
#for i in self.liste_creatures:
# if (self.liste_creatures[i]["Race"] not in self.liste_races):
# self.liste_races.append(self.liste_creatures[i]["Race"])
def creation_perso_rapide(self, nom):
# si utilisé avec Rencontre_aleatoire(), on vérifie que le nom de la créature
# rencontrée est valide. Il arrive qu'une rencontre aléatoire ne renvoit "personne"
# CAD que le joueur ne rencontre personne dans le lieu.
if nom != "personne":
# si le nom de la créature est valable, on lui donne les caractéristiques de liste_creatures{}:
# - Ajuster selon le niveau du joueur -- A FAIRE
self.name = nom
self.Race = self.liste_creatures[nom]["Race"]
self.hp = self.liste_creatures[nom]["hp"]
self.strength = self.liste_creatures[nom]["strength"]
self.dext = self.liste_creatures[nom]["dext"]
self.ca = self.liste_creatures[nom]["ca"]
self.armure = self.liste_creatures[nom]["armure"]
self.arme = self.liste_creatures[nom]["arme"]
self.level = self.liste_creatures[nom]["level"]
self.xp = self.liste_creatures[nom]["xp"]
self.Desc = self.liste_creatures[nom]["Desc"]
print "%s est apparu dans le monde" % (self.liste_creatures[nom]["Desc"])
else:
# pour débug
print "personne n'a été créé"
def creation_perso_assistant(self):
pass
class Item:
"A revoir, la logique etc"
def __init__(self):
self.table_armes = { \
'arme0': {'Nom': 'Mains nues', 'Desc': 'de poing', 'Poids': 0, 'Degats': 3, 'Cpt_privi': 'strength'}, \
'arme1': {'Nom': 'Dague', 'Desc': 'de dague', 'Poids': 500, 'Degats': 10, 'Cpt_privi': 'dext'}, \
'arme2': {'Nom': 'Rapière', 'Desc': 'de rapière', 'Poids': 1500, 'Degats': 20, 'Cpt_privi': 'strength'}, \
'arme3': {'Nom': 'Hache', 'Desc': 'de hache', 'Poids': 3000, 'Degats': 30, 'Cpt_privi': 'strength'}, \
'arme4': {'Nom': 'Défenses', 'Desc': 'de défenses', 'Poids': 0, 'Degats': 15, 'Cpt_privi': 'strength'}, \
'arme5': {'Nom': 'Canines', 'Desc': 'de canines', 'Poids': 0, 'Degats': 20, 'Cpt_privi': 'dext'} \
}
def donne_arme(self, perso, arme_id):
"Donne une arme au personnage - A travailler"
perso.arme = self.table_armes[arme_id]
def desc_arme(self, arme_id):
"Information concernant une arme - A travailler"
print "Arme : %s" % (self.table_armes[arme_id]['Nom'])
print "Description : %s" % (self.table_armes[arme_id]['Desc'])
print "Poids : %d %s" % (self.table_armes[arme_id]['Poids'], "Gr")
print "Dégats : 1d%d" % (self.table_armes[arme_id]['Degats'])
print "Compétance à privilégier : %s" % (self.table_armes[arme_id]['Cpt_privi'])
class Duel:
"Duel entre deux perso"
def __init__(self):
self.initiative = False
def calcul_init(self, perso1, perso2): # Calcul d'initiative'
# D20 : dext + jet 1d20
jet_perso1 = perso1.dext + random.randrange(1, 20)
jet_perso2 = perso2.dext + random.randrange(1, 20)
# un peu de texte histoire de décrire (pas certain que ce soit une bonne idée de placer ça là)
print "%s : %d dext" % (perso1.name, perso1.dext)
print " > le jet de dés donne une initiative de %s pour %s" %\
(jet_perso1, perso1.name)
print "%s : %d dext" % (perso2.name, perso2.dext)
print " > le jet de dés donne une initiative de %s pour %s" % (jet_perso2, perso2.name)
if jet_perso1 >= jet_perso2:
print "%s attaque le premier" % perso1.name
self.initiative = False # on bascule le switch pour déterminé qui a l'initiative (voir stdr_fight())
else:
print "%s attaque le premier" % (perso2.name)
self.initiative = True
def stdr_fight(self, perso1, perso2):
"Le combat en lui même"
# Tant que l'un des personnages est en vie
while (perso1.hp > 0) and (perso2.hp > 0):
time.sleep(2) # marque un temps de pause entre les pseudos tours
print "_____________________________________________"
# on vérifie le switch initiative pour savoir qui attaque
if self.initiative == False:
self.attaque(perso1, perso2)
self.initiative = True # on bascule le switch, permet au second perso d'attaquer
else:
self.attaque(perso2, perso1)
self.initiative = False
if (perso1.hp <= 0): # si l'un des perso n'a plus de points de vie
self.victoire(perso2, perso1) # on lance victoire()
elif (perso2.hp <= 0):
self.victoire(perso1, perso2)
def attaque(self, attaquant, defenseur):
"Permet de déterminé si le coup porte"
puiss_attaqu = 0 # variable qui contient la puissance de l'attaque
print "%s donne un coup %s à %s" % (attaquant.name, attaquant.arme['Desc'], defenseur.name, )
# On calcul l'attaque via jet_attaque()
puiss_attaqu = self.jet_attaque(attaquant)
# on vérifie que la CA est dépassée par l'attaque (puiss_attaqu)
if puiss_attaqu >= defenseur.ca:
# Puis on retire les pts de vie selon le calcul effectué par jet_degat()
defenseur.hp -= self.jet_degats(attaquant)
if defenseur.hp > 0: # si le def est en vie
print " > %s perd %d points de vie. %d restants" %\
(defenseur.name, puiss_attaqu, defenseur.hp)
else: # Si non, on change le message en indiquant la mort du perso
print " > %s perd %d points de vie et s'écroule sur le sol" % (defenseur.name, puiss_attaqu)
else: # dans le cas ou le coup porté manque la cible (cad si puiss_attaqu < defenseur.ca)
print " > Le coup manque la cible. Jet d'attaque : %d |" \
" CA de la cible : %d" % (puiss_attaqu, defenseur.ca)
def jet_attaque(self, perso):
# Calcul du jet d'attaque
# ~D20 : 1d20 + force + dextérité
return random.randrange(1, 20) + perso.strength + perso.dext
def jet_degats(self, perso):
# Calcul du jet de dégats
# ~D20 : dégats = Degats(1,?) + Cpt_privi + Poids(poids_conv())
# ---------------------------solution temporaire au bonus Cpt_privi
perso_cpt = perso.arme['Cpt_privi']
if perso.arme['Cpt_privi'] == 'dext':
perso_cpt = perso.dext
else:
perso_cpt = perso.strength
# ---------------------------/solution temporaire au bonus Cpt_privi
return random.randrange(1, perso.arme['Degats']) + perso_cpt +\
self.poids_conv(perso.arme['Poids'])
def poids_conv(self, poids):
"Tableau de convertion poids-Malus/Bonus"
table_poids = {0: 0, 500: +1, 1500: -2, 3000: -4}
return table_poids[poids]
def victoire(self, vainqueur, perdant):
print "__________________Fin du duel_________________"
# Simple message indiquant le gagnant
print "%s remporte le combat" % (vainqueur.name)
print "%s a %d points de vie restants" % (vainqueur.name, vainqueur.hp)
class Rencontre_aleatoire():
"Permet de simuler une rencontre avec une créature aléatoirement choisie selon le lieu"
def __init__(self):
# On récupère les infos via pickle - A FAIRE
# -- Comment est construit le dict "lieux" : --
# Dict1 : chaque lieu est référencé de la sorte Lieu1, Lieu2 etc
# Chaque Lieu contient un dict,
# entrée Nom = Nom du lieu
# entrée Desc = La description du lieu (pas encore utilisée)
# entrée Monstres = contient un tuple
#chaque item du tuple contient une liste elle même ayant 2 items
# item 0 = Nom de la créature, permet de renvoyer à la liste des attributs, pour le combat
# item 1 = le poids du montsre, utilisé pour calculer la prob de renctr, voir calcul_rencontre()
#... parait un peu lourd, pas mieux pour le moment
self.lieux = {\
"Lieu1": {"Nom": "Plaine", "Desc": "une plaine verdoyante", \
"Monstres": [("personne", 3),("Sanglier", 5), ("Orc", 4), ("Elf franchement éfféminé",1)]},\
#-----------
"Lieu2": {"Nom": "Donjon", "Desc": "un donjon sombre et humide", "Monstres": [("personne", 1),("Squelette", 6), ("Vampire", 3)]} \
}
def aff_infos_lieu(self, lieu):
# affiche simplement les détails concernant le lieu, et les rencontres possibles
# voir le problème d'encodage avec espaces/accents
print "Lieu : %s" % (lieu)
print self.lieux[lieu]["Nom"]
print self.lieux[lieu]["Monstres"]
def calcul_rencontre(self, nom_perso, lieu, objet):
# "lieu" correspond à un des lieux de lieux[] dans Rencontre_aleatoire(), objet désigne soit "Monstres" (voir liste_creatures dans Perso())
# soit un type de lieu "emplacement"(voir lieux [] dans Rencontre_aleatoire() (A FAIRE... ou pas)
# nom_perso sera utilisé pour créer un ennemi de niveau équivalent (ou presque) au perso -- A FAIRE
# Permet de sortir une créature au hasard selon son poids (voir lieux[])
# afficher le poids...................self.lieux[lieu]["Monstres"][x][1]
# afficher le nom de la créature......self.lieux[lieu]["Monstres"][x][0]
# afficher tous les monstres et poids.self.lieux[lieu]["Monstres"]
self.total = 0 # contiendra le total des poids
self.liste_poids = [] # liste contenant LES totaux des poids
for i in self.lieux[lieu][objet]: # On récupère les poids des monstres
self.total += i[1] # on ajoute le poids sélectionné au total
self.liste_poids.append(self.total) # on append le total en cours à la liste
#---------------------------------------- v Bien meilleur méthode a étudier, OK
alea = random.random() * self.liste_poids[-1]
i = bisect.bisect_right(self.liste_poids, alea)
#print "%s rencontre %s dans %s" % (nom_perso, \
#self.lieux[lieu]["Monstres"][i][0], self.lieux[lieu]["Nom"])
return self.lieux[lieu][objet][i][0] # sort le montre à créer -- Voir pour selec équipement et niveau
ennemi = Perso()
perso1 = Perso()
crea_item = Item()
aventure = Rencontre_aleatoire()
perso1.creation_perso_rapide("Karadoc")
crea_item.donne_arme(perso1, "arme1")
ennemi.creation_perso_rapide(aventure.calcul_rencontre("Karadoc", "Lieu2", "Monstres"))
if ennemi.name is not "lambda": # utilisé pour éviter un bug lorsque la rencontre renvoit "personne"
crea_item.donne_arme(ennemi, ennemi.arme)
perso1.calcul_ca()
ennemi.calcul_ca()
cmb1 = Duel()
cmb1.calcul_init(perso1, ennemi)
cmb1.stdr_fight(perso1, ennemi) |
Partager