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
|
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Created on Thu Feb 23 16:56:25 2012
"""
class Attribute(object):
def __init__(self, min=None, max=None):
# TODO: Nettoyer résidu
b = 0
if min is not None: b += 1
if max is not None: b += 2
if b == 0: raise TypeError("%s takes at least one argument" % self.__class__)
if b == 1:
self._min = min
self._max = min
if b == 2:
self._min = max
self._max = max
if b == 3:
self._min = min
self._max = max
self._current = self._max
assert self._min<=self._current<=self._max
def __add__(self, value):
v = self._current + value
if v > self._max:
return self._max
return v
def __iadd__(self, value):
self._current = self.__add__(value)
return self
def __sub__(self, value):
v = self._current - value
if v < self._min:
return self._min
return v
def __isub__(self, value):
self._current = self.__sub__(value)
return self
def __repr__(self):
min = "min:%i" % self._min
max = "max:%i" % self._max
current = "current:%i" % self._current
return " ".join((min, current, max))
def get_copy(self):
return Attribute(self._min, self._max)
def set_min(self, min):
assert min <= self._current <= self._max
self._min = min
def set_max(self, max):
assert self._min <= self._current <= max
self._max = max
def set_current(self, current):
assert self._min <= current <= self._max
self._current = current
class MetaCreature(type):
def __new__(cls, names, bases, attrs):
new_attrs = dict()
for key, value in attrs.iteritems():
if isinstance(value, Attribute):
newkey = "_" + key
new_attrs[newkey] = value
getter = cls.attribute_getter(newkey)
setter = cls.attribute_setter(newkey)
new_attrs[key] = property(getter, setter)
else:
new_attrs[key] = value
return type.__new__(cls, names, bases, new_attrs)
def __call__(cls, *args, **kwargs):
obj = object.__new__(cls)
for c in reversed(cls.__mro__):
for key, value in c.__dict__.iteritems():
if isinstance(value, Attribute):
setattr(obj, key, value.get_copy())
return obj
@staticmethod
def attribute_getter(attribute):
def getter(obj):
return getattr(obj, attribute)
return getter
@staticmethod
def attribute_setter(attribute):
def setter(obj, value):
if isinstance(value, Attribute):
setattr(obj, attribute, value)
elif type(value) is int:
attr_obj = getattr(obj, attribute)
attr_obj.set_current(value)
else:
raise TypeError()
return setter
class BaseCreature(object):
__metaclass__ = MetaCreature
pass
class Creature(BaseCreature):
hp = Attribute(min=0, max=50)
mp = Attribute(10)
class Orc(Creature):
hp = Attribute(min=0, max=999)
orc = Orc() |
Partager