comparison src/parpg/characterstatistics.py @ 0:1fd2201f5c36

Initial commit of parpg-core.
author M. George Hansen <technopolitica@gmail.com>
date Sat, 14 May 2011 01:12:35 -0700
parents
children 756ce052ac85
comparison
equal deleted inserted replaced
-1:000000000000 0:1fd2201f5c36
1 # This program is free software: you can redistribute it and/or modify
2 # it under the terms of the GNU General Public License as published by
3 # the Free Software Foundation, either version 3 of the License, or
4 # (at your option) any later version.
5
6 # This program is distributed in the hope that it will be useful,
7 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 # GNU General Public License for more details.
10
11 # You should have received a copy of the GNU General Public License
12 # along with this program. If not, see <http://www.gnu.org/licenses/>.
13 """
14 Provides classes that define character stats and traits.
15 """
16
17 from abc import ABCMeta, abstractmethod
18 from weakref import ref as weakref
19
20 from .serializers import SerializableRegistry
21
22 class AbstractCharacterStatistic(object):
23 __metaclass__ = ABCMeta
24
25 @abstractmethod
26 def __init__(self, description, minimum, maximum):
27 self.description = description
28 self.minimum = minimum
29 self.maximum = maximum
30
31
32 class PrimaryCharacterStatistic(AbstractCharacterStatistic):
33 def __init__(self, long_name, short_name, description, minimum=0,
34 maximum=100):
35 AbstractCharacterStatistic.__init__(self, description=description,
36 minimum=minimum, maximum=maximum)
37 self.long_name = long_name
38 self.short_name = short_name
39
40 SerializableRegistry.registerClass(
41 'PrimaryCharacterStatistic',
42 PrimaryCharacterStatistic,
43 init_args=[
44 ('long_name', unicode),
45 ('short_name', unicode),
46 ('description', unicode),
47 ('minimum', int),
48 ('maximum', int),
49 ],
50 )
51
52
53 class SecondaryCharacterStatistic(AbstractCharacterStatistic):
54 def __init__(self, name, description, unit, mean, sd, stat_modifiers,
55 minimum=None, maximum=None):
56 AbstractCharacterStatistic.__init__(self, description=description,
57 minimum=minimum, maximum=maximum)
58 self.name = name
59 self.unit = unit
60 self.mean = mean
61 self.sd = sd
62 self.stat_modifiers = stat_modifiers
63
64 SerializableRegistry.registerClass(
65 'SecondaryCharacterStatistic',
66 SecondaryCharacterStatistic,
67 init_args=[
68 ('name', unicode),
69 ('description', unicode),
70 ('unit', unicode),
71 ('mean', float),
72 ('sd', float),
73 ('stat_modifiers', dict),
74 ('minimum', float),
75 ('maximum', float),
76 ],
77 )
78
79
80 class AbstractStatisticValue(object):
81 __metaclass__ = ABCMeta
82
83 @abstractmethod
84 def __init__(self, statistic_type, character):
85 self.statistic_type = statistic_type
86 self.character = weakref(character)
87
88
89 class PrimaryStatisticValue(AbstractStatisticValue):
90 def value():
91 def fget(self):
92 return self._value
93 def fset(self, new_value):
94 assert 0 <= new_value <= 100
95 self._value = new_value
96
97 def __init__(self, statistic_type, character, value):
98 AbstractStatisticValue.__init__(self, statistic_type=statistic_type,
99 character=character)
100 self._value = None
101 self.value = value
102
103
104 class SecondaryStatisticValue(AbstractStatisticValue):
105 def normalized_value():
106 def fget(self):
107 return self._normalized_value
108 def fset(self, new_value):
109 self._normalized_value = new_value
110 statistic_type = self.statistic_type
111 mean = statistic_type.mean
112 sd = statistic_type.sd
113 self._value = self.calculate_value(mean, sd, new_value)
114 return locals()
115 normalized_value = property(**normalized_value())
116
117 def value():
118 def fget(self):
119 return self._value
120 def fset(self, new_value):
121 self._value = new_value
122 statistic_type = self.statistic_type
123 mean = statistic_type.mean
124 sd = statistic_type.sd
125 self._normalized_value = self.calculate_value(mean, sd, new_value)
126 return locals()
127 value = property(**value())
128
129 def __init__(self, statistic_type, character):
130 AbstractStatisticValue.__init__(self, statistic_type=statistic_type,
131 character=character)
132 mean = statistic_type.mean
133 sd = statistic_type.sd
134 normalized_value = self.derive_value(normalized=True)
135 self._normalized_value = normalized_value
136 self._value = self.calculate_value(mean, sd, normalized_value)
137
138 def derive_value(self, normalized=True):
139 """
140 Derive the current value
141 """
142 statistic_type = self.statistic_type
143 stat_modifiers = statistic_type.stat_modifiers
144 character = self.character()
145
146 value = sum(
147 character.statistics[name].value * modifier for name, modifier in
148 stat_modifiers.items()
149 )
150 assert 0 <= value <= 100
151 if not normalized:
152 mean = statistic_type.mean
153 sd = statistic_type.sd
154 value = self.calculate_value(mean, sd, value)
155 return value
156
157 @staticmethod
158 def calculate_value(mean, sd, normalized_value):
159 value = sd * (normalized_value - 50) + mean
160 return value
161
162 @staticmethod
163 def calculate_normalized_value(mean, sd, value):
164 normalized_value = ((value - mean) / sd) + 50
165 return normalized_value