Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # -*- coding: utf-8 *-*
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
- # (un peu inspiré des règles D20)
- # V0.9 - maj 16/08/2012
- # dernière modif : test_rencontre()
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
- 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() - A bosser
- 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
Advertisement
Add Comment
Please, Sign In to add comment