update dice parser
This commit is contained in:
parent
a9ea30dec9
commit
1285190ee7
5 changed files with 21 additions and 14 deletions
0
src/__init__.py
Normal file
0
src/__init__.py
Normal file
|
@ -5,18 +5,19 @@ from src.dice.parser import DieParser
|
||||||
|
|
||||||
class DiceRoller:
|
class DiceRoller:
|
||||||
"""
|
"""
|
||||||
DiceRoller is a simple class that allows you to roll dices.
|
DiceRoller is a simple class that allows you to roll dices.
|
||||||
|
|
||||||
A die can be rolled using the following expression:
|
A die can be rolled using the following expression:
|
||||||
- 1d20 will roll a 20-faceted die and output the result a random number between 1 and 20.
|
- 1d20 will roll a 20-faceted die and output the result a random number between 1 and 20.
|
||||||
- 1d100 will roll a 100 faceted die.
|
- 1d100 will roll a 100 faceted die.
|
||||||
- 2d20 will roll a two d20 dies and multiply the result by two.
|
- 2d20 will roll a two d20 dies and multiply the result by two.
|
||||||
- 2d20+5 will roll a two d20 dies and multiply the result by two and ads 5.
|
- 2d20+5 will roll a two d20 dies and multiply the result by two and ads 5.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
_parser = DieParser()
|
_parser = DieParser()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def roll(expression: str, advantage: typing.Optional[bool]) -> int:
|
def roll(expression: str, advantage: typing.Optional[bool] = None) -> int:
|
||||||
"""
|
"""
|
||||||
Roll die and return the result.
|
Roll die and return the result.
|
||||||
:param expression: The die expression.
|
:param expression: The die expression.
|
||||||
|
|
|
@ -8,9 +8,9 @@ DIE_GRAMMAR = """
|
||||||
@@grammar::Die
|
@@grammar::Die
|
||||||
@@whitespace :: None
|
@@whitespace :: None
|
||||||
|
|
||||||
start = die:die [modifier:die_modifier] $;
|
start = die:die $;
|
||||||
|
|
||||||
die = [number_of_dies:number] die_type:die_type die_number:number;
|
die = [number_of_dies:number] die_type:die_type die_number:number [modifier:die_modifier];
|
||||||
die_modifier = op:operator modifier:number;
|
die_modifier = op:operator modifier:number;
|
||||||
|
|
||||||
operator = '+' | '-';
|
operator = '+' | '-';
|
||||||
|
|
|
@ -8,9 +8,7 @@ class DieSemantics:
|
||||||
return int(ast)
|
return int(ast)
|
||||||
|
|
||||||
def start(self, ast):
|
def start(self, ast):
|
||||||
modifier = ast.get("modifier") or 0
|
return ast.get("die")
|
||||||
die = ast.get("die")
|
|
||||||
return die + modifier
|
|
||||||
|
|
||||||
def die(self, ast):
|
def die(self, ast):
|
||||||
if not isinstance(ast, AST):
|
if not isinstance(ast, AST):
|
||||||
|
@ -18,14 +16,22 @@ class DieSemantics:
|
||||||
number_of_dies = ast.get("number_of_dies") or 1
|
number_of_dies = ast.get("number_of_dies") or 1
|
||||||
die_type = ast.get("die_type")
|
die_type = ast.get("die_type")
|
||||||
die_number = ast.get("die_number") or 1
|
die_number = ast.get("die_number") or 1
|
||||||
|
die_modifier = ast.get("modifier") or 0
|
||||||
if die_number <= 0:
|
if die_number <= 0:
|
||||||
return 0
|
return 0
|
||||||
# normal die
|
# normal die
|
||||||
if die_type == "d":
|
if die_type == "d":
|
||||||
return sum([random.randint(1, die_number) for _ in range(number_of_dies)])
|
die_sum = sum(
|
||||||
|
[random.randint(1, die_number) for _ in range(number_of_dies)]
|
||||||
|
)
|
||||||
|
# do not let die to underflow
|
||||||
|
return max(die_sum + die_modifier, 1)
|
||||||
# zero-based die can output 0.
|
# zero-based die can output 0.
|
||||||
if die_type == "zd":
|
if die_type == "zd":
|
||||||
return sum([random.randint(0, die_number) for _ in range(number_of_dies)])
|
die_sum = sum(
|
||||||
|
[random.randint(0, die_number) for _ in range(number_of_dies)]
|
||||||
|
)
|
||||||
|
return max(die_sum + die_modifier, 0)
|
||||||
raise ValueError(f"Invalid die type: {die_type}")
|
raise ValueError(f"Invalid die type: {die_type}")
|
||||||
|
|
||||||
def die_modifier(self, ast):
|
def die_modifier(self, ast):
|
||||||
|
|
0
tests/__init__.py
Normal file
0
tests/__init__.py
Normal file
Loading…
Reference in a new issue