move the generic roll result code into a common place
Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
"""Roll dice when asked, intended for RPGs."""
|
||||
import logging
|
||||
import random
|
||||
import re
|
||||
|
||||
from django.conf import settings
|
||||
from irc.client import NickMask
|
||||
|
||||
+97
@@ -126,6 +126,103 @@ def cypher_result(difficulty, modifier, is_attack, stat, comment, ircify=False):
|
||||
return f"{comment} {result_str} {detail_str}"
|
||||
|
||||
|
||||
def generic_roll(keep, dice, size):
|
||||
"""Takes the parsed dice string for a single roll (eg 3/4d20) and performs
|
||||
the actual roll. Returns a string representing the result.
|
||||
"""
|
||||
|
||||
a = list(range(dice))
|
||||
for i in range(dice):
|
||||
a[i] = random.randint(1, size)
|
||||
if keep != dice:
|
||||
b = sorted(a, reverse=True)
|
||||
b = b[0:keep]
|
||||
else:
|
||||
b = a
|
||||
total = sum(b)
|
||||
outstr = "[" + ",".join(str(i) for i in a) + "]"
|
||||
|
||||
return (total, outstr)
|
||||
|
||||
|
||||
def generic_result(trials, mods, comment, ircify):
|
||||
"""Processes rolls coming from the parser.
|
||||
|
||||
This generates the inputs for the generic_roll() command, and returns
|
||||
the full string representing the whole current dice string (the part
|
||||
up to a semicolon or end of line).
|
||||
"""
|
||||
rolls = mods[0][0][1] if mods[0][0][1] else 1
|
||||
if trials:
|
||||
assert trials <= 30, "Too many rolls (max: 30)."
|
||||
assert rolls <= 50, "Too many dice (max: 50) in roll."
|
||||
|
||||
output = ""
|
||||
repeat = 1
|
||||
if trials is not None:
|
||||
repeat = trials
|
||||
for i in range(repeat):
|
||||
mode = 1
|
||||
total = 0
|
||||
curr_str = ""
|
||||
if i > 0:
|
||||
output += ", "
|
||||
for m in mods:
|
||||
keep = 0
|
||||
dice = 1
|
||||
res = 0
|
||||
# if m is a tuple, then it is a die roll
|
||||
# m[0] = (keep, num dice)
|
||||
# m[1] = num faces on the die
|
||||
if type(m) == tuple:
|
||||
if m[0] is not None:
|
||||
if m[0][0] is not None:
|
||||
keep = m[0][0]
|
||||
dice = m[0][1]
|
||||
size = m[1]
|
||||
if keep > dice or keep == 0:
|
||||
keep = dice
|
||||
if size < 1:
|
||||
output = "# of sides for die is incorrect: %d" % size
|
||||
return output
|
||||
if dice < 1:
|
||||
output = "# of dice is incorrect: %d" % dice
|
||||
return output
|
||||
res = generic_roll(keep, dice, size)
|
||||
curr_str += "%d%s" % (res[0], res[1])
|
||||
res = res[0]
|
||||
elif m == "+":
|
||||
mode = 1
|
||||
curr_str += "+"
|
||||
elif m == "-":
|
||||
mode = -1
|
||||
curr_str += "-"
|
||||
else:
|
||||
res = m
|
||||
curr_str += str(m)
|
||||
total += mode * res
|
||||
if repeat == 1:
|
||||
if comment is not None:
|
||||
if ircify:
|
||||
output = "%d %s 14(%s)" % (total, comment.strip(), curr_str)
|
||||
else:
|
||||
output = "%d %s (%s)" % (total, comment.strip(), curr_str)
|
||||
else:
|
||||
if ircify:
|
||||
output = "%d 14(%s)" % (total, curr_str)
|
||||
else:
|
||||
output = "%d (%s)" % (total, curr_str)
|
||||
else:
|
||||
if ircify:
|
||||
output += "%d 14(%s)" % (total, curr_str)
|
||||
else:
|
||||
output += "%d (%s)" % (total, curr_str)
|
||||
if i == repeat - 1:
|
||||
if comment is not None:
|
||||
output += " (%s)" % (comment.strip())
|
||||
return output
|
||||
|
||||
|
||||
def reaction_roll():
|
||||
"""Make a reaction roll, which gives some oracle-like randomness to uncertain situations (for solo play or similar).
|
||||
|
||||
|
||||
+2
-98
@@ -1,6 +1,5 @@
|
||||
"""Dice rollers used by the views, bots, etc."""
|
||||
import logging
|
||||
import random
|
||||
import re
|
||||
|
||||
import ply.lex as lex
|
||||
@@ -52,101 +51,6 @@ class DiceRoller(object):
|
||||
|
||||
output = ""
|
||||
|
||||
def roll_dice(self, keep, dice, size):
|
||||
"""Takes the parsed dice string for a single roll (eg 3/4d20) and performs
|
||||
the actual roll. Returns a string representing the result.
|
||||
"""
|
||||
|
||||
a = list(range(dice))
|
||||
for i in range(dice):
|
||||
a[i] = random.randint(1, size)
|
||||
if keep != dice:
|
||||
b = sorted(a, reverse=True)
|
||||
b = b[0:keep]
|
||||
else:
|
||||
b = a
|
||||
total = sum(b)
|
||||
outstr = "[" + ",".join(str(i) for i in a) + "]"
|
||||
|
||||
return (total, outstr)
|
||||
|
||||
def process_roll(self, trials, mods, comment):
|
||||
"""Processes rolls coming from the parser.
|
||||
|
||||
This generates the inputs for the roll_dice() command, and returns
|
||||
the full string representing the whole current dice string (the part
|
||||
up to a semicolon or end of line).
|
||||
"""
|
||||
rolls = mods[0][0][1] if mods[0][0][1] else 1
|
||||
if trials:
|
||||
assert trials <= 30, "Too many rolls (max: 30)."
|
||||
assert rolls <= 50, "Too many dice (max: 50) in roll."
|
||||
|
||||
output = ""
|
||||
repeat = 1
|
||||
if trials is not None:
|
||||
repeat = trials
|
||||
for i in range(repeat):
|
||||
mode = 1
|
||||
total = 0
|
||||
curr_str = ""
|
||||
if i > 0:
|
||||
output += ", "
|
||||
for m in mods:
|
||||
keep = 0
|
||||
dice = 1
|
||||
res = 0
|
||||
# if m is a tuple, then it is a die roll
|
||||
# m[0] = (keep, num dice)
|
||||
# m[1] = num faces on the die
|
||||
if type(m) == tuple:
|
||||
if m[0] is not None:
|
||||
if m[0][0] is not None:
|
||||
keep = m[0][0]
|
||||
dice = m[0][1]
|
||||
size = m[1]
|
||||
if keep > dice or keep == 0:
|
||||
keep = dice
|
||||
if size < 1:
|
||||
output = "# of sides for die is incorrect: %d" % size
|
||||
return output
|
||||
if dice < 1:
|
||||
output = "# of dice is incorrect: %d" % dice
|
||||
return output
|
||||
res = self.roll_dice(keep, dice, size)
|
||||
curr_str += "%d%s" % (res[0], res[1])
|
||||
res = res[0]
|
||||
elif m == "+":
|
||||
mode = 1
|
||||
curr_str += "+"
|
||||
elif m == "-":
|
||||
mode = -1
|
||||
curr_str += "-"
|
||||
else:
|
||||
res = m
|
||||
curr_str += str(m)
|
||||
total += mode * res
|
||||
if repeat == 1:
|
||||
if comment is not None:
|
||||
if self.ircify:
|
||||
output = "%d %s 14(%s)" % (total, comment.strip(), curr_str)
|
||||
else:
|
||||
output = "%d %s (%s)" % (total, comment.strip(), curr_str)
|
||||
else:
|
||||
if self.ircify:
|
||||
output = "%d 14(%s)" % (total, curr_str)
|
||||
else:
|
||||
output = "%d (%s)" % (total, curr_str)
|
||||
else:
|
||||
if self.ircify:
|
||||
output += "%d 14(%s)" % (total, curr_str)
|
||||
else:
|
||||
output += "%d (%s)" % (total, curr_str)
|
||||
if i == repeat - 1:
|
||||
if comment is not None:
|
||||
output += " (%s)" % (comment.strip())
|
||||
return output
|
||||
|
||||
def p_roll_r(self, p):
|
||||
# Chain rolls together.
|
||||
|
||||
@@ -170,7 +74,7 @@ class DiceRoller(object):
|
||||
mods = p[2]
|
||||
else:
|
||||
mods = [p[2]]
|
||||
p[0] = self.process_roll(p[1], mods, p[3])
|
||||
p[0] = dice.lib.generic_result(p[1], mods, p[3], self.ircify)
|
||||
output = p[0]
|
||||
|
||||
def p_roll_no_trials(self, p):
|
||||
@@ -183,7 +87,7 @@ class DiceRoller(object):
|
||||
mods = p[1]
|
||||
else:
|
||||
mods = [p[1]]
|
||||
p[0] = self.process_roll(None, mods, p[2])
|
||||
p[0] = dice.lib.generic_result(None, mods, p[2], self.ircify)
|
||||
output = p[0]
|
||||
|
||||
def p_cypher_stat(self, p):
|
||||
|
||||
Reference in New Issue
Block a user