started refactoring of dicerolling to use a context-free grammar.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
from typing import Dict
|
||||
import re
|
||||
import numpy as np
|
||||
from dice.dice import Dice
|
||||
|
||||
commands: Dict = {}
|
||||
|
||||
@@ -16,7 +17,6 @@ def command(*commandlist):
|
||||
def handle_command(kwargs):
|
||||
c = kwargs['message'].split()[0]
|
||||
params = kwargs['message'].replace(c, '')
|
||||
params = re.sub(r'\s+', '', params)
|
||||
|
||||
if c in commands:
|
||||
commands[c](kwargs, params)
|
||||
@@ -26,21 +26,9 @@ def handle_command(kwargs):
|
||||
|
||||
@command('/roll')
|
||||
def custom_roll(kwargs, params):
|
||||
pattern = re.compile('(?P<sign>(?:\+|\-)?)(?P<dice_num>\d+)(?i:d)(?P<dice_val>\d+)(?P<maths>(?:(?:\+|\-)\d+)*(?!(?i:d)))')
|
||||
rolls = re.findall(pattern, params)
|
||||
|
||||
rng = np.random.default_rng()
|
||||
results = []
|
||||
for roll in rolls:
|
||||
result = []
|
||||
if int(roll[2]) < 2:
|
||||
result.append(int(roll[2]))
|
||||
else:
|
||||
result.append(rng.integers(1, int(roll[2]), size=int(roll[1])).tolist())
|
||||
result.append(roll[3])
|
||||
results.append(result)
|
||||
print(results)
|
||||
print(f'/roll received {kwargs}. Roll parameters: {params}. Rolls recognized: {rolls}')
|
||||
print(f'Kwargs: {kwargs}. Params: {params}')
|
||||
dice = Dice()
|
||||
print(dice.roll(params))
|
||||
|
||||
|
||||
def error_response(kwargs, params):
|
||||
|
||||
0
dice/__init__.py
Normal file
0
dice/__init__.py
Normal file
75
dice/dice.py
Normal file
75
dice/dice.py
Normal file
@@ -0,0 +1,75 @@
|
||||
import pyparsing
|
||||
import math
|
||||
import operator
|
||||
import numpy as np
|
||||
|
||||
from pyparsing import (
|
||||
Literal,
|
||||
CaselessLiteral,
|
||||
Word,
|
||||
Optional,
|
||||
Group,
|
||||
Forward,
|
||||
nums,
|
||||
ParseException,
|
||||
)
|
||||
|
||||
|
||||
class Dice:
|
||||
|
||||
exprStack = []
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def roll(self, roll_params):
|
||||
self.exprStack[:] = [] # Reset the stack
|
||||
try:
|
||||
results = self.BNF().parseString(roll_params, parseAll=True)
|
||||
except ParseException as pe:
|
||||
print("Parse exception ", str(pe))
|
||||
return
|
||||
except Exception as e:
|
||||
print("Exception ", str(e), self.exprStack)
|
||||
|
||||
return results
|
||||
|
||||
def push_first(self, tokens):
|
||||
self.exprStack.append(tokens[0])
|
||||
|
||||
def BNF(self):
|
||||
|
||||
integer = Word(nums)
|
||||
plus, minus = map(Literal, "+-")
|
||||
|
||||
addop = plus | minus
|
||||
rollop = CaselessLiteral('d')
|
||||
# lowop = CaselessLiteral('l')
|
||||
# highop = CaselessLiteral('h')
|
||||
|
||||
# Define roll as a group
|
||||
roll = Group(Optional(integer, default=1) + rollop + integer)
|
||||
|
||||
expression = Forward()
|
||||
|
||||
operand = (
|
||||
addop[...]
|
||||
+ (
|
||||
# Numbers as a fallback, add everything else as (roll | exception | ...)
|
||||
(roll).setParseAction(self.push_first)
|
||||
| integer
|
||||
)
|
||||
)
|
||||
|
||||
term = operand + (rollop + operand).setParseAction(self.push_first)[...]
|
||||
expression <<= term + (addop + term).setParseAction(self.push_first)[...]
|
||||
bnf = expression
|
||||
|
||||
return bnf
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -4,3 +4,4 @@ flask-cors==3.0.8
|
||||
flask-restful==0.3.8
|
||||
flask-socketio==4.3.1
|
||||
numpy==1.19.1
|
||||
pyparsing==2.4.7
|
||||
Reference in New Issue
Block a user