IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Avis concernant un petit programme [Débutant(e)]


Sujet :

Python

  1. #1
    Membre régulier
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Juin 2012
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Juin 2012
    Messages : 10
    Par défaut Avis concernant un petit programme
    Salut,
    D'abord j'espère avoir posté dans la bonne section...
    Comme il est dit dans le titre, je viens vers vous pour avoir un avis sur ma façon de programmer, savoir si je fais bien les choses, si je suis sur la bonne voie, sur la logique etc.
    J'ai bien conscience qu'il n'est pas forcément agréable d'éplucher un programme fait pas un débutant (première fois que je tente de vraiment penser en objets) mais cela me serait d'une grande aide pour progresser.

    Concernant le programme, c'est assez simple. Il s'agit de faire combattre deux personnages, aux attributs différents et de déterminer un vainqueur.
    Je me suis librement inspiré des règles de donjons et dragons (inspiré est le mot car j'avoue ne pas saisir toute la complexité des règles ^^).

    La class item est en cours, donc celle-ci est je pense vraiment cracra...

    Voilà, je remercie par avance les personnes qui prendront le temps de lire tout ça.

    C'est ici : http://pastebin.com/yjg4kXqQ

    ou bien là :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
    # -*- coding: utf-8 *-*
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
    # Petit passe temps : Combat entre 2 perso
    # (un peu inspiré des règles D20)
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
     
    import time
    import random
     
     
    class Perso:
        "Création d'un perso, Perso standard"
        def __init__(self, sname, shp, sstrength, sdext, sca, sarmure, sarme):
            self.name = sname          # Nom
            self.hp = shp              # Points de vie
            self.strength = sstrength  # Force
            self.dext = sdext          # Dextérité
            self.ca = sca              # Classe d'armure (mettre 0)
            self.armure = sarmure      # Armure
            self.arme = sarme          # Arme
     
     
    class Item:
        "A revoir, la logique etc"
        def __init__(self):
            self.table_armes = { \
            'arme1': {'Nom': 'Dague', 'Desc': 'ddesc', 'Poids': 500, 'Degats': 10, 'Cpt_privi': 'dext'}, \
            'arme2': {'Nom': 'Rapière', 'Desc': 'ddesc', 'Poids': 1500, 'Degats': 20, 'Cpt_privi': 'strength'}, \
            'arme3': {'Nom': 'Hache', 'Desc': 'ddesc', 'Poids': 3000, 'Degats': 30, 'Cpt_privi': 'strength'} \
            }
     
        def crea_arme(self, arme_id):
            "Donne une arme au personnage - A travailler"
            return self.table_armes[arme_id]
     
        def desc_arme(self, arme_id):
            "Information concernant une arme - A travailler"
            print "Arme : " + self.table_armes[arme_id]['Nom']
            print "Description : " + self.table_armes[arme_id]['Desc']
            print "Poids : " + str(self.table_armes[arme_id]['Poids']) + " Gr"
            print "Dégats : 1d" + str(self.table_armes[arme_id]['Degats'])
            print "Compétance à privilégier : " + 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 perso1.name + " : " + str(perso1.dext) + " dext"
            print "    > le jet de dés donne une initiative de " + str(jet_perso1) \
            + " pour " + perso1.name
            print perso2.name + " : " + str(perso2.dext) + " dext"
            print "    > le jet de dés donne une initiative de " + str(jet_perso2) \
            + " pour " + perso2.name
            if jet_perso1 >= jet_perso2:
                print perso1.name + " attaque le premier"
                self.initiative = False  # on bascule le switch pour déterminé qui a l'initiative (voir stdr_fight())
            else:
                print perso2.name + " attaque le premier"
                self.initiative = True
     
        def calcul_ca(self, perso):
            # 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é
            perso.ca = 10 + perso.armure + perso.dext
            print perso.name + " CA : " + str(perso.ca)
     
        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)
                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()
                    break  # on brise la boucle while
                elif (perso2.hp <= 0):
                    self.victoire(perso1, perso2)
                    break
     
        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 attaquant.name + " donne un coup à " + defenseur.name + " avec " + attaquant.arme['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 = defenseur.hp - self.jet_degats(attaquant)
                if defenseur.hp > 0:  # si le def est en vie
                    print "    > " + defenseur.name + " perd " + str(puiss_attaqu) \
                    + " points de vie. " + str(defenseur.hp) + " restants"
                else:  # Si non, on change le message en indiquant la mort du perso
                    print "    > " + defenseur.name + " perd " + str(puiss_attaqu) \
                    + " points de vie et s'écroule sur le sol"
            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 :"\
                + str(puiss_attaqu) + " | CA de la cible : " + str(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_cpt == '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 = {500: 0, 1500: -2, 3000: -4}
            return table_poids[poids]
            pass
     
        def victoire(self, vainqueur, perdant):
            print "__________________Fin du duel_________________"
            # Simple message indiquant le gagnant
            print vainqueur.name + " remporte le combat contre " + perdant.name
            print vainqueur.name + " a " + str(vainqueur.hp) + \
            " points de vie restant"
     
     
    #test création arme (voir perso) + affichage info arme
    crea_item = Item()
    #crea_item.desc_arme("arme1")  # semble ok
     
    # Création des persos
    # pour mémoire (name,   hp,str,dext,ca0, armure, arme)
    perso1 = Perso("Karadoc", 50, 8, 2, 0, 5, crea_item.crea_arme('arme3'))
    perso2 = Perso("Perceval", 50, 3, 5, 0, 0, crea_item.crea_arme('arme1'))
     
    cmb1 = Duel()
     
    #calcul de l'initiative
    cmb1.calcul_init(perso1, perso2)
     
    #calcul de la CA
    cmb1.calcul_ca(perso1)
    cmb1.calcul_ca(perso2)
     
    # Puis le combat
    cmb1.stdr_fight(perso1, perso2)

  2. #2
    Membre Expert

    Homme Profil pro
    Diverses et multiples
    Inscrit en
    Mai 2008
    Messages
    662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Diverses et multiples

    Informations forums :
    Inscription : Mai 2008
    Messages : 662
    Par défaut
    Dans l’ensemble, ça m’a l’air pas mal du tout*! Le code est clair, proprement indenté et bien commenté.

    Seul gros reproche*: pourquoi diable, en 2012, commencer en python avec la branche 2.x*? Il me semblerait bien plus indiqué de directement se pencher sur python3*!

    Sinon, voici les quelques remarques qui me viennent à l’esprit*:

    Quelques petites améliorations de détail dans le “style”, par exemple plutôt que*:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
                defenseur.hp = defenseur.hp - self.jet_degats(attaquant)
    …autant utiliser*:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
                defenseur.hp -= self.jet_degats(attaquant)
    Ça fait exactement la même chose, mais c’est plus “élégamment” écrit…



    De plus, il serait bon d’apprendre la syntaxe de “formatage” des strings. Par exemple,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    print perso1.name + " : " + str(perso1.dext) + " dext"
    …peut s’écrire*:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    print "%s : %d dext" % (perso1.name, perso1.dext)
    …(%s attend un str, %d un entier, etc.), ou encore (syntaxe py3, aussi dispo en py 2.7)*:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    print("{} : {} dext".format(perso1.name, perso1.dext))
    Voir là pour py2 et ici pour py3.



    Enfin, pourquoi ne pas développer un peu le constructeur de Duel(), en lui passant les deux persos en paramètres, afin qu’il se charge des calculs initiaux*?

    Mais dans l’ensemble, je dis bon boulot*!

  3. #3
    Membre Expert Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Par défaut
    Ma fois, si tous les codes de débutants sont comme cela pourquoi pas. C'est un bon début.
    Puisque les classes sont 'en cours' et que mont29 a déjà parler du formatage du texte et du style il me reste les miettes.

    break est inutile (mais ne coûte rien) puisque while (perso1.hp >= 0) and (perso2.hp >= 0).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
        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 attaquant.name + " donne un coup à " + defenseur.name + " avec " + attaquant.arme['Nom']
            #  On calcul l'attaque via jet_attaque()
            puiss_attaqu = self.jet_attaque(attaquant)
    Pourquoi puiss_attaqu = 0 puisque puiss_attaqu = self.jet_attaque(attaquant) ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
        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_cpt == 'dext':
                perso_cpt = perso.dext
            else:
                perso_cpt = perso.strength
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
        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
            if perso.arme['Cpt_privi'] == 'dext':
                perso_cpt = perso.dext
            else:
                perso_cpt = perso.strength
    Non ?

    Il reste un pass après le return dans poids_conv

    Enfin, des détails en fait.

    @+ et bon code

  4. #4
    Membre régulier
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Juin 2012
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Juin 2012
    Messages : 10
    Par défaut
    Merci pour vos réponses rapides.
    Citation Envoyé par mont29 Voir le message
    Seul gros reproche*: pourquoi diable, en 2012, commencer en python avec la branche 2.x*?
    Bien, en fait, cela fait quelque temps que je m'intéresse à python, donc j'ai commencé à apprendre avec la version 2 (donc, petits bouts par petits bouts, très espacé dans le temps). Je n'ai fais jusqu'à maintenant des petits morceaux de scripts, et pas du tout sous forme d'objets. ^^

    Citation Envoyé par mont29 Voir le message
    Enfin, pourquoi ne pas développer un peu le constructeur de Duel(), en lui passant les deux persos en paramètres, afin qu’il se charge des calculs initiaux*?
    Mmmh oui, maintenant que tu le dis... il faut que j'étudie ça. Merci.

    Citation Envoyé par mont29 Voir le message
    Le code est clair, proprement indenté et bien commenté
    C'est en partie grâce à Ninja IDE, il me semble qu'il est vraiment bien de ce point de vue pour un débutant. Avant je codais avec gedit.




    Citation Envoyé par PauseKawa Voir le message
    Pourquoi puiss_attaqu = 0 puisque puiss_attaqu = self.jet_attaque(attaquant) ?
    ...
    Il reste un pass après le return dans poids_conv
    Merci, c'est corrigé


    J'ai dans l'idée de stocker mes personnages (noms attributs etc) dans des fichiers, histoire de pouvoir les sauvegarder. Je pense utiliser ConfigParser que je connais déjà un peu. Si vous voyez un autre module plus adapté...

  5. #5
    Membre Expert
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Par défaut
    Bonjour,

    J'aurais procédé un petit peu différemment pour la division des responsabilités (attribution des méthodes aux classes). Par exemple, j'aurais plutôt mis la méthode calcul_ca dans la classe Perso, vu qu'elle ne dépend que des attributs du personnage (en fait, j'en aurais même fait une property de la classe Perso).

    Idem pour jet_attaque et jet_degats, sauf si tu envisages que par la suite, le résultat de ces méthodes puisse dépendre d'attributs propres au duel (l'autre personnage ou l'environnement ou ...).

    Et comme l'a suggéré mont29, je ferais des deux persos des attributs du duel.

    Cela dit, je suis d'accord avec mont29 et PauseKawa, pour un débutant, c'est déjà très bon.

    Pour la persistance, ConfigParser peut convenir. Ca me semble assez lourd mais si tu es déjà à l'aise avec, pourquoi pas. Si tu n'as pas besoin d'éditer le fichier à la main, regarde du côté de pickle.

  6. #6
    Membre régulier
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Juin 2012
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Juin 2012
    Messages : 10
    Par défaut
    Je n'ai pas trouvé comment éditer mon premier message
    donc, le code mis à jour :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
    # -*- coding: utf-8 *-*
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
    # Petit passe temps : Combat entre 2 perso
    # (un peu inspiré des règles D20)
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
     
    import time
    import random
     
     
    class Perso:
        "Création d'un perso, Perso standard"
        def __init__(self, sname, shp, sstrength, sdext, sca, sarmure, sarme):
            self.name = sname          # Nom
            self.hp = shp              # Points de vie
            self.strength = sstrength  # Force
            self.dext = sdext          # Dextérité
            self.ca = sca              # Classe d'armure (mettre 0)
            self.armure = sarmure      # Armure
            self.arme = sarme          # Arme
     
        def calcul_ca(self, perso):
            # 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é
            perso.ca = 10 + perso.armure + perso.dext
            print "%s CA : %s" % (perso.name, perso.ca)
     
     
    class Item:
        "A revoir, la logique etc"
        def __init__(self):
            self.table_armes = { \
            'arme1': {'Nom': 'Dague', 'Desc': 'ddesc', 'Poids': 500, 'Degats': 10, 'Cpt_privi': 'dext'}, \
            'arme2': {'Nom': 'Rapière', 'Desc': 'ddesc', 'Poids': 1500, 'Degats': 20, 'Cpt_privi': 'strength'}, \
            'arme3': {'Nom': 'Hache', 'Desc': 'ddesc', 'Poids': 3000, 'Degats': 30, 'Cpt_privi': 'strength'} \
            }
     
        def crea_arme(self, arme_id):
            "Donne une arme au personnage - A travailler"
            return 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 : %s dext" % (perso1.name, perso1.dext)
            print "    > le jet de dés donne une initiative de %s pour %s" %\
            (jet_perso1, perso1.name)
            print perso2.name + "%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)
                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 avec %s" % (attaquant.name, defenseur.name, attaquant.arme['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.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 = {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 contre %s" % (vainqueur.name, perdant.name)
            print "%s a %d points de vie restants" % (vainqueur.name, vainqueur.hp)
     
     
    #test création arme (voir perso) + affichage info arme
    crea_item = Item()
    #crea_item.desc_arme("arme1")  # semble ok
     
    # Création des persos
    # pour mémoire (name,   hp,str,dext,ca0, armure, arme)
    perso1 = Perso("Karadoc", 50, 8, 2, 1, 5, crea_item.crea_arme('arme3'))
    perso2 = Perso("Perceval", 50, 3, 8, 2, 0, crea_item.crea_arme('arme1'))
     
    #calcul de la CA
    perso1.calcul_ca(perso1)
    perso2.calcul_ca(perso2)
     
    cmb1 = Duel()
     
    #calcul de l'initiative
    cmb1.calcul_init(perso1, perso2)
     
    # Puis le combat
    cmb1.stdr_fight(perso1, perso2)
    Je suis tombé sur une erreur également en exécutant le script. Un des personnages n'avait plus de points de vie mais il frappait encore Oo

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    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):
    @dividee : En effet, je pense que tu as raison concernant calcul_ca, c'est plus logique ainsi.
    Pour le reste de tes propositions, sachant que je ne sais pas trop l'évolution que prendra la chose, je ferai les changements au fur et à mesure.
    Merci en tout cas d'avoir pris le temps d'étudier ça.

    Concernant "property", j'ai commencé de regarder et pour le moment je n'ai pas tout saisi...
    Pickle me semble intéressant, je vais regarder ça de plus près.

  7. #7
    Membre Expert
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Par défaut
    Bonjour,

    passer perso en argument de calcul_ca ne sert à rien; c'est le même que self:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class Perso:
        ....
        def calcul_ca(self):
            self.ca = 10 + self.armure + self.dext
            print "%s CA : %s" % (self.name, self.ca)
    Le calcul de la CA n'est pas complexe, donc on pourrait très bien écrire la méthode de façon à ce qu'elle retourne la CA au lieu de la sauver dans un attribut:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    class Perso:
        ....
        def ca(self):
            return 10 + self.armure + self.dext
    (Il faut virer ton self.ca = sca de __init__; je ne vois pas trop à quoi sert sca, vu que la valeur est recalculée après...)
    On utiliserait alors perso.ca() au lieu de perso.ca quand on a besoin de cette valeur. Si cela te gène, on peut faire de ca une property:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class Perso:
        ....
       @property
        def ca(self):
            return 10 + self.armure + self.dext
    De cette façon, tu y accèdes avec perso.ca comme précédemment, mais il n'y a plus de calcul_ca à appeler...

  8. #8
    Membre régulier
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Juin 2012
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Juin 2012
    Messages : 10
    Par défaut
    Citation Envoyé par dividee Voir le message
    Bonjour,
    passer perso en argument de calcul_ca ne sert à rien; c'est le même que self:
    Effectivement, merci, j'ai corrigé

    Concernant sca... je l'ai créé pour stocker le petit calcul_ca(). De cette façon je n'ai que deux calculs à faire par duel. Je t'avoue que tout en l'écrivant ça ma gêné, mais je n'ai pas trouvé mieux.
    Maintenant, j'ai peut-être mal compris ce que tu as écrit, mais si tu fais ca(), ce qui lance le calcul de la classe d'armure, il me faut la calculer à chaque fois que j'en ai besoin, autrement dit à chaque coup porté.

    D'un côté je trouve ça plus logique, d'un autre je trouve que ça fait beaucoup de calculs, certes très simples, mais des calculs quand même.
    Je ne sais pas du coup, je ne suis pas certain d'avoir compris



    En attendant, j'ai commencé d'étudier un peu plus les règles de donjons et dragons (et autres). Je vais améliorer un peu tout ça.
    J'avais, il y a quelques temps, fait un petit script pour m'amuser. Je suis en train de regarder pour l'adapter et créer comme une sorte de zones de combats (genre plaine, donjon niveau 1, niveau 2 etc) et la probabilité de rencontrer tel type de monstre.
    Et donc je vais ajouter à Duel() un truc genre rencontre_aléatoire(), ainsi qu'un système d'expérience.

    Je posterai le résultat pour avoir vos avis.

  9. #9
    Membre Expert
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    952
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2006
    Messages : 952
    Par défaut
    Salut,

    Citation Envoyé par Matb-89 Voir le message
    Je pense utiliser ConfigParser que je connais déjà un peu. Si vous voyez un autre module plus adapté...
    C'est un très bon module pour sauver quelque chose de global, comme un baudrate ou un label. L'absence de profondeur (on peut le voir comme un gros dictionnaire, sans réelle possibilité d'un élément du dictionnaire qui puisse être lui même un dictionnaire ou une liste) est handicapante. Il vaut mieux passer par un fichier XML. Le module python généralement utilisé est Element Tree. Le bénéfice que tu en tireras compensera largement le temps passé à le découvrir.

    A+

    Pfeuh

  10. #10
    Membre régulier
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Juin 2012
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Juin 2012
    Messages : 10
    Par défaut
    Merci de la précision pfeuh concernant l'utilisation de ConfigParser, je vais étudier Element Tree.

    Je vais en profiter pour poster le code en cours... j'ai ajouté une class qui permet de faire apparaitre avec tel % de chance, une créature donnée selon un lieu donné. C'est plutôt cool
    J'avais un script maison pour faire ça à la base... puis finalement je me suis rendu compte qu'il y avait une solution beaucoup plus performante. Ca ne sert à rien de réinventer la roue comme on dit.
    J'ai également modifié la class Perso() histoire de pouvoir créer n'importe quel type de personnage.
    Puis 2/3/4 modifs par-ci par-là...
    Après il reste énormément de travail à faire, dont la partie sauvegarde/chargement à partir d'un fichier

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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)

  11. #11
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 816
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 816
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Matb-89 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    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é"}, \
            }
    Salut

    J'ai un peu lu en diagonale donc très vite mais j'ai remarqué ce petit pb: ici, chaque personnage créé contiendra, en lui, la liste de tous les personnages possibles.
    Ca fonctionne mais c'est super lourd (autant de persos créés, autant de listes identiques en mémoires). Donc pourquoi ne pas mettre cette liste en tant que membre statique de ta classe ???

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    class Perso():
        "Création d'un perso"
     
        # Membres statiques
        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 __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
            ...
    Ainsi même s'il y a 50 personnage, il n'y a qu'une seule liste en mémoire.
    Tu pourras de plus, y accéder de la même façon qu'avant: par exemple si tu crées un personnage toto=Perso(...) alors tu pourras taper dans toto.liste_creatures[...]. Mais tu n'es pas obligé car liste_creatures appartenant à la classe Perso elle-même (et non aux variables de cette classe), tu pourras y accéder de façon absolue en tapant dans cPerso.liste_creatures[...]...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  12. #12
    Membre régulier
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Juin 2012
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Juin 2012
    Messages : 10
    Par défaut
    Salut,
    J'ai essayé de corriger cela mais en fait il me retourne une erreur "global name 'liste_creatures' is not defined".
    Si je ne m'abuse, il considère liste_creatures comme une variable locale présentement ? Même sans le "self." (j'ai de vagues souvenirs de ça quand , dans ma jeunesse , je m'amusais avec Div Game Studio)


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    class Perso():
        "Création d'un perso"
        def __init__(self, name = "lambda", Race = "humain", hp = 10, strength = 3, \
        dext = 3, perception = 3, ca = 0, armure = 0, arme = "arme0", level = 1, xp = 0, \
        Desc = "un humain", Coord_x = 0, Coord_y = 0):
            self.name = name
            self.Race = Race        # voir list.creatures()
            self.hp = hp
            self.strength = strength
            self.dext = dext
            self.perception = perception
            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)
            self.Coord_x = Coord_x
            self.Coord_y = Coord_y
            # chargemment des personnages via pickle -- A FAIRE
            #nom de la créature : {Race,HP,Strength,Dextérité,CA,Armure,Arme,Level,XP,Decription}
            liste_creatures = {...etc etc }
    
    
        def creation_perso_rapide(self, nom):
                self.name = nom
                self.Race = liste_creatures[nom]["Race"]
                self.hp = liste_creatures[nom]["hp"]
                self.strength =liste_creatures[nom]["strength"]
                self.dext = liste_creatures[nom]["dext"]
                self.perception = liste_creatures[nom]["perception"]
                self.ca = liste_creatures[nom]["ca"]
                self.armure = liste_creatures[nom]["armure"]
                self.arme = liste_creatures[nom]["arme"]
                self.level = liste_creatures[nom]["level"]
                self.xp = liste_creatures[nom]["xp"]
                self.Desc = liste_creatures[nom]["Desc"]
                self.Coord_x = liste_creatures[nom]["Coord_x"]
                self.Coord_y = liste_creatures[nom]["Coord_y"]
                print "%s est apparu dans le monde" % (liste_creatures[nom]["Desc"])
    Il faut que je déclare liste_creatures comme étant une variable globale pour arriver au bon résultat ?
    Quelque chose comme ça (pour mémoire j'utilise Python 2.7):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class Perso():
    
       def __init__(...)
              global  liste_creatures 
              liste_creatures = {...etc etc }
    Ça a l'air de fonctionner en tout cas, après je ne sais pas si ça fait la même chose que ce que tu proposes Sve@r.

  13. #13
    Membre Expert

    Homme Profil pro
    Diverses et multiples
    Inscrit en
    Mai 2008
    Messages
    662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Diverses et multiples

    Informations forums :
    Inscription : Mai 2008
    Messages : 662
    Par défaut
    Oui, tu peux utiliser global (i.e. une variable globale), mais c’est rarement une “bonne” solution en POO, et ce que te proposait Sve@r, c’était de faire de liste_creatures non une variable d’instance, mais une variable de classe.

    En python, même les types d’objet (les classes) sont des objets, donc tu peux leur assigner des variables spécifiques, au même titre que tu leur assignes des méthodes (des fonctions, si tu préfères).

    Donc en reprenant le code de Sve@r, le liste_creatures appartient à la classe Perso, et est donc accessible soit comme Perso.liste_creatures, soit comme self.liste_creatures (depuis une méthode de cette classe)…

  14. #14
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 816
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 816
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Matb-89 Voir le message
    Salut,
    J'ai essayé de corriger cela mais en fait il me retourne une erreur "global name 'liste_creatures' is not defined".
    Si je ne m'abuse, il considère liste_creatures comme une variable locale présentement ? Même sans le "self."
    Tu as dû oublier un truc

    Essaye juste ceci
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    class toto:
        txt="Hello"     # Membre de classe
     
    print toto.txt     # Afficher le membre "txt" de la classe toto
     
     
    a=toto()           # Créer une variable de classe toto
    print a.txt         # Afficher le membre "txt" de l'objet a (qui est de facto un objet de classe toto)
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  15. #15
    Membre régulier
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Juin 2012
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Juin 2012
    Messages : 10
    Par défaut
    Effectivement, j'avais simplement mal placé liste_creatures merci.
    J'ignorai qu'on pouvait créer des variables de classe, intéressant.

    Bon comme je passe par là, voilà à quoi ressemble le code maintenant (avec un petit artifice histoire de)... toujours pas de sauvegarde, j'ai un peu de mal à m'y mettre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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

  16. #16
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 049
    Par défaut
    On pourrait créer un module creatures.py où tu placerais ta/tes variables concernant tes créatures, ça ferait un peu moins fouillis.

    Tu l’appellerais ainsi

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    class Perso:
        from creatures import liste_creatures

  17. #17
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 816
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 816
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Matb-89 Voir le message
    Effectivement, j'avais simplement mal placé liste_creatures merci.
    J'ignorai qu'on pouvait créer des variables de classe, intéressant.
    En C++ on les nommes "membres statiques de classe"...

    Citation Envoyé par Matb-89 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    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'} \
            }
    Tu aurais pu aussi mettre ta table des armes en tant que variable de classe et en faire une vraie table. De plus les backslashes ne sont pas obligatoires. En fait, il ne sont obligatoires que si la fin de la ligne pose une ambigüité.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class Item:
        "A revoir, la logique etc"
        table_armes = (
            {'Nom': 'Mains nues', 'description': 'de poing', 'Poids': 0, 'Degats': 3, 'Cpt_privi': 'strength'},
            {'Nom': 'Dague', 'description': 'de dague', 'Poids': 500, 'Degats': 10, 'Cpt_privi': 'dext'},
            {'Nom': 'Rapière', 'description': 'de rapière', 'Poids': 1500, 'Degats': 20, 'Cpt_privi': 'strength'},
            {'Nom': 'Hache', 'description': 'de hache', 'Poids': 3000, 'Degats': 30, 'Cpt_privi': 'strength'},
            {'Nom': 'Défenses', 'description': 'de défenses', 'Poids': 0, 'Degats': 15, 'Cpt_privi': 'strength'},
            {'Nom': 'Canines', 'description': 'de canines', 'Poids': 0, 'Degats': 20, 'Cpt_privi': 'dext'},
        )
    Ensuite tu accèdes à l'arme X via son indice table_armes[x]
    Sinon je trouve ton code amusant. Surtout le module turtle permettant de tracer une zone
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  18. #18
    Membre régulier
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Juin 2012
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Juin 2012
    Messages : 10
    Par défaut
    Citation Envoyé par fred1599 Voir le message
    On pourrait créer un module creatures.py où tu placerais ta/tes variables concernant tes créatures, ça ferait un peu moins fouillis.

    Tu l’appellerais ainsi

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    class Perso:
        from creatures import liste_creatures
    Une fois la méthode de sauvegarde/chargement écrite liste_creatures sera beaucoup moins envahissante je pense.
    Dans quelle condition il est conseillé de créer un module ? Pour rendre le code plus léger/clair ou il y a un bénéfice "technique" quelconque ?
    Après il serait peut-être intéressant de séparer toutes les class du reste du programme ?




    Citation Envoyé par Sve@r Voir le message
    De plus les backslashes ne sont pas obligatoires. En fait, il ne sont obligatoires que si la fin de la ligne pose une ambigüité.
    Oh, d'accord, j'ignorai ça. Je les utilisais pour que ce soit moins fatiguant à lire.

    Citation Envoyé par Sve@r Voir le message
    Sinon je trouve ton code amusant. Surtout le module turtle permettant de tracer une zone
    Je pense utiliser Pygame par la suite, j'avais déjà regardé il y a un bout de temps. Bon mais j'en suis encore loin.

  19. #19
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 049
    Par défaut
    Dans quelle condition il est conseillé de créer un module ?
    C'est une question d'organisation, de maintien du code, si tu as une modification à faire pour une créature, il suffit simplement d'aller dans le module creatures.py pour faire les modifs.

    La condition, c'est lorsqu'on se rend compte que le code devient moins lisible.

Discussions similaires

  1. Réponses: 6
    Dernier message: 05/12/2014, 15h01
  2. aide petit programme pour débutant
    Par kartp0rqx dans le forum C
    Réponses: 16
    Dernier message: 14/10/2005, 19h31
  3. Faisabilité d'un petit programme FTP...
    Par ptit_seb dans le forum Windows
    Réponses: 2
    Dernier message: 15/09/2005, 21h10
  4. Avis sur un petit projet
    Par nicolas66 dans le forum OpenGL
    Réponses: 10
    Dernier message: 02/02/2005, 00h27
  5. [SRC] Petit programme avec BD
    Par Nico62 dans le forum C++Builder
    Réponses: 3
    Dernier message: 10/01/2005, 20h07

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo