New function to combine dice, and use this function for hit dice.

Fixes: https://github.com/canismarko/dungeon-sheets/issues/84
This commit is contained in:
Mark Wolfman
2021-08-08 13:23:15 -05:00
parent 339dd61bce
commit 700541a35d
3 changed files with 42 additions and 2 deletions
+32
View File
@@ -1,10 +1,12 @@
import random
import re
from collections import namedtuple
from itertools import groupby
from dungeonsheets.exceptions import DiceError
dice_re = re.compile(r"(\d+)d(\d+)", flags=re.I)
dice_part_re = re.compile(r"[0-9d]+", flags=re.I)
Dice = namedtuple("Dice", ("num", "faces"))
@@ -25,6 +27,36 @@ def read_dice_str(dice_str):
return dice
def combine_dice(dice_str):
"""Condense a dice string into its simplest representation.
For example: "1d8 + 5 + 2d8 + 2" would be reduced to "3d8 + 7".
Returns
=======
new_dice_str
A new, condensed string for the given dice.
"""
dice = []
bonuses = 0
# Sort out each portion of the dice string
for part in dice_part_re.findall(dice_str):
try:
dice.append(read_dice_str(part))
except DiceError:
bonuses += int(part)
# Recombine the dice into a more concise string
new_parts = []
dice = sorted(dice, key=lambda x: x.faces)
for faces, grp in groupby(dice, key=lambda x: x.faces):
new_parts.append(f"{sum([d.num for d in grp])}d{faces}")
if bonuses > 0:
new_parts.append(str(bonuses))
new_dice_str = " + ".join(new_parts)
return new_dice_str
def roll(a, b=None):
"""roll(20) means roll 1d20, roll(2, 6) means roll 2d6"""
if b is None: