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

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  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
    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

  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
    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)

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