dice.py: Factored string-based dice creation into a @classmethod

This commit is contained in:
Anna Rose 2012-03-21 12:08:58 -04:00
parent eb1c897b96
commit fb1d1f01a6

82
dice.py
View File

@ -13,6 +13,43 @@ import argparse
# Implements a "dice" - that is, a series of dice plus modifiers
class Dice():
# This builds dice out of a simple input format
# All of the dark regex magic is contained to this function,
# lest it corrupt innocent code
@classmethod
def from_desc(cls, desc):
if not re.match(r'^\d+d\d+', desc):
raise Exception('Dice format invalid. See --help')
(n, s) = re.match(r'^(\d+)d(\d+)', desc).groups()
num = int(n)
sides = int(s)
mod = 0
drop_low = 0
drop_high = 0
reroll = 0
reroll_times = 0
for m in re.findall(r'[dD+-]\d+', desc):
if m[0] == '-':
mod += int(m)
elif m[0] == '+':
mod += int(m[1:])
elif m[0] == 'D':
drop_high = int(m[1:])
elif m[0] == 'd':
drop_low = int(m[1:])
m = re.search(r'r(\d+)(x\d+)?', desc)
if m:
(r, rt) = m.groups()
reroll = int(r)
if rt:
reroll_times = int(rt[1:])
return cls(num, sides, mod, drop_low, drop_high, reroll, reroll_times)
def __init__(self, num, sides, mod, drop_low=0, drop_high=0, reroll=0, reroll_times=0):
self.num = num
self.sides = sides
@ -22,8 +59,14 @@ class Dice():
self.reroll = reroll
self.reroll_times = reroll_times
self.times_rolled = 0
def num_rolls(self):
return self.times_rolled
# Rolls the dice, prints the result
# Rolls the dice, returns a structure
# containing the result plus metadata
def roll(self, verbose=False):
results = []
rerolled = []
@ -103,43 +146,12 @@ class Dice():
return "{num}d{sides}{mod}{drop}{reroll}".format(num=self.num, sides=self.sides, mod=mod_info, drop=drop_info, reroll=reroll_info)
# This builds dice out of a simple input format
# All of the dark regex magic is contained to this function,
# lest it corrupt innocent code
# This takes command-line input as dice description strings
# and builds a list of Dice objects
def parse_input(args):
dice_list = []
for arg in args:
if not re.match(r'^\d+d\d+', arg):
continue
(n, s) = re.match(r'^(\d+)d(\d+)', arg).groups()
num = int(n)
sides = int(s)
mod = 0
dlow = 0
dhigh = 0
reroll = 0
reroll_times = 0
for m in re.findall(r'[dD+-]\d+', arg):
if m[0] == '-':
mod += int(m)
elif m[0] == '+':
mod += int(m[1:])
elif m[0] == 'D':
dhigh = int(m[1:])
elif m[0] == 'd':
dlow = int(m[1:])
m = re.search(r'r(\d+)(x\d+)?', arg)
if m:
(r, rt) = m.groups()
reroll = int(r)
if rt:
reroll_times = int(rt[1:])
dice_list.append(Dice(num, sides, mod, drop_low=dlow, drop_high=dhigh, reroll=reroll, reroll_times=reroll_times))
dice_list.append(Dice.from_desc(arg))
return dice_list