Mercurial > traipse_dev
comparison orpg/dieroller/die.py @ 0:4385a7d0efd1 grumpy-goblin
Deleted and repushed it with the 'grumpy-goblin' branch. I forgot a y
author | sirebral |
---|---|
date | Tue, 14 Jul 2009 16:41:58 -0500 |
parents | |
children | 449a8900f9ac |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4385a7d0efd1 |
---|---|
1 #!/usr/bin/env python | |
2 # Copyright (C) 2000-2001 The OpenRPG Project | |
3 # | |
4 # openrpg-dev@lists.sourceforge.net | |
5 # | |
6 # This program is free software; you can redistribute it and/or modify | |
7 # it under the terms of the GNU General Public License as published by | |
8 # the Free Software Foundation; either version 2 of the License, or | |
9 # (at your option) any later version. | |
10 # | |
11 # This program is distributed in the hope that it will be useful, | |
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 # GNU General Public License for more details. | |
15 # | |
16 # You should have received a copy of the GNU General Public License | |
17 # along with this program; if not, write to the Free Software | |
18 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
19 # -- | |
20 # | |
21 # File: die.py | |
22 # Author: Andrew Bennett | |
23 # Maintainer: | |
24 # Version: | |
25 # $Id: die.py,v 1.13 2007/03/13 17:53:42 digitalxero Exp $ | |
26 # | |
27 # Description: This class is used to make working with dice easier | |
28 # | |
29 | |
30 __version__ = "$Id: die.py,v 1.13 2007/03/13 17:53:42 digitalxero Exp $" | |
31 | |
32 | |
33 import random | |
34 import UserList | |
35 import copy | |
36 #import string | |
37 | |
38 class die_base(UserList.UserList): | |
39 | |
40 def __init__(self,source = []): | |
41 if isinstance(source, (int, float, basestring)): | |
42 s = [] | |
43 s.append(di(source)) | |
44 else: | |
45 s = source | |
46 UserList.UserList.__init__(self,s) | |
47 | |
48 | |
49 def sum(self): | |
50 s = 0 | |
51 for a in self.data: | |
52 s += int(a) | |
53 return s | |
54 | |
55 def __lshift__(self,other): | |
56 if type(other) == type(3) or type(other) == type(3.0): | |
57 o = other | |
58 elif hasattr(other,"sum"): | |
59 o = other.sum() | |
60 else: | |
61 return None | |
62 | |
63 result = [] | |
64 for die in self: | |
65 if die < o: | |
66 result.append(die) | |
67 return self.__class__(result) | |
68 | |
69 def __rshift__(self,other): | |
70 | |
71 if type(other) == type(3) or type(other) == type(3.0): | |
72 o = other | |
73 elif hasattr(other,"sum"): | |
74 o = other.sum() | |
75 else: | |
76 return None | |
77 | |
78 result = [] | |
79 for die in self: | |
80 if die > o: | |
81 result.append(die) | |
82 return self.__class__(result) | |
83 | |
84 def __rlshift__(self,other): | |
85 return self.__rshift__(other) | |
86 | |
87 def __rrshift__(self,other): | |
88 return self.__lshift__(other) | |
89 | |
90 | |
91 def __str__(self): | |
92 if len(self.data) > 0: | |
93 myStr = "[" + str(self.data[0]) | |
94 for a in self.data[1:]: | |
95 myStr += "," | |
96 myStr += str(a) | |
97 myStr += "] = (" + str(self.sum()) + ")" | |
98 else: | |
99 myStr = "[] = (0)" | |
100 return myStr | |
101 | |
102 def __lt__(self,other): | |
103 if type(other) == type(3) or type(other) == type(3.0): | |
104 return (self.sum() < other) | |
105 elif hasattr(other,"sum"): | |
106 return (self.sum() < other.sum()) | |
107 else: | |
108 return UserList.UserList.__lt__(self,other) | |
109 | |
110 def __le__(self,other): | |
111 if type(other) == type(3) or type(other) == type(3.0): | |
112 return (self.sum() <= other) | |
113 elif hasattr(other,"sum"): | |
114 return (self.sum() <= other.sum()) | |
115 else: | |
116 return UserList.UserList.__le__(self,other) | |
117 | |
118 def __eq__(self,other): | |
119 if type(other) == type(3) or type(other) == type(3.0): | |
120 return (self.sum() == other) | |
121 elif hasattr(other,"sum"): | |
122 return (self.sum() == other.sum()) | |
123 else: | |
124 return UserList.UserList.__eq__(self,other) | |
125 | |
126 def __ne__(self,other): | |
127 if type(other) == type(3) or type(other) == type(3.0): | |
128 return (self.sum() != other) | |
129 elif hasattr(other,"sum"): | |
130 return (self.sum() != other.sum()) | |
131 else: | |
132 return UserList.UserList.__ne__(self,other) | |
133 | |
134 def __gt__(self,other): | |
135 if type(other) == type(3) or type(other) == type(3.0): | |
136 return (self.sum() > other) | |
137 elif hasattr(other,"sum"): | |
138 return (self.sum() > other.sum()) | |
139 else: | |
140 return UserList.UserList.__gt__(self,other) | |
141 | |
142 def __ge__(self,other): | |
143 if type(other) == type(3) or type(other) == type(3.0): | |
144 return (self.sum() >= other) | |
145 elif hasattr(other,"sum"): | |
146 return (self.sum() >= other.sum()) | |
147 else: | |
148 return UserList.UserList.__ge__(self,other) | |
149 | |
150 def __cmp__(self,other): | |
151 # this function included for backwards compatibility | |
152 # As of 2.1, lists implement the "rich comparison" | |
153 # methods overloaded above. | |
154 if type(other) == type(3) or type(other) == type(3.0): | |
155 return cmp(self.sum(), other) | |
156 elif hasattr(other,"sum"): | |
157 return cmp(self.sum(), other.sum()) | |
158 else: | |
159 return UserList.UserList.__cmp__(self,other) | |
160 | |
161 | |
162 def __rcmp__(self,other): | |
163 return self.__cmp__(other) | |
164 | |
165 def __add__(self,other): | |
166 mycopy = copy.deepcopy(self) | |
167 if type(other) == type(3) or type(other) == type(3.0): | |
168 #if other < 0: | |
169 # return self.__sub__(-other) | |
170 #other = [di(other,other)] | |
171 other = [static_di(other)] | |
172 #return self.sum() + other | |
173 | |
174 elif type(other) == type("test"): | |
175 return self | |
176 mycopy.extend(other) | |
177 #result = UserList.UserList.__add__(mycopy,other) | |
178 return mycopy | |
179 | |
180 def __iadd__(self,other): | |
181 return self.__add__(other) | |
182 | |
183 def __radd__(self,other): | |
184 mycopy = copy.deepcopy(self) | |
185 if type(other) == type(3) or type(other) == type(3.0): | |
186 new_die = di(0) | |
187 new_die.set_value(other) | |
188 other = new_die | |
189 mycopy.insert(0,other) | |
190 return mycopy | |
191 | |
192 def __int__(self): | |
193 return self.sum() | |
194 | |
195 def __sub__(self,other): | |
196 mycopy = copy.deepcopy(self) | |
197 if type(other) == type(3) or type(other) == type(3.0): | |
198 neg_die = static_di(-other) | |
199 #neg_die.set_value(-other) | |
200 other = [neg_die] | |
201 #return self.sum() - other | |
202 else: | |
203 other = -other | |
204 mycopy.extend(other) | |
205 return mycopy | |
206 | |
207 def __rsub__(self,other): | |
208 mycopy = -copy.deepcopy(self) | |
209 #print type(other) | |
210 if type(other) == type(3) or type(other) == type(3.0): | |
211 new_die = di(0) | |
212 new_die.set_value(other) | |
213 other = new_die | |
214 mycopy.insert(0,other) | |
215 return mycopy | |
216 | |
217 def __isub__(self,other): | |
218 return self.__sub__(other) | |
219 | |
220 def __mul__(self,other): | |
221 if type(other) == type(3) or type(other) == type(3.0): | |
222 return self.sum() * other | |
223 elif hasattr(other,"sum"): | |
224 return other.sum() * self.sum() | |
225 else: | |
226 return UserList.UserList.__mul__(self,other) | |
227 | |
228 def __rmul__(self,other): | |
229 return self.__mul__(other) | |
230 | |
231 def __div__(self,other): | |
232 if type(other) == type(3) or type(other) == type(3.0): | |
233 return float(self.sum()) / other | |
234 elif hasattr(other,"sum"): | |
235 return float(self.sum()) / other.sum() | |
236 else: | |
237 return UserList.UserList.__div__(self,other) | |
238 | |
239 def __rdiv__(self,other): | |
240 if type(other) == type(3) or type(other) == type(3.0): | |
241 return other / float(self.sum()) | |
242 elif hasattr(other,"sum"): | |
243 return other.sum() / float(self.sum()) | |
244 else: | |
245 return UserList.UserList.__rdiv__(self,other) | |
246 | |
247 def __mod__(self,other): | |
248 if type(other) == type(3) or type(other) == type(3.0): | |
249 return self.sum()%other | |
250 elif hasattr(other,"sum"): | |
251 return self.sum() % other.sum() | |
252 else: | |
253 return UserList.UserList.__mod__(self,other) | |
254 | |
255 def __rmod__(self,other): | |
256 if type(other) == type(3) or type(other) == type(3.0): | |
257 return other % self.sum() | |
258 elif hasattr(other,"sum"): | |
259 return other.sum() % self.sum() | |
260 else: | |
261 return UserList.UserList.__rmod__(self,other) | |
262 | |
263 def __neg__(self): | |
264 for i in range(len(self.data)): | |
265 self.data[i] = -self.data[i] | |
266 return self | |
267 | |
268 def __pos__(self): | |
269 for i in range(len(self.data)): | |
270 self.data[i] = +self.data[i] | |
271 return self | |
272 | |
273 def __abs__(self): | |
274 for i in range(len(self.data)): | |
275 self.data[i] = abs(self.data[i]) | |
276 return self | |
277 #return abs(self.sum()) | |
278 | |
279 def __pow__(self,other): | |
280 if type(other) == type(3) or type(other) == type(3.0): | |
281 return self.sum() ** other | |
282 elif hasattr(other,"sum"): | |
283 return self.sum() ** other.sum() | |
284 else: | |
285 return UserList.UserList.__pow__(self,other) | |
286 | |
287 | |
288 def __rpow__(self,other): | |
289 # We're overloading exponentiation of ints to create "other" number of dice | |
290 | |
291 if other >= 1: | |
292 result = self.__class__(self[0].sides) | |
293 for t in range(other-1): | |
294 result+=self.__class__(self[0].sides) | |
295 else: | |
296 result = None | |
297 | |
298 return result | |
299 | |
300 ### di class to handle actual dice | |
301 | |
302 class di: | |
303 def __init__(self,sides,min=1): | |
304 self.sides = sides | |
305 self.history = None | |
306 self.value = None | |
307 self.target = None | |
308 self.roll(min) | |
309 | |
310 def __str__(self): | |
311 if len(self.history) > 1: | |
312 return str(self.history) | |
313 else: | |
314 return str(self.value) | |
315 | |
316 def __neg__(self): | |
317 self.value = -self.value | |
318 for i in range(len(self.history)): | |
319 self.history[i] = -self.history[i] | |
320 return self | |
321 | |
322 def __pos__(self): | |
323 self.value = +self.value | |
324 for i in range(len(self.history)): | |
325 self.history[i] = +self.history[i] | |
326 return self | |
327 | |
328 def __abs__(self): | |
329 self.value = abs(self.value) | |
330 for i in range(len(self.history)): | |
331 self.history[i] = abs(self.history[i]) | |
332 return self | |
333 | |
334 def __repr__(self): | |
335 if len(self.history) > 1: | |
336 return str(self.history) | |
337 else: | |
338 return str(self.value) | |
339 | |
340 def __int__(self): | |
341 return self.value | |
342 | |
343 | |
344 def __lt__(self,other): | |
345 if type(other) == type(3) or type(other) == type(3.0): | |
346 return self.value < other | |
347 elif hasattr(other,"value"): | |
348 return self.value < other.value | |
349 else: | |
350 return self < other | |
351 | |
352 def __le__(self,other): | |
353 if type(other) == type(3) or type(other) == type(3.0): | |
354 return self.value <= other | |
355 elif hasattr(other,"value"): | |
356 return self.value <= other.value | |
357 else: | |
358 return self <= other | |
359 | |
360 def __eq__(self,other): | |
361 if type(other) == type(3) or type(other) == type(3.0): | |
362 return self.value == other | |
363 elif hasattr(other,"value"): | |
364 return self.value == other.value | |
365 else: | |
366 return self == other | |
367 | |
368 def __ne__(self,other): | |
369 if type(other) == type(3) or type(other) == type(3.0): | |
370 return self.value != other | |
371 elif hasattr(other,"value"): | |
372 return self.value != other.value | |
373 else: | |
374 return self != other | |
375 | |
376 def __gt__(self,other): | |
377 if type(other) == type(3) or type(other) == type(3.0): | |
378 return self.value > other | |
379 elif hasattr(other,"value"): | |
380 return self.value > other.value | |
381 else: | |
382 return self > other | |
383 | |
384 def __ge__(self,other): | |
385 if type(other) == type(3) or type(other) == type(3.0): | |
386 return self.value >= other | |
387 elif hasattr(other,"value"): | |
388 return self.value >= other.value | |
389 else: | |
390 return self >= other | |
391 | |
392 def __cmp__(self,other): | |
393 # this function included for backwards compatibility | |
394 # As of 2.1, lists implement the "rich comparison" | |
395 # methods overloaded above. | |
396 if type(other) == type(3) or type(other) == type(3.0): | |
397 return cmp(self.value, other) | |
398 elif hasattr(other,"value"): | |
399 return cmp(self.value, other.value) | |
400 else: | |
401 return cmp(self,other) | |
402 | |
403 def roll(self,min=1): | |
404 if isinstance(self.sides, basestring) and self.sides.lower() == 'f': | |
405 self.value = random.randint(-1, 1) | |
406 else: | |
407 #self.value = random.randint(min, self.sides) | |
408 self.value = int(random.uniform(min, self.sides+1)) | |
409 self.history = [] | |
410 self.history.append(self.value) | |
411 | |
412 def extraroll(self): | |
413 if isinstance(self.sides, basestring) and self.sides.lower() == 'f': | |
414 result = random.randint(-1, 1) | |
415 else: | |
416 #result = random.randint(1, self.sides) | |
417 result = int(random.uniform(1,self.sides+1)) | |
418 | |
419 self.value += result | |
420 self.history.append(result) | |
421 | |
422 def lastroll(self): | |
423 return self.history[len(self.history)-1] | |
424 | |
425 def set_value(self,value): | |
426 self.value = value | |
427 self.history = [] | |
428 self.history.append(self.value) | |
429 | |
430 def modify(self,mod): | |
431 self.value += mod | |
432 self.history.append(mod) | |
433 | |
434 def gethistory(self): | |
435 return self.history[:] | |
436 | |
437 class static_di(di): | |
438 def __init__(self,value): | |
439 di.__init__(self,value,value) | |
440 self.set_value(value) | |
441 | |
442 | |
443 class std(die_base): | |
444 def __init__(self,source=[]): | |
445 die_base.__init__(self,source) | |
446 | |
447 # Examples of adding member functions through inheritance. | |
448 | |
449 def ascending(self): | |
450 result = self[:] | |
451 result.sort() | |
452 return result | |
453 | |
454 def descending(self): | |
455 result = self[:] | |
456 result.sort() | |
457 result.reverse() | |
458 return result | |
459 | |
460 def takeHighest(self,num_dice): | |
461 return self.descending()[:num_dice] | |
462 | |
463 def takeLowest(self,num_dice): | |
464 return self.ascending()[:num_dice] | |
465 | |
466 def extra(self,num): | |
467 for i in range(len(self.data)): | |
468 if self.data[i].lastroll() >= num: | |
469 self.data[i].extraroll() | |
470 return self | |
471 | |
472 def open(self,num): | |
473 if num <= 1: | |
474 self | |
475 done = 1 | |
476 for i in range(len(self.data)): | |
477 if self.data[i].lastroll() >= num: | |
478 self.data[i].extraroll() | |
479 done = 0 | |
480 if done: | |
481 return self | |
482 else: | |
483 return self.open(num) | |
484 | |
485 def minroll(self,min): | |
486 for i in range(len(self.data)): | |
487 if self.data[i].lastroll() < min: | |
488 self.data[i].roll(min) | |
489 return self | |
490 | |
491 def each(self,mod): | |
492 mod = int(mod) | |
493 for i in range(len(self.data)): | |
494 self.data[i].modify(mod) | |
495 return self | |
496 | |
497 | |
498 def vs(self, target): | |
499 for dn in self.data: | |
500 dn.target = target | |
501 return self | |
502 | |
503 | |
504 ## If we are testing against a saving throw, we check for | |
505 ## greater than or equal to against the target value and | |
506 ## we only return the number of successful saves. A negative | |
507 ## value will never be generated. | |
508 def sum(self): | |
509 retValue = 0 | |
510 for dn in self.data: | |
511 setValue = reduce( lambda x, y : int(x)+int(y), dn.history ) | |
512 if dn.target: | |
513 if setValue >= dn.target: | |
514 retValue += 1 | |
515 | |
516 else: | |
517 retValue += setValue | |
518 | |
519 return retValue |