rendered paste body#!/usr/bin/env pythonclass RegisterableParent: def __init__(self): self._updates = [] self.value = 0 def calculate(self): self._set(self.formula()) def _set(self, val): self.value = val for stat in self._updates: stat.calculate() def get(self): return self.valueclass PrimitiveStat(RegisterableParent): def __init__(self): RegisterableParent.__init__(self) self.set = self._setclass CompoundStat(RegisterableParent): def __init__(self, base=PrimitiveStat()): RegisterableParent.__init__(self) self.multipliers = MultiplyingCollection() self.bonuses = AddingCollection() self.base = base for stat in [self.multipliers, self.bonuses, self.base]: stat._updates.append(self) def formula(self): return (self.multipliers.value * self.base.value) + self.bonuses.valueclass CalculatedStat(RegisterableParent): def __init__(self, **kwargs): RegisterableParent.__init__(self) self._toolbox = {} for arg in kwargs: self._toolbox[arg] = kwargs[arg] for stat in self._toolbox: self._toolbox[stat]._updates.append(self) def getStat(self, stat): return self._toolbox[stat].valueclass Bonus: def __init__(self, value): self.value = value self._updates = [] class BonusCollectionParent(RegisterableParent): def __init__(self): RegisterableParent.__init__(self) self.bonuses = set() def register(self, item): self.bonuses.add(item) self.calculate() def unregister(self, item): self.bonuses.remove(item) self.calculate()class AddingCollection(BonusCollectionParent): def formula(self): x = 0 for bonus in self.bonuses: x += bonus.value return xclass MultiplyingCollection(BonusCollectionParent): def formula(self): x = 1 for bonus in self.bonuses: x *= (1 + bonus) return xlevel = PrimitiveStat()strength = CompoundStat()strength.base.set(13)bonus_attack_power = PrimitiveStat()bonus_attack_power.set(5)attack_power = CalculatedStat(level=level, strength=strength, bonus_attack_power = bonus_attack_power)attack_power.formula = lambda: attack_power.getStat('level') + attack_power.getStat('strength') * 2 + attack_power.getStat('bonus_attack_power')hp = CalculatedStat(level=level)hp.formula = lambda: hp.getStat('level') * 10level.set(4)print level.valueprint hp.valueprint attack_power.valuelevel.set(level.value + 1)print attack_power.valuebonus_attack_power.set(0)print attack_power.valuetest = AddingCollection()g = Bonus(3)test.register(g)print test.valuetest.register(Bonus(4))print test.valuetest.unregister(g)print test.value