fix dice parser allow adding dices

This commit is contained in:
Denis-Cosmin Nutiu 2024-01-24 14:10:52 +02:00
parent d0ee7a5e3e
commit 184cb23739
6 changed files with 45 additions and 13 deletions

View file

@ -19,7 +19,7 @@ class DiceCog(commands.Cog):
for index, die in enumerate(die_result.dies):
roll_fields.append(
(
f"- #{index+1} 🎲 ",
f"- #{index+1} 🎲 {die.type}{die.die_number}",
f"Res: {die.result}, Mod: {die.modifier}, Rolls: {die.rolls}",
)
)
@ -47,7 +47,7 @@ class DiceCog(commands.Cog):
die_result: DieExpressionResult = DiceRoller.roll(dice_expression)
embed = disnake.Embed(
title="",
title=f"{die_result.total} !!",
description=f"{dice_expression} = {die_result.total}",
timestamp=datetime.now(),
)

View file

@ -13,6 +13,7 @@ class DieRollResult:
result: int
modifier: int
rolls: typing.List[int]
die_number: int
type: str
@ -66,6 +67,7 @@ class DiceRoller:
result=die.get("result"),
rolls=die.get("rolls"),
type=die.get("type"),
die_number=die.get("die_number"),
)
)
return DieExpressionResult(total=result.get("total"), dies=dies)

View file

@ -8,12 +8,14 @@ DIE_GRAMMAR = """
@@grammar::Die
@@whitespace :: None
start = die:die ~ {op:operator die:die} $;
start = die:die {op:operator die:die} $;
die = [number_of_dies:number] die_type:die_type die_number:number [modifier:die_modifier];
die_modifier = op:operator modifier:number;
operator = '+' | '-' | 'adv' | 'dis';
die_modifier = op:modifier_operator modifier:number;
modifier_operator = '+' | '-';
operator = 'add' | 'sub' | 'adv' | 'dis';
die_type = 'd' | 'zd';

View file

@ -27,9 +27,9 @@ class DieSemantics:
right = die_results.popleft()
operator = operators.popleft()
total = 0
if operator == "+":
if operator == "add":
total = left + right
if operator == "-":
if operator == "sub":
total = left - right
if operator == "adv":
total = max(left, right)
@ -64,6 +64,7 @@ class DieSemantics:
return {
"result": max(sum(rolls) + die_modifier, minimum_value_for_die),
"die_number": die_number,
"type": die_type,
"rolls": rolls,
"modifier": die_modifier,

View file

@ -7,12 +7,16 @@ def test_format_die_result_to_message():
DieExpressionResult(
total=25,
dies=[
DieRollResult(result=10, modifier=5, rolls=[10], type="d"),
DieRollResult(result=15, modifier=0, rolls=[10, 5], type="d"),
DieRollResult(
result=10, modifier=5, rolls=[10], type="d", die_number=20
),
DieRollResult(
result=15, modifier=0, rolls=[10, 5], type="d", die_number=20
),
],
),
)
assert message == [
("- #1 🎲 ", "Res: 10, Mod: 5, Rolls: [10]"),
("- #2 🎲 ", "Res: 15, Mod: 0, Rolls: [10, 5]"),
("- #1 🎲 d20", "Res: 10, Mod: 5, Rolls: [10]"),
("- #2 🎲 d20", "Res: 15, Mod: 0, Rolls: [10, 5]"),
]

View file

@ -55,6 +55,29 @@ def test_die_roller_die_roll_simple(expression, range_min, range_max, dice_rolle
assert range_min <= result <= range_max
@pytest.mark.parametrize(
"expression, range_min, range_max",
[
# normal roll
("d20 add d20", 1, 40),
("d20+0 add d20", 1, 40),
("d20+0 adv d20", 1, 20),
("d20+0 adv 2d20", 1, 40),
("d20+0 adv 2zd20", 1, 40),
("d20+0 dis 2d12", 1, 20),
("d20+0 add 2d20+2", 1, 62),
("zd20+0 add 2d20+2", 1, 62),
],
)
def test_die_roller_die_roll_compound_simple(
expression, range_min, range_max, dice_roller
):
# let the dies roll...
for i in range(100):
result = dice_roller.roll_simple(expression)
assert range_min <= result <= range_max
@pytest.mark.parametrize(
"expression, range_min, range_max",
[
@ -124,6 +147,6 @@ def test_die_roller_die_parsing_fail(expression, dice_roller):
def test_die_roller_roll(dice_roller):
for i in range(100):
result = dice_roller.roll("d20 + d20 adv d20+5 dis d12+3")
result = dice_roller.roll("d20 add d20 adv d20+5 dis d12+3")
assert 1 <= result.total <= 15
assert len(result.dies) == 4