Add rolling of multiple dices

This commit is contained in:
Simone Baracchi 2020-11-11 19:29:05 +01:00
parent 853a188c1d
commit 8f88408893
1 changed files with 112 additions and 88 deletions

View File

@ -26,8 +26,20 @@ df
df+3
4dF +1
0dF +0
1d4+1d6
1d4+1d6495
1d4+1d4+1d4+1d4
1d4+1dF+1
1d4+1d4+99
d4+d4+1
1d3+1+1d3+1
1d4+3+1d4
1d4+
these other should be rejected:
these other should not match completely:
d
asd
asdq
8d10-
8dF-
3d1F
@ -35,8 +47,11 @@ these other should be rejected:
9d1+1-1
9d-1
-1d3
1d4+1+1
1dn
1a3
+1
-1
"""
class InvalidFormat(Exception):
@ -55,99 +70,108 @@ def roll(dice):
ret = 0
outcome = ''
m = re.search('^([0-9]+)?d([0-9]+|[Ff])\s*(?:([\+\-])([0-9]+))?$', dice)
if m is not None:
# DnD dice
dices = m.group(1)
sides = m.group(2)
bonustype = m.group(3)
bonus = m.group(4)
else:
m = re.finditer('([0-9]+)?d([0-9]+|[Ff])\s*(?:([\+\-])([0-9]+)(?!(?:[0-9]+)?d(?:[0-9]+|[Ff])))?(?:\+?)', dice)
if m is None:
raise InvalidFormat
groups = list(m)
matched = ''.join(x.group() for x in groups)
if dice != matched:
raise InvalidFormat
# check number of sides
sides_int = 0
if sides == 'F' or sides == 'f':
sides = 'F'
else:
try:
sides_int = int(sides)
except:
raise InvalidFormat
if sides_int > 10000:
raise TooManyDices
if sides_int <= 0:
raise InvalidFormat
# check number of dices
dices_int = 0
if dices is None:
if sides == 'F':
dices_int = 4
else:
dices_int = 1
else:
try:
dices_int = int(dices)
except:
raise InvalidFormat
if dices_int > 100:
raise TooManyDices
if dices_int <= 0:
raise InvalidFormat
# check bonus type
bonus_mult = None
if bonustype == None:
pass
elif bonustype == '+':
bonus_mult = 1
elif bonustype == '-':
bonus_mult = -1
else:
raise InvalidFormat
# check bonus
if bonus is not None:
try:
bonus = int(bonus)
if bonus == 0:
bonus = None
bonustype = None
bonus_mult = None
except:
raise InvalidFormat
bonus = None
dice_description = ''
if bonustype is None:
dice_description = '{}d{}'.format(dices_int, sides)
else:
dice_description = '{}d{}{}{}'.format(dices_int, sides, bonustype, bonus)
dices_list = []
for g in groups:
if g.group(4) is not None:
bonus = 0 if bonus is None else bonus
try:
if g.group(3) == '+':
bonus += int(g.group(4))
elif g.group(3) == '-':
bonus -= int(g.group(4))
else:
raise InvalidFormat
except:
raise InvalidFormat
# roll dice
if sides == 'F':
# Fate dice
for i in range(0, dices_int):
value = random.randint(-1, 1)
ret += value;
if value == -1:
outcome += ''
if value == 0:
outcome += ''
if value == 1:
outcome += ''
else:
# DnD dice
lista = []
for x in range(0, dices_int):
value = random.randint(1, sides_int);
ret += value
lista.append(str(value))
outcome = '+'.join(lista)
dices_list.append((g.group(1), g.group(2)))
if bonus_mult is not None and bonus is not None:
ret += bonus_mult * bonus
outcome += '(' + bonustype + str(bonus) + ')'
for dice in dices_list:
dices = dice[0]
sides = dice[1]
# check number of sides
sides_int = 0
if sides == 'F' or sides == 'f':
sides = 'F'
else:
try:
sides_int = int(sides)
except:
raise InvalidFormat
if sides_int > 10000:
raise TooManyDices
if sides_int <= 0:
raise InvalidFormat
# check number of dices
dices_int = 0
if dices is None:
if sides == 'F':
dices_int = 4
else:
dices_int = 1
else:
try:
dices_int = int(dices)
except:
raise InvalidFormat
if dices_int > 100:
raise TooManyDices
if dices_int <= 0:
raise InvalidFormat
if dice_description is not '':
dice_description += '+'
dice_description += '{}d{}'.format(dices_int, sides)
# roll dice
if sides == 'F':
# Fate dice
for i in range(0, dices_int):
value = random.randint(-1, 1)
ret += value;
if value == -1:
outcome += ''
if value == 0:
outcome += ''
if value == 1:
outcome += ''
else:
# DnD dice
lista = []
for x in range(0, dices_int):
value = random.randint(1, sides_int);
ret += value
lista.append(str(value))
if outcome != '':
outcome += '+'
if len(dices_list) > 1 and dices_int > 1:
outcome += '('
outcome += '+'.join(lista)
if len(dices_list) > 1 and dices_int > 1:
outcome += ')'
if bonus is not None:
if bonus >= 0:
dice_description += '+{}'.format(bonus)
outcome += '(+{})'.format(bonus)
else:
dice_description += '{}'.format(bonus)
outcome += '({})'.format(bonus)
ret += bonus
return dice_description, ret, outcome