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 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379
|
# -*- coding: utf-8 *-*
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# (un peu inspiré des règles D20)
# V0.9 - maj 12/08/2012
# dernière modif : localisation_perso()
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
import time
import random
import bisect # utilisé dans Rencontre_aleatoire()
from math import sqrt # utilisé pour localisation_perso()
import turtle # A supprimer - Tester visuellement la localisation du perso
# import pickle # utilisé pour Perso() Item() et Rencontres_aleatoires()
class Perso:
"Personnages"
# Dict contenant les créatures et personnages
liste_creatures = {\
"Gerald de Rive": {"race": "Sorceleur", "hp": 45, "strength": 6, \
"dext": 5, "perception": 8,"ca": 0, "armure": 5, "arme": 'arme2', \
"niveau": 1, "xp": 0, "description": "un sorceleur", "Coord_x": 10, "Coord_y": 19}, \
# -----------
"Karadoc": {"race": "Humain", "hp": 50, "strength": 8, \
"dext": 2, "perception": 8, "ca": 0, "armure": 5, "arme": 'arme3', \
"niveau": 1, "xp": 0, "description": "un humain", "Coord_x": 28, "Coord_y": 120}, \
# -----------
"Perceval": {"race": "Humain", "hp": 50, "strength": 8, \
"dext": 2, "perception": 8, "ca": 0, "armure": 5, "arme": 'arme3', \
"niveau": 1, "xp": 0, "description": "un humain", "Coord_x": 70, "Coord_y": 15}, \
# -----------
"Orc": {"race": "Orc", "hp": 15, "strength": 4, \
"dext": 2, "perception": 8, "ca": 0, "armure": 2, "arme": 'arme2', \
"niveau": 1, "xp": 0, "description": "un Orc", "Coord_x": 50, "Coord_y": 50}, \
# -----------
"Sanglier": {"race": "Sanglier", "hp": 20, "strength": 4, \
"dext": 2, "perception": 8, "ca": 0, "armure": 2, "arme": 'arme4', \
"niveau": 1, "xp": 0, "description": "un sanglier", "Coord_x": 50, "Coord_y": 50}, \
# -----------
"Vampire": {"race": "Mort vivant", "hp": 30, "strength": 2, \
"dext": 5, "perception": 8, "ca": 0, "armure": 0, "arme": 'arme5', \
"niveau": 1, "xp": 0, "description": "un vampire", "Coord_x": 50, "Coord_y": 50}, \
# -----------
"Squelette": {"race": "Mort vivant", "hp": 15, "strength": 5, \
"dext": 1, "perception": 8, "ca": 0, "armure": 3, "arme": 'arme2', \
"niveau": 1, "xp": 0, "description": "un squelette", "Coord_x": 50, "Coord_y": 50}, \
# -----------
"Elf franchement éfféminé": {"race": "Elf", "hp": 18, "strength": 2, \
"dext": 6, "perception": 8, "ca": 0, "armure": 2, "arme": 'arme1', \
"niveau": 1, "xp": 0, "description": "un elf franchement éfféminé", "Coord_x": 50, "Coord_y": 50}, \
}
def __init__(self, nom = "lambda", race = "humain", hp = 10, strength = 3, \
dext = 3, perception = 3, ca = 0, armure = 0, arme = "arme0", niveau = 1, xp = 0, \
description = "un humain", Coord_x = 0, Coord_y = 0):
self.nom = nom # Nom du personnage
self.race = race # voir list.creatures() - A faire
self.hp = hp # Points de vie
self.strength = strength # Force
self.dext = dext # Dextérité
self.perception = perception # Perception
self.ca = ca # sera calculé avec calcul_ca()
self.armure = armure # Armure - A faire
self.arme = arme # voir table_armes() de Item() A refaire
self.niveau = niveau # A FAIRE
self.xp = xp # A FAIRE
self.description = description # utilisé lors de print divers (à voir)
self.Coord_x = Coord_x # Coordonnées du perso - A voir pour les créatures
self.Coord_y = Coord_y # Coordonnées du perso
# chargemment des personnages via pickle -- A FAIRE
#nom de la créature : {race,HP,Strength,Dextérité, Percéption,CA,Armure,Arme,niveau,XP,Decription, X, Y}
def calcul_ca(self):
"Calculer la Classe d'Armure d'un personnage''"
# D20 : Permet de calculer la CA (classe d'armure)
# Sera utilisé 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.nom, self.ca)
def donne_xp(self, ennemi_niveau):
# Ajoute de l'expérience au personnage - A FAIRE
#niveau = 500 * niveau * (niveau + 1)
pass
def niveau_sup(self):
#Fait monter le personnage d'un niveau - A FAIRE
self.table_xp = {1: 0, 2: 100, 3: 500}
pass
def deplacement(self):
pass
def creation_perso_rapide(self, nom):
"Créér un personnage à partir de liste_creatures()"
# on lui donne les caractéristiques de liste_creatures{}:
# - Ajuster selon le niveau du joueur -- A FAIRE
self.nom = 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.perception = self.liste_creatures[nom]["perception"]
self.ca = self.liste_creatures[nom]["ca"]
self.armure = self.liste_creatures[nom]["armure"]
self.arme = self.liste_creatures[nom]["arme"]
self.niveau = self.liste_creatures[nom]["niveau"]
self.xp = self.liste_creatures[nom]["xp"]
self.description = self.liste_creatures[nom]["description"]
self.Coord_x = self.liste_creatures[nom]["Coord_x"]
self.Coord_y = self.liste_creatures[nom]["Coord_y"]
# A supprimer
print "%s est apparu dans le monde" % (self.liste_creatures[nom]["description"])
def creation_perso_assistant(self):
# A voir, surement renommé et utilisé pour le changement de niveau (donc changement de caractéristiques)
pass
class Item:
"A revoir, la logique etc"
def __init__(self):
self.table_armes = { \
'arme0': {'Nom': 'Mains nues', 'description': 'de poing', 'Poids': 0, 'Degats': 3, 'Cpt_privi': 'strength'}, \
'arme1': {'Nom': 'Dague', 'description': 'de dague', 'Poids': 500, 'Degats': 10, 'Cpt_privi': 'dext'}, \
'arme2': {'Nom': 'Rapière', 'description': 'de rapière', 'Poids': 1500, 'Degats': 20, 'Cpt_privi': 'strength'}, \
'arme3': {'Nom': 'Hache', 'description': 'de hache', 'Poids': 3000, 'Degats': 30, 'Cpt_privi': 'strength'}, \
'arme4': {'Nom': 'Défenses', 'description': 'de défenses', 'Poids': 0, 'Degats': 15, 'Cpt_privi': 'strength'}, \
'arme5': {'Nom': 'Canines', 'description': '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 description_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]['description'])
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.nom, perso1.dext)
print " > le jet de dés donne une initiative de %s pour %s" %\
(jet_perso1, perso1.nom)
print "%s : %d dext" % (perso2.nom, perso2.dext)
print " > le jet de dés donne une initiative de %s pour %s" % (jet_perso2, perso2.nom)
if jet_perso1 >= jet_perso2:
print "%s attaque le premier" % perso1.nom
self.initiative = False # on bascule le switch pour déterminé qui a l'initiative (voir stdr_fight())
else:
print "%s attaque le premier" % (perso2.nom)
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(1) # 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.nom, attaquant.arme['description'], defenseur.nom, )
# 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.nom, 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.nom, 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 conversion poids-Malus/Bonus"
table_poids = {0: 0, 500: +1, 1500: -2, 3000: -4}
return table_poids[poids]
def victoire(self, vainqueur, perdant):
"Fin du duel, distribution de l'xp et gain de niveau'"
# voir Perso.donne_xp() et Perso.niveau_sup():
print "__________________Fin du duel_________________"
# Simple message indiquant le gagnant
print "%s remporte le combat" % (vainqueur.nom)
print "%s a %d points de vie restants" % (vainqueur.nom, vainqueur.hp)
class Rencontre_aleatoire():
"Rencontre aléatoire avec une créature choisie selon le lieu"
# 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 description = La descriptionription 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()
# "Coord_x": x, "Coord_y": y, "Rayon":10 = Localisation et taille de la zone décrite.
#... parait un peu lourd, pas mieux pour le moment
lieux = {\
"Lieu1": {"Nom": "Plaine", "description": "une plaine verdoyante", \
"Monstres": [("Sanglier", 5), ("Orc", 4), ("Elf franchement éfféminé",1)], \
"Coord_x": 0, "Coord_y": 0, "Rayon": 30},\
#-----------
"Lieu2": {"Nom": "Forêt", "description": "une forêt", "Monstres": [("Squelette", 2), ("Sanglier", 5), ("Orc", 4)], \
"Coord_x": 20, "Coord_y": 70, "Rayon": 20},\
#-----------
"Lieu3": {"Nom": "Marai", "description": "un marai humide", "Monstres": [("Squelette", 6), ("Vampire", 3)], \
"Coord_x": 75, "Coord_y": 150, "Rayon": 64},\
#-----------
"Lieu4": {"Nom": "Village en ruine", "description": "un village en ruine", "Monstres": [("Squelette", 2), ("Sanglier", 1), ("Orc", 5)], \
"Coord_x": 40, "Coord_y": 40, "Rayon": 10},\
}
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):
"Sélectionne un objet ou une créature aléatoirement, selon le lieu"
# "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 créatures
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] # renvoit le monstre à créer -- Voir pour selec équipement et niveau
def localisation_perso(self, perso):
"Permet de déterminer, selon les coordonnées du personnages, dans quelle zone il se trouve'"
for i in self.lieux:
distance = sqrt((self.lieux[i]["Coord_x"] - perso.Coord_x) ** 2 + (self.lieux[i]["Coord_y"] - perso.Coord_y) ** 2)
if distance <= self.lieux[i]["Rayon"]:
# print self.lieux[i]["Nom"]
return i
break
def test_rencontre(self, perso):
"Lance un test de rencontre, détermine si lors d'un déplacement 'le personnage fait une rencontre aléa"
lieu = self.localisation_perso(perso)
if lieu is not None: # Si le perso se trouve dans une zone déterminée dans lieux()
if (random.randrange(1, 6)) >= 4: # On lance test de rencontre prenant en compte les apptitudes du perso - A Faire, intervenir compétences du perso ici
# On créé une ennemi selon le lieu dans lequel se trouve le perso
# calcul_rencontre = chercher dans le liste des montsres du lieu
ennemi = Perso()
# on créé notre créature
ennemi.creation_perso_rapide(self.calcul_rencontre("Selon niveau perso1 -- A Faire", lieu, "Monstres"))
crea_item.donne_arme(ennemi, ennemi.arme) # On lui donne son arme - Revoir Item()
print "Le jet de dés donne une mauvaise rencontre pour %s" % (perso.nom)
# Puis on calcul la CA des personnages
perso.calcul_ca()
ennemi.calcul_ca()
# Puis on lance le combat
cmb = Duel()
cmb.calcul_init(perso, ennemi)
cmb.stdr_fight(perso, ennemi)
else:
print "%s a évité une mauvaise rencontre" % (perso.nom)
else:
print "%s n'a fait aucune rencontre" % (perso.nom)
def voir_carte_zone(self): # A supprimer,
"Affiche une réprésentation des zones et localisation perso"
for i in self.lieux:
# Turtle Zones- A SUpprimer
turtle.penup()
turtle.setpos(self.lieux[i]["Coord_x"], (self.lieux[i]["Coord_y"] - self.lieux[i]["Rayon"]))
turtle.pendown()
turtle.circle(self.lieux[i]["Rayon"])
turtle.write(self.lieux[i]["Nom"])
# / Turtle - A SUpprimer
turtle.penup()
turtle.goto(0, 0)
def voir_pos_perso(self, perso):
"Affiche sur la carte la position du perso"
# Turtle Perso- A SUpprimer
turtle.penup()
turtle.setx(perso.Coord_x)
turtle.sety(perso.Coord_y)
turtle.pendown()
turtle.dot(4, "red")
turtle.write(perso.nom)
# / Turtle - A SUpprimer
# personnages
perso1 = Perso()
perso2 = Perso()
perso3 = Perso()
crea_item = Item() # Revoir tout le système d'items, pas satisfaisant
aventure = Rencontre_aleatoire()
perso1.creation_perso_rapide("Gerald de Rive") # On récupère le personnage
crea_item.donne_arme(perso1, "arme2") # On lui donne une arme - A revoir
perso2.creation_perso_rapide("Perceval")
crea_item.donne_arme(perso2, "arme2")
perso3.creation_perso_rapide("Karadoc")
crea_item.donne_arme(perso3, "arme3")
aventure.voir_carte_zone() # Visualiser la carte - A SUPPRIMER
aventure.voir_pos_perso(perso1) # Affiche la position du perso - A SUPPRIMER
aventure.voir_pos_perso(perso2)
aventure.voir_pos_perso(perso3)
aventure.test_rencontre(perso1) # On lance le test d'une rencontre aléatoire'
aventure.test_rencontre(perso2)
aventure.test_rencontre(perso3)
turtle.getscreen()._root.mainloop() # A surrprimer |
Partager