News:

Forum changes: Editing of posts has been turned off until further notice.

Main Menu

Sorcerer dice-rolling tool in Python

Started by J B Bell, December 30, 2001, 09:35:00 PM

Previous topic - Next topic

J B Bell

Here's a little dice utility for Sorcerer rolls written in Python, & therefore useable on Unix or Windows (and possibly Mac, not sure if there's python for it or not).  I hope folks find it potentially useful; it's not a full-fledged GM aid, but could easily be expanded into one.  In fact, if anyone familiar with Tkinter or wxPython would like to help me have a crack at it, please email me.

Without further ado, the code:


def rollGen(dice, sides):
   """Generate sequences of rolls, ordered from highest to lowest"""
   import random
   result = []
   for i in range(1, dice+1):
       face = random.randrange(1, sides+1)
       result.append(face)
   result.sort()
   result.reverse()
   return result

def rollComp(a, b):
   """Compare two Sorcerer rolls.  Can be used as an argument to sort().  It
      returns the # of victories--if positive, a's victories, if negative,
      b's.  0 in case of a tie, of course."""
   # My instincts tell me the following is heinous.  It's not necessary if
   # rolls are coming from rollGen(), but we like to be agnostic.
   for var in ('a', 'b'):
       for op in ('sort', 'reverse'):
           exec "%s.%s()" % (var,op)
   rolls = map(None, a, b)  # [1,2] and [3,4] become [ (1,3), (2,4) ]
   # In cases where one roll is only one die, victory goes to the one with
   # more dice
   if a[0] == b[0] and (len(a) == 1 or len(b) == 1):
       diff = len(a) - len(b)
       if diff == 0:
           return 0
       winner = diff/abs(diff)
       return winner * diff / diff
   curr = [None,None]   # Pair of results under examination at the moment
   winner = None
   victories = 0
   for pair in rolls:
       for die in (0,1):
           if pair[die] is not None:
               curr[die] = pair[die]
       diff = curr[0] - curr[1]
       if diff == 0:
           continue
       if winner is None:
           winner = diff/abs(diff)
       if diff * winner > 0:
           victories += winner * diff / diff
       else:
           break
   return victories


(Edited a bit later to eliminate a div. by 0 in the one-die special case)

[ This Message was edited by: TQuid on 2001-12-31 03:47 ]
"Have mechanics that focus on what the game is about. Then gloss the rest." --Mike Holmes

Ron Edwards

Hi TQuid, and welcome to the Forge!

I like the engine. I'm not programming jock enough to tell, but am I correct that it doesn't "eliminate" high ties to determine the actual victory conditions from the remainder of the dice?

The test would be to use Fritz and Fred from the Chapter 1 examples.

Oh yes, and another application would be to generate user-friendly steps through combat. So everyone rolls, and the program tells you what order they all go in. Then you can enter defensive rolls and designate which moves are aborted, and new bonus dice, etc - and then we can get the outcomes of all the conflicts, again in order.

But Christmas is over, isn't it, and I shouldn't be greedy. Thanks for what you've presented so far.

Best,
Ron


J B Bell

Quote
On 2001-12-31 01:15, Ron Edwards wrote:
Hi TQuid, and welcome to the Forge!

As they say, "Thanks Ron, it's a pleasure to be here."  :)

Quote
I like the engine. I'm not programming jock enough to tell, but am I correct that it doesn't "eliminate" high ties to determine the actual victory conditions from the remainder of the dice?

The test would be to use Fritz and Fred from the Chapter 1 examples.

OK:


>>> from sorcroller import *
>>> fred = [8, 5, 5, 2]
>>> fritz = [8, 7, 6, 1]
>>> rollComp(fred, fritz)
-2


That matches the book's example, assuming I've located the issue you meant to be talking about.  This is what the "if diff == 0: continue" line is about.

Quote
Oh yes, and another application would be to generate user-friendly steps through combat. So everyone rolls, and the program tells you what order they all go in. Then you can enter defensive rolls and designate which moves are aborted, and new bonus dice, etc - and then we can get the outcomes of all the conflicts, again in order.

What I envision is a window that has a line for each combatant, and on each of these lines, a space for # of dice, the name of the combatant, and their current roll.  To handle the one-die "lump it" roll, I'd need a pop-up of some kind, since you want to keep the original roll.  To defend, you could just click a "re-roll" button on the line.  To compare any two rolls, click one line (or a checbox on it or something) and then another, and you'd get a pop-up saying, e.g. "Fritz beats Fred with 4 victories--Total Victory!"

Then once you've compared all the rolls you need to, and changed the # of dice by each combatant as necessary, you click the big "re-roll everyone" button at the bottom, and the window refreshes with everyone in proper order.

This is clearly doable, but I've never done a GUI before, so I may be a little while getting it finished.  Thus my plea for mentors.  :)

Quote
But Christmas is over, isn't it, and I shouldn't be greedy. Thanks for what you've presented so far.

Well, not to gush too much, but Sorcerer and the reading here it led me to have totally changed how I look at gaming, and really released a big burden of frustration & feelling incompetent.  I played for years with a great group that had drifted from Simulationism to Narrativism, and I was going insane being unable to reproduce all that pleasure, because all the explicit negotiating I did with players was around genre and world-creation . . . well, once I get some Actual Play in (we're setting up characters and such next weekend), I plan to post a suitably emotional tale of How Ron Saved My Gaming Life.  So I figure I owe you, but merry Christmas and a happy New Year anyway.  :)

J B Bell (TQuid)

[ This Message was edited by: TQuid on 2001-12-31 02:25 ]

[ This Message was edited by: TQuid on 2001-12-31 03:42 ]
"Have mechanics that focus on what the game is about. Then gloss the rest." --Mike Holmes

Bailywolf


Please forgive my ignorance, my programing experience begins with visual basic (pretty good) and ends with Java (painfuly bad).  I'm not familiar with python... perhaps a quick description of the language?


I wrote a quick and dirty VB app for sorcerer dice.  Just two drop-down combo boxes for number of dice (figuring in roleplaying and other bonuses and penalties).  It then generates random numbers (using 10 siders as the hard-coded default), compares, drops the high matches, then gives victories or indicates total victory.  

results display in a picbox, and one button clears and runs the dice-roll, the other ends the program.

Shamefuly, I didn't use any kind of advanced programing techniques, and just dumped the code directly behind the controls.  

Sorcerer has very computer-friendly dice mechanics.


J B Bell

Quote
On 2001-12-31 08:04, Bailywolf wrote:

Please forgive my ignorance, my programing experience begins with visual basic (pretty good) and ends with Java (painfuly bad).  I'm not familiar with python... perhaps a quick description of the language?

Hm.  Well, I'm a bit of a zealot for it, but I'll try to describe it beyond "Python is the Way and the Light."

Python has numerous cool built-in types.  It's more or less object oriented, though someone used to procedural programming can mostly ignore that.  It's fascist about style (the indentations have meaning; note the lack of command terminators), which some love, and others hate.  I like it, it forces you to write more readable code.  It has a lot of really excellent modules that come with the core distro., and many others available.  One of its coolest features is that any program you write can be loaded as a module without any modification, so you get very easy code re-use.  I could go on, but check out http://www.python.org and go through the tutorial there.  If you have any programming experience at all, you should find it very easy to pick up (another advantage--and it's also a fine first language, too).

Quote
I wrote a quick and dirty VB app for sorcerer dice.  Just two drop-down combo boxes for number of dice (figuring in roleplaying and other bonuses and penalties).  It then generates random numbers (using 10 siders as the hard-coded default), compares, drops the high matches, then gives victories or indicates total victory.

This program does more or less that, but lets you do it for an arbitrary number of rolls.  But it ain't graphical, and that's what I want.  Unfortunately, docs for Tkinter (the default Python GUI thingy) and wxPython (a different one) are pretty sketchy to this beginner's mind.  I may just skip all that entirely and go grab a book on Palm development today, though.

(Some stuff deleted for brevity)

QuoteSorcerer has very computer-friendly dice mechanics.

Well, once you figure out how to read across the dice roll arrays, yep, pretty friendly.  The one-die-loses-to-more-dice-if-it-ties exception is a bit gnarly, but not bad.

One thing I think I've just noticed is that penalizing someone one die, or giving their opponent (or difficulty) a bonus die, appears to be statistically identical.  This is nice, and further shows how excellent Ron's work on "currency" is.
"Have mechanics that focus on what the game is about. Then gloss the rest." --Mike Holmes