Skip to Content

DIC52 Week 4: Python Syndicate content

Dave Sherohman's picture

For this week, I've written up an Ars Magica die roller. Ars Magica's dice conventions are unique, using three different types of rolls, all of which are based on ten-sided dice:

  • Simple Roll: This is just your basic d10 roll with 0 read as 10.
  • Quality Roll: In a quality roll, 2-10 are read normally, but a roll of 1 means to re-roll, doubling the result. Further rolls of 1 will repeatedly double the final result, allowing for arbitrarily high rolls. For example, rolling 1-1-1-7 is read as 56 (7, doubled three times).
  • Stress Roll: Stress rolls are basically like quality rolls, but with the potential for very bad results as well as very good. A stress die is rolled just like a quality die, except that, if the initial roll is a 0, the total of the roll is 0, regardless of any modifiers, and the die is rerolled to determine whether you have botched your attempted action. Under poor circumstances, additional botch dice may be called for. If any botch die comes up 0, something bad has happened in addition to having failed. If multiple botch dice are rolled and more than one 0 is rolled, each 0 makes the result even worse.

These descriptions provide the basic outline of how the die roller functions. With such a limited set of rolling options, it's practically a given that rolls will almost always have modifiers applied, so the roller accepts them along with the type of roll. In order to save less-mathematical users from having to total up the modifiers, I decided to allow for entering multiple modifiers, which the roller will total up for you.

The final format for specifying rolls, then, is:

  • The first character indicates the type of roll to make. "S" for a stress roll, "Q" for a quality roll, or anything else for a simple roll.
  • Any number of modifiers to the roll may be specified as +N or -N. The base modifier starts at 0.
  • Any number of adjustments to the number of botch dice may be specified as +Nb or -Nb. The number of botch dice starts at 1 and will never be less than 1, regardless of reductions.

    Examples:

    • +3: A simple roll at +3
    • q+3 -5: A quality roll at -2
    • s +3 -1b -5 +3b +12: A stress roll at +10 with 3 botch dice
    • (no input): A simple roll with no modifiers

    #!/usr/bin/python
    
    import random
    import re
    
    def simple_roll(modifier):
      value = random.randint(1, 10)
      print value
      return value + modifier
    
    def quality_roll(modifier):
      value = simple_roll(0)
      if value == 1:
        value = 2 * quality_roll(0)
      return value + modifier
    
    def check_botch(botch_dice):
      botches = 0
      if botch_dice < 1: botch_dice = 1
      for i in range(0, botch_dice):
        if simple_roll(0) == 10: botches += 1
      if botches == 0: return 0
      if botches == 1: return '1 botch'
      return str(botches) + ' botches'
    
    def stress_roll(modifier, botch_dice):
      value = simple_roll(0)
      if value == 10:
        return check_botch(botch_dice)
      if value == 1:
        value = 2 * quality_roll(0)
      return value + modifier
    
    
    print """Ars Magica die roller
    Rolls a simple die by default.  Begin input with "s" for stress die or "q"
    for quality die.  Any number of additions or subtractions to the roll may
    be specified as +N or -N.  For stress rolls, +Nb and -Nb may also be used
    to modify the number of botch dice.
    """
    
    try:
      while 1:
        modifier = 0
        botch_dice = 1
        die_spec = raw_input('> ')
    
        for mod in re.finditer('([+-]\d+)([Bb]?)', die_spec):
          if mod.group(2): botch_dice += int(mod.group(1))
          else:            modifier   += int(mod.group(1))
    
        if   re.match('[Ss]', die_spec):
          result = stress_roll(modifier, botch_dice)
        elif re.match('[Qq]', die_spec):
          result = quality_roll(modifier)
        else:
          result = simple_roll(modifier)
    
        print 'Result: ', result
    except EOFError:
      print
    

    Post new comment