Partage
  • Partager sur Facebook
  • Partager sur Twitter

Patern Decorator

Adaptation du super tuto

Sujet résolu
    11 mars 2011 à 12:36:07

    Bonjour,
    Je m'inspire du super tuto.
    Je tente de l'adapter à mon programme ( de combat ).
    Mais je reste bloqué à un endroit. Au lieu d'ajouter +1 à la quantité de l'ingrédient. Je voudrais ajouter +x (valeur transmise à la fonction) à la valeur de l'ingrédient. (Ici moi ce sont des stats.)

    Voir la ligne 79.
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    
    # Fight tournament 1.0 avec décorator patern
    # Créateur : Klaitos
    # Date de création : Vendredi 11 mars 2011
    # Version de python : 3.1 et 3.2
    # Inspiration : http://www.siteduzero.com/tutoriel-3-368501-le-pattern-decorator-en-python.html
    
    from collections import namedtuple
    
    val_SANTE = 100
    val_FORCE = 10
    val_AGILITE = 5
    val_INTELLIGENCE = 5
    
    Stats = namedtuple('Stats', 'val')
    
    class Personnage(object):
    	def __init__(self, nom, pouvoir):
    		self.nom = nom
    		self.pouvoir = pouvoir
    		self._stats = dict()
    
    	@property
    	def val(self):
    		return sum(i.val * i.qte for i in self._stats.values())
    
    	def __repr__(self):
    		return "Personnage {0} : Pouvoir {1}".format(self.nom, self.pouvoir)
    
    	def __str__(self):
    		s = repr(self)
    		for key, it in self._stats.items():
    			s += "\n {0:<15}{2:>5}".format(key, it, it.val)
    		return s + '\n'
    
    class Heros(Personnage):
    	def __init__(self,nom, pouvoir):
    		super().__init__(nom, pouvoir)
    		self._stats['Sante'] = Stats(val_SANTE)
    		self._stats['Force'] = Stats(val_FORCE)
    		self._stats['Agilité'] = Stats(val_AGILITE)
    		self._stats['Intelligence'] = Stats(val_INTELLIGENCE)
    
    	def __repr__(self):
    		return "\n *Personnage {0} : Pouvoir {1}".format(self.nom, self.pouvoir)
    
    class DecorateurPersonnage(Personnage):
    	def __init__(self, Personnage):
    		super().__init__(Personnage.nom, Personnage.pouvoir)
    		self.Personnage = Personnage
    		self._stats = Personnage._stats
    
    class RetraitStats(DecorateurPersonnage):
    	def __init__(self, Personnage, Stats):
    		super().__init__(Personnage)
    		# suppression de l'ingrédient voulu
    		self.retrait = None
    		if Stats in self._stats:
    			del self._stats[Stats]
    			self.retrait = Stats
    
    	def __repr__(self):
    		r = repr(self.Personnage)
    		if self.retrait is not None:
    			r += ", sans {0}".format(self.retrait)
    		return r
    
    def sans_force(Personnage): # Pourra peut-être être utile pour retirer un debuff
        return RetraitStats(Personnage, 'Force')
    
    
    class Supplement(DecorateurPersonnage):
    	def __init__(self, Personnage, stat, val, X):
    		super().__init__(Personnage)
    		# ajout de l'ingrédient voulu
    		val = self._stats.get(stat, 0)
    		self.ajout = stat 
    		self._stats[stat] = Stats(9+X)# J'ai mis 9 pour faire 9+5 (j'ajoute 5 de force à mon personnage et sa marche!
    # Je n'arrive pas à récupéré le 10 de force qu'il à de base !
    
    	def __repr__(self):
    		r = repr(self.personnage)
    		s = ", supplément {0}".format(self.ajout)
    		if s not in r:
    			r += s
    		return r
    
    def supp_force(Heros,X):
    	return Supplement(Heros, 'Force', val_FORCE,X)
     
    a = Heros('Klaitos','Flammes infernales')
    print (a)
    
    supp_force(a,5) # Je veux lui ajouter 5 à sa force. Par défaut il en a 10
    print (a)
    


    Merci.
    • Partager sur Facebook
    • Partager sur Twitter
      12 mars 2011 à 1:00:01

      Salut.

      Il y a clairement un problème de conception, mais le pattern decorator peut être adapté à ton cas (c'est pas non plus la solution à tous les problèmes, note).

      Un personnage n'est pas un Kebab : tu peux aussi t'éloigner du tuto en ne gardant que le principe en tête. Je veux dire par là que l'idée du Decorator, c'est d'envelopper un objet et se faire passer pour lui, rien de plus.

      Si ton décorateur augmente "temporairement" la force du personnage, pourquoi ne pas le faire "entrer en action" que lorsque l'on appelle sa méthode qui inflige des dégats ?
      Il commence par déléguer au personnage décoré le boulot de base, puis il ajoute lui même un bonus de dégats (correspondant à son +5 de force) : ça t'évite de modifier définitivement l'état de ton personnage, et pour peu que tu crées un système (une méthode... ou autre) qui te permette de dé-décorer ton objet, tu récupèrerais ce dernier intact.
      • Partager sur Facebook
      • Partager sur Twitter
      Zeste de Savoir, le site qui en a dans le citron !
      Anonyme
        12 mars 2011 à 12:05:53

        Citation

        Je m'inspire du super tuto.



        C'est clair, il est super sympa ce tuto, je dirais pas le contraire.

        Citation

        Je tente de l'adapter à mon programme ( de combat ).



        Est-ce vraiment utile? C'est un peu tuer une mouche avec une tronçonneuse.

        Citation

        Mais je reste bloqué à un endroit. Au lieu d'ajouter +1 à la quantité de l'ingrédient. Je voudrais ajouter +x (valeur transmise à la fonction) à la valeur de l'ingrédient. (Ici moi ce sont des stats.)



        Toutes les valeurs variants dans le temps, tu devrais les mettre dans ton __init__

        • Partager sur Facebook
        • Partager sur Twitter
          12 mars 2011 à 13:01:55

          Okok, merci à vous deux.
          Je vais réfléchir sur tout sa..
          • Partager sur Facebook
          • Partager sur Twitter

          Patern Decorator

          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
          • Editeur
          • Markdown