172
|
1 #!/usr/bin/env python
|
239
|
2 # Copyright (C) 2000-2010 The OpenRPG Project
|
172
|
3 #
|
239
|
4 # owner@madmathlabs.com
|
172
|
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: dieroller/utils.py
|
|
22 # Author: OpenRPG Team
|
239
|
23 # Maintainer (Traipse): Tyler Starke
|
172
|
24 # Version:
|
184
|
25 # $Id: utils.py,v Traipse 'Ornery-Orc' prof.ebral Exp $
|
172
|
26 #
|
|
27 # Description: Classes to help manage the die roller
|
|
28 #
|
|
29
|
|
30 import re
|
|
31
|
|
32 import orpg.dieroller.rollers
|
|
33 from orpg.dieroller.base import die_rollers
|
|
34
|
|
35 class roller_manager(object):
|
|
36 def __new__(cls):
|
|
37 it = cls.__dict__.get("__it__")
|
|
38 if it is not None: return it
|
|
39 cls.__it__ = it = object.__new__(cls)
|
|
40 it._init()
|
|
41 return it
|
|
42
|
|
43 def _init(self):
|
|
44 self.setRoller('std')
|
|
45
|
|
46 def setRoller(self, roller_class):
|
|
47 try: self.roller_class = die_rollers[roller_class]
|
|
48 except KeyError: raise Exception("Invalid die roller!")
|
|
49
|
|
50 def getRoller(self):
|
|
51 return self.roller_class.name
|
|
52
|
|
53 def listRollers(self):
|
|
54 return die_rollers.keys()
|
|
55
|
239
|
56 def completeMath(self, matches):
|
|
57 s = matches.group(0)
|
|
58 return str(eval(s))
|
|
59
|
183
|
60 def stdDieToDClass(self, match):
|
239
|
61 s = match.group(0)
|
172
|
62 num_sides = s.split('d')
|
|
63 if len(num_sides) > 1:
|
|
64 num_sides; num = num_sides[0]; sides = num_sides[1]
|
183
|
65 if sides.strip().upper() == 'F': sides = "'f'"
|
|
66 try:
|
|
67 if int(num) > 100 or int(sides) > 10000: return None
|
|
68 except: pass
|
172
|
69 ret = ['(', num.strip(), "**die_rollers['", self.getRoller(), "'](",
|
184
|
70 sides.strip(), '))']
|
|
71 s = ''.join(ret)
|
|
72 return s
|
|
73
|
172
|
74 # Use this to convert ndm-style (3d6) dice to d_base format
|
239
|
75 def convertTheDieString(self, s):
|
|
76 """
|
|
77 Die Roller Changes:
|
|
78 I've made some changes for ease of reading. Below you see the new formula and the old depricated formula. The new formula is easier to understand
|
|
79 and works a little better with math. Try this: [(2+4)+4d(6+8)+(4*4)] with both formulas. Traipse succeeds, Standard (1.7.1) fails.
|
|
80
|
|
81 The new formula deals only with numbers of the Fudge roller. The math has a required process flow, which is unliked currently by me but I am not
|
|
82 going to spend more time on at currently to correct it. It occurs when using paranthesis on the facet. If paranthesis are used no modifier can be added
|
|
83 at the end, but you can added it before the roll.
|
|
84
|
|
85 This is the standard roller formula: (Math D Numbers or Math or Fudge). If that fails the new non_stdDie looks for a regExpression formula inside
|
|
86 the current die roller, set under the name. So all of that bloat to include the english language in the Gilcrease 1.8.0 remains bloat and Traipse's
|
|
87 dice can be liberated to do what they want, where they want, when they want.
|
|
88 """
|
184
|
89 self.result = ''
|
239
|
90 math = '[\(0-9\/\*\-\+\)]+'
|
|
91 reg = re.compile(math+'d\s*([0-9]+|'+math+'|[fF])')
|
|
92
|
|
93 #reg = re.compile("(?:\d+|\([0-9\*/\-\+]+\))\s*[a-zA-Z]+\s*[\dFf]+") ## Original
|
172
|
94 (result, num_matches) = reg.subn(self.stdDieToDClass, s)
|
239
|
95
|
172
|
96 if num_matches == 0 or result is None:
|
239
|
97 reg = re.compile(math)
|
|
98 (result, math_matches) = reg.subn(self.completeMath, s)
|
|
99
|
|
100 if num_matches == 0 or result is None:
|
|
101 try:
|
|
102 reg = re.compile(die_rollers._rollers[self.getRoller()].regExpression)
|
|
103 (result, num_matches) = reg.subn(self.roller_class().non_stdDie, s)
|
|
104 self.result = result
|
172
|
105 except: pass
|
|
106 return result
|
|
107
|
|
108 def proccessRoll(self, s):
|
184
|
109 v = self.convertTheDieString(s)
|
|
110 try: b = str(eval(v))
|
|
111 except:
|
239
|
112 if v == '': b = s
|
184
|
113 else: b = str(v) ##Fail safe for non standard dice.
|
|
114 return b
|
183
|
115
|