dice.py: Factored string-based dice creation into a @classmethod
This commit is contained in:
parent
eb1c897b96
commit
fb1d1f01a6
82
dice.py
82
dice.py
|
@ -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
|
||||
|
@ -23,7 +60,13 @@ class Dice():
|
|||
self.reroll_times = reroll_times
|
||||
self.times_rolled = 0
|
||||
|
||||
# Rolls the dice, prints the result
|
||||
|
||||
def num_rolls(self):
|
||||
return self.times_rolled
|
||||
|
||||
|
||||
# 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
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user