Sunday 3 February 2008

Dice!

Mindful of the desire to have human readable input where possible, and expose information to players at all times, I wrote a simple parser for dice strings. I'm quite pleased at how well it (eventually) worked, as this is the first time I've created a recursive descent parser in any language.

There's an annoying bug in my grammar, though, which is mandating the top level expression has to be a group or single number. That aside and ignoring the spurious top group, it can happily parse string such as:
5d6-5

But that's a bit dull. It also supports nesting:
(2d4+1)d10

Interpreted as 'roll 2d4, add 1, and then use the result to roll that many d10s'. It also supports dropping of low rolls:
5d7l2

Which simply means roll 5d7 and then discard the lowest two values. The converse also works:
7d12h6

Means roll 7d12, then drop the highest six values.

Today I need to add multiplication and division, plus 'keep high' and 'keep low' as the logical duals to 'drop high' and 'drop low'. These should only be needed when doing expressions like 2d3d6 and needing to ensure that, say, the two highest values should be preserved. I believe that Legend of the Five Rings had similar scheme at some point, and used 'k' to denote 'keep high'. Not sure about the notation for 'keep low' yet. Oh, and I should also fix the grammar and - possibly - think about operator precedence.

Once that's done, I really should look at doing some simple statistical analysis to allow the extraction of min, max, mean and standard deviation from these expressions. Then I need a way to decompose the result to show where all the values come from. Finally, I should have a useful toolbox for describing random events in data, informing the player of what they should expect to see, and hopefully aid development of a game system that is both interesting and transparent.

All in the name of our little polyhedral masters, although surely the more platonic among them object to my positing 'd7', Meh.

No comments: