Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement "World of Darkness" style dice pool rolling #5

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ A [maubot](https://github.com/maubot/maubot) that rolls dice. Has built-in calcu
## Usage
The base command is `!roll`. To roll dice, pass `XdY` as an argument, where `X`
is the number of dice (optional) and `Y` is the number of sides in each dice.
Additionally, you can use `XwodY` to roll a pool of `X` ten sided dice and
compare them against the threshold of `Y` and subtracting all natural ones from
the result.
Most Python math and bitwise operators and basic `math` module functions are
also supported, which means you can roll different kinds of dice and combine
the results however you like.
29 changes: 25 additions & 4 deletions dice.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
from maubot import Plugin, MessageEvent
from maubot.handlers import command

pattern_regex = re.compile("([0-9]{0,9})[dD]([0-9]{1,9})")
pattern_regex = re.compile("([0-9]{0,9})([dD]|[wW][oO][dD])([0-9]{1,9})")

_OP_MAP = {
ast.Add: operator.add,
Expand Down Expand Up @@ -227,10 +227,31 @@ def randomize(number: int, size: int) -> int:
_result = int(random.gauss(mean, math.sqrt(variance)))
return _result

def wod_pool(pool: int, threshold: int) -> int:
if pool < 0 or threshold < 0:
raise ValueError("wodPool() only accepts non-negative values")
if pool == 0:
return 0
botches = 0
successes = 0
for i in range(pool):
roll = randomize(1, 10)
if roll >= threshold:
successes += 1
elif roll == 1:
botches += 1
return successes - botches

def replacer(match: Match) -> str:
number = int(match.group(1) or "1")
size = int(match.group(2))
return str(randomize(number, size))
mode = match.group(2)
if mode.lower() == 'd':
number = int(match.group(1) or "1")
size = int(match.group(3))
return str(randomize(number, size))
elif mode.lower() == 'wod':
pool = int(match.group(1) or "1")
threshold = int(match.group(3) or "1")
return str(wod_pool(pool, threshold))

pattern = pattern_regex.sub(replacer, pattern)
try:
Expand Down