diceroller.py: Refactored Dice object into its own library under lib/
This commit is contained in:
parent
9f740180a8
commit
796a26c3b3
78
diceroller.py
Executable file
78
diceroller.py
Executable file
|
@ -0,0 +1,78 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
#
|
||||||
|
# Command-line dice roller
|
||||||
|
|
||||||
|
import sys
|
||||||
|
sys.path.append('lib/')
|
||||||
|
|
||||||
|
from dice import Dice
|
||||||
|
import random
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
|
||||||
|
# This takes command-line input as dice description strings
|
||||||
|
# and builds a list of Dice objects
|
||||||
|
def parse_input(args):
|
||||||
|
dice_list = []
|
||||||
|
for arg in args:
|
||||||
|
dice_list.append(Dice.from_str(arg))
|
||||||
|
|
||||||
|
return dice_list
|
||||||
|
|
||||||
|
|
||||||
|
def parse_args():
|
||||||
|
parser = argparse.ArgumentParser(description='Roll dice based on descriptions passed in on the command line', formatter_class=argparse.RawTextHelpFormatter)
|
||||||
|
parser.add_argument('--repeat', '-r', metavar='N', type=int, default=1, help='repeat the given rolls N times')
|
||||||
|
parser.add_argument('--verbose', '-v', action='store_true', help='print detailed information about each roll')
|
||||||
|
parser.add_argument('dice', nargs=argparse.REMAINDER, help="""
|
||||||
|
Dice are input in the following form:
|
||||||
|
|
||||||
|
XdY[modifiers]
|
||||||
|
|
||||||
|
This will roll X Y-sided dice and apply the specified modifiers.
|
||||||
|
|
||||||
|
Modifiers can be any of the following (where N and M are integers):
|
||||||
|
|
||||||
|
(+|-)N Add or subtract N from the total
|
||||||
|
lN Drop the lowest-rolling N dice from the total
|
||||||
|
hN Drop the highest-rolling N dice from the total
|
||||||
|
rN[xM] Any dice that roll <= N will be rerolled.
|
||||||
|
If the optional 'xM' option is specified, dice will be rerolled a maximum of M times.
|
||||||
|
Otherwise each die will be rerolled until the result is > N
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
1d20+5 roll 1 twenty-sided die, and add 5 to the result
|
||||||
|
6d6l1h1 roll 6 six-sided dice, and drop both the highest and the lowest roll
|
||||||
|
4d6l1r2x1 roll 4 six-sided dice. Any dice rolling a 1 or 2 will be rerolled once.
|
||||||
|
If the result is still 1 or 2 it is kept. The lowest die is dropped from the result
|
||||||
|
""")
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
settings = parse_args()
|
||||||
|
dice_list = parse_input(settings.dice)
|
||||||
|
|
||||||
|
for i in range(settings.repeat):
|
||||||
|
for dice in dice_list:
|
||||||
|
ret = dice.roll()
|
||||||
|
|
||||||
|
if settings.verbose:
|
||||||
|
drop_info = ''
|
||||||
|
reroll_info = ''
|
||||||
|
|
||||||
|
if ret['dropped']:
|
||||||
|
drop_info = ' [dropped {}]'.format(','.join(['{}'.format(x) for x in ret['dropped']]))
|
||||||
|
if ret['rerolled']:
|
||||||
|
reroll_info = ' [rerolled {}]'.format(','.join(['{}'.format(x) for x in ret['rerolled']]))
|
||||||
|
|
||||||
|
print('{dice}: {rolls}{drop}{reroll} {total}'.format(dice=dice, rolls=ret['rolls'], total=ret['total'], drop=drop_info, reroll=reroll_info))
|
||||||
|
|
||||||
|
else:
|
||||||
|
print('{dice}: {total}'.format(dice=dice, total=ret['total']))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
81
dice.py → lib/dice.py
Executable file → Normal file
81
dice.py → lib/dice.py
Executable file → Normal file
|
@ -1,17 +1,14 @@
|
||||||
#!/usr/bin/python
|
# dice.py
|
||||||
#
|
#
|
||||||
# Command-line dice roller
|
# This module contains a class to represent various RPG-style dice expressions.
|
||||||
|
# These can then be rolled and the results, both total and individual rolls, returned.
|
||||||
#
|
#
|
||||||
# It assumes that the Mersenne Twister is acceptable.
|
# This module assumes that the built-in python PRNG (Mersenne Twister) is acceptable.
|
||||||
# Support for real entropy is an RFE
|
# Support for real entropy is an RFE.
|
||||||
|
|
||||||
import random
|
import random
|
||||||
import sys
|
|
||||||
import re
|
import re
|
||||||
import argparse
|
|
||||||
|
|
||||||
|
|
||||||
# Implements a "dice" - that is, a series of dice plus modifiers
|
|
||||||
class Dice():
|
class Dice():
|
||||||
# This builds dice out of a simple input format
|
# This builds dice out of a simple input format
|
||||||
# All of the dark regex magic is contained to this function,
|
# All of the dark regex magic is contained to this function,
|
||||||
|
@ -132,71 +129,3 @@ class Dice():
|
||||||
mod_info = '-{}'.format(self.mod)
|
mod_info = '-{}'.format(self.mod)
|
||||||
|
|
||||||
return "{num}d{sides}{mod}{drop}{reroll}".format(num=self.num, sides=self.sides, mod=mod_info, drop=drop_info, reroll=reroll_info)
|
return "{num}d{sides}{mod}{drop}{reroll}".format(num=self.num, sides=self.sides, mod=mod_info, drop=drop_info, reroll=reroll_info)
|
||||||
|
|
||||||
|
|
||||||
# This takes command-line input as dice description strings
|
|
||||||
# and builds a list of Dice objects
|
|
||||||
def parse_input(args):
|
|
||||||
dice_list = []
|
|
||||||
for arg in args:
|
|
||||||
dice_list.append(Dice.from_str(arg))
|
|
||||||
|
|
||||||
return dice_list
|
|
||||||
|
|
||||||
|
|
||||||
def parse_args():
|
|
||||||
parser = argparse.ArgumentParser(description='Roll dice based on descriptions passed in on the command line', formatter_class=argparse.RawTextHelpFormatter)
|
|
||||||
parser.add_argument('--repeat', '-r', metavar='N', type=int, default=1, help='repeat the given rolls N times')
|
|
||||||
parser.add_argument('--verbose', '-v', action='store_true', help='print detailed information about each roll')
|
|
||||||
parser.add_argument('dice', nargs=argparse.REMAINDER, help="""
|
|
||||||
Dice are input in the following form:
|
|
||||||
|
|
||||||
XdY[modifiers]
|
|
||||||
|
|
||||||
This will roll X Y-sided dice and apply the specified modifiers.
|
|
||||||
|
|
||||||
Modifiers can be any of the following (where N and M are integers):
|
|
||||||
|
|
||||||
(+|-)N Add or subtract N from the total
|
|
||||||
lN Drop the lowest-rolling N dice from the total
|
|
||||||
hN Drop the highest-rolling N dice from the total
|
|
||||||
rN[xM] Any dice that roll <= N will be rerolled.
|
|
||||||
If the optional 'xM' option is specified, dice will be rerolled a maximum of M times.
|
|
||||||
Otherwise each die will be rerolled until the result is > N
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
|
|
||||||
1d20+5 roll 1 twenty-sided die, and add 5 to the result
|
|
||||||
6d6l1h1 roll 6 six-sided dice, and drop both the highest and the lowest roll
|
|
||||||
4d6l1r2x1 roll 4 six-sided dice. Any dice rolling a 1 or 2 will be rerolled once.
|
|
||||||
If the result is still 1 or 2 it is kept. The lowest die is dropped from the result
|
|
||||||
""")
|
|
||||||
return parser.parse_args()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
settings = parse_args()
|
|
||||||
dice_list = parse_input(settings.dice)
|
|
||||||
|
|
||||||
for i in range(settings.repeat):
|
|
||||||
for dice in dice_list:
|
|
||||||
ret = dice.roll()
|
|
||||||
|
|
||||||
if settings.verbose:
|
|
||||||
drop_info = ''
|
|
||||||
reroll_info = ''
|
|
||||||
|
|
||||||
if ret['dropped']:
|
|
||||||
drop_info = ' [dropped {}]'.format(','.join(['{}'.format(x) for x in ret['dropped']]))
|
|
||||||
if ret['rerolled']:
|
|
||||||
reroll_info = ' [rerolled {}]'.format(','.join(['{}'.format(x) for x in ret['rerolled']]))
|
|
||||||
|
|
||||||
print('{dice}: {rolls}{drop}{reroll} {total}'.format(dice=dice, rolls=ret['rolls'], total=ret['total'], drop=drop_info, reroll=reroll_info))
|
|
||||||
|
|
||||||
else:
|
|
||||||
print('{dice}: {total}'.format(dice=dice, total=ret['total']))
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
|
@ -12,14 +12,14 @@ A battle manager - keeps track of initiative order, hit points, and conditions f
|
||||||
Battleman also aas a sense of whose turn it is, and prints a convenient message telling you who now has initiative when you enter the 'next' command.
|
Battleman also aas a sense of whose turn it is, and prints a convenient message telling you who now has initiative when you enter the 'next' command.
|
||||||
|
|
||||||
|
|
||||||
### dice.py
|
### diceroller.py
|
||||||
A robust command-line dice-rolling utility. Many others exist, of course, but this one accepts all of its arguments as command-line parameters, making it a simple and intuitive interface.
|
A robust command-line dice-rolling utility. Many others exist, of course, but this one accepts all of its arguments as command-line parameters, making it a simple and intuitive interface for Linux types.
|
||||||
|
|
||||||
|
|
||||||
## For programmers
|
## For programmers
|
||||||
|
|
||||||
### dice.py
|
### dice
|
||||||
When treated as a library, provides a robust Dice class with a convenient from_str() classmethod.
|
A module that provides a robust Dice class with a convenient from_str() classmethod.
|
||||||
|
|
||||||
|
|
||||||
### battle
|
### battle
|
||||||
|
|
Loading…
Reference in New Issue
Block a user