News:

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

Main Menu

Dice distribution calculator

Started by Jasper Flick, May 01, 2009, 12:47:00 PM

Previous topic - Next topic

Guy Srinivasan

1d5*(1d2-1) is a die that has 0 0 0 0 0 1 2 3 4 5 on its 10 faces.

(1d5*(1d2-1))+(1d5*(1d2-1))+(1d5*(1d2-1)) is 3dThat

chance.thirteen

Keen!

Now how about that 5d12 total the best 2d12.

Or add and rerolls on doubles or the highest n values? EG 4d8 add and reroll on 7 and 8, total the best 3?

Jasper Flick

That are some nice suggestions, chance.thirteen!

Absolute values should be a cinch to add.

I've meditated on the classical roll "4d6 drop lowest" and I think I've found a way to include it, though I'm a bit tired at the moment. It's #2 on my ToDo list.

As luck would have it, I just added custom dice, along with some optimizations. So now you can directly enter "3 d {0,0,0,0,0,1,2,3,4,5}". It is easier to read than "(1d5*(1d2-1))+(1d5*(1d2-1))+(1d5*(1d2-1))" and runs faster too! By the way, a fudge die is now simply "1d{-1,0,1}".

I haven't allowed things like "1 d (1 d 4)" yet, though it's easy to add. It basically means "take this distribution and treat is as a single die". The "d" is currently already half an operator, why not go all the way?

But more imporant matters first: counting successes is #1 on my list right now.
Trouble with dice mechanics? Check out AnyDice, my online dice distribution calculator!

chance.thirteen

I have another horrid suggestion.

Basically, its counting successes by dividing your total by some set number. EG, roll 4d10, divide by 6 thats how many successes you get.

The evil hybrid would be set a success threshold number (lets go with 6 on a d10) and 0 for numbers less that 6, and accumulated fractions above 6 (let use say that again this accumulation need to reach 6 before its a full success)

I think this would read {0 0 0 0 0 1 1.16 1.33 1.5 1.66}

so perhaps just sticking with the custom dice approach would be best.


chance.thirteen

Wouldn't traditional success counting just need the creation of a syntax to note the number of sides per die, and what success value would be denoted, but actually just create a custom die?

EG: White Wolf used to roll d10s, success at 6-10.

1d{0,0,0,0,0,1,1,1,1,1}

At one point a 1 was a negative success:

1d{-1,0,0,0,0,1,1,1,1,1}

And in Scion and Exalted, success is at 7-9, with 2 successes on a 10.

1d{0,0,0,0,0,0,1,1,1,2}

Likewise I think someone here proposed a success system where you sued various sizes, but successes were counted only in full increments of 4 so a d6 and a d12 look like this:

1d{0,0,0,1,1,1,}

1d{0,0,0,1,1,1,1,2,2,2,2,3}




Egonblaidd

Heh, try a "dprime", or a d{2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97}, a 25 sided die with all the prime numbers up to 100.  It gets weird when you start doing multiple of them, for example values divisible by 2 almost never come up, regardless of how many you roll (as long as it's more than one).  In fact, when you only throw a few of them, only one in every few values divisible by two even have a chance to come up (for example, if you throw 2 there are no possible even results between 4 and 12).  If you could get your hands on some of these, you could make a special rule for when the result is divisible by 2.  Hmm, I don't think you can have a die with an odd number of sides, but you could get a d26 and just slap a 1 on the extra side (or get a d50 and have each result twice).  Check out what happens when you add a 1 face to the "dprime", though, and make sure to compare throwing an even or odd number of dice.

Now that we can try out custom dice, what other interesting kinds of dice would actually make sense?  You could simulate the rolling of multiple die, as I think someone said, by having multiples of the same value, i.e. d{2, 3, 3, 4, 4, 4, 5, 5, 6} = 2d3, but what other kinds of things could you do?

Now I'm starting to think about non-numerical dice...
I wonder if non-fair dice could be used?  Like a hit location die with a large face for chest hits but a small one for head hits.  The more practical approach seems like it would be to use a fair die with a symbol/value repeated to make it more common.
Phillip Lloyd
<><

Jasper Flick

chance.thirteen:

If I would add integer division you could do something like "1d8 / 4" which would result in {0,0,0,1,1,1,1,2}. So that's what you suggest but without the fractions.

You're right about the success-counts being custom dice (distributions) themselves. In fact, that's how they'll be represented. It'll be something like "1d6 = 6" resulting in {0,0,0,0,0,1}, which means five misses plus one succes.

And thanks for pointing out the bug! I need to generalize my counting strategy again.

Egonblaidd:

:) Hurray, the first dprime showed up!

Remeber that any die for which a number shows up more than others is technically unfair. So {2,3,3,4} is unfair, because a 3 is more likely to show up than a 2 or a 4. So yea, from that point of view 2d2 is unfair. You could actually make a physical "d(2d2)" out of a real d4 by replacing it numbers with {2,3,3,4}.
Trouble with dice mechanics? Check out AnyDice, my online dice distribution calculator!

Wordman

First, my complements on the program. Very useful.

A long, long time ago, I released a "dice library" that did some of what you are doing. Yours is more advanced, but you might find something of use in mine. Or maybe not. The only things mine adds is the idea of using letters other than 'd' for certain types of rolling.For example, a 't' indicated an "open roll" (sometimes called "exploding dice"), where, if the maximum value for the die comes up, you add that value to another roll of the same die. If the second roll comes up at the maximum, you add and roll again, and so on.

Also, at the time the rand() function of most C implementations was hideously bad, so the code contains a number of much better pseudeo-random number generators.

Anyway, if you want to mine it for anything, it is here: RollPlay Dice Library.
What I think about. What I make.

chance.thirteen

I offer the terms used by 7Th Sea and my own use of Troll to deal with exploding dice.

3k2 meanes roll three, keep two. In 7Th sea d10s are the only die, but you could easily say 3k2d10 or 3d10k2.

For dice that explode, which is usually only on a max result I just called the dice dx. 3d10dxk2.

Then there are the doubles, triples and so on.

Really really like the custom dice thing. Even for something as simple as usuing a d20 to decide a hit location, the visual graph can help some designers.

One additional idea that I did not make up was roll 2 dice, subtract larger from the smaller. I believe that is the same as |Dhigh-Dlower| but there may be other similarly easy to use as a player but hard to describe in math terms approaches of interst here at The Forge.

Jasper Flick

Wordman:

Thanks, and thanks for the program reference. I'll check it out for a bit. My calculated works completely different though, it doesn't do any rolling itself.

chance.thirteen:

I'm also familiar with the term exploding dice. I can put them in, but with a definite upper bound. As the program graphs the entire result space, exploding an infinite number of times will send it into an infinite loop. So for example at most 3 rerolls per die.

Substracting higher from lower is indeed equal to |a-b|, regardless whether a or b is higher.

Ok, I've been mulling about putting all desired functionality into the calculator and how to respresent it. Here are some examples I came up with:
   1 : the most simple and boring input.
   1d4 : duh.
   4d6h3 : roll 4d6 sum highest three values.
   2d4l1 : roll 2d4 take lowest value.
   3d6m1 : roll 3d6 take the median value.
   4d4m2 : roll 4d4 sum the two median values.
   6d10<5 : roll 6d10 sum all values lower than 5.
   3d{-1,0,1} : roll 3 fudge dice.
   8d6ch : roll 8d6 and count all highest values (all 6s) as successes.
   9d6cl : roll 9d6 and count all lowest values (all 1s).   
   5d10c>7 : roll 5d10 and count all values greater than 7 (all 8s, 9,s and 10s).
   6d10c{-1,0,0,0,0,0,1,1,1,2} : roll 6d10 where 7-9 counts as one success, 10 as two, and 1 as -1.
   4d(1d4+1d8)cl : roll 1d4+1d8 four times and count how often you get a 2.
   3(2d4)c{-1,0,0,0,1,1,1} : roll 2d4 three times, count 6-8 as one success and a 2 as -1.
   4d8e3h : roll 4d8 and reroll all 8s, but reroll a single die at most 3 times.
   2d10e2<5 : roll 2d10 and reroll all results lower than 5, at most twice.
   1d4e3{0,0,0,2} : roll 1d4 and reroll a 4 twice, but do this at most three times.
   1d(2d6 + 5)eh1 : roll 2d6+5 and roll the whole thing once more if you get the highest possible result.
   4d6h3c=16 : roll 4d6 drop lowest and count how often you get a 16.
   10d(2d6cl)eh1 : roll 2d6 and count how often you get a 2. Do this ten times, then once more for each time you got two 2s.
   2d6 x 2d4 : show all ways a roll of 2d6 can be followed by a roll of 2d4.
   4d6h3^6 : roll a D&D character.

Here's the syntax definition:
   Statement = CartesianProductSequence ['x' CartesianProductSequence]*
   
   CartesianProductSequence = Expression ['^' N]
   
   Expression = [-] MulExpression [('+' | '-') MulExpression]*
   
   MulExpression = Roll ['*' Roll]*
   
   Roll = N ['d' Distribution [Filter] [Modifier]]
   
   Distribution = N | Set | NestedDistribution | AbsoluteDistribution
   
   NestedDistribution = '(' Expression ')' "evaluate expression and use as a new distribution"
   
   AbsoluteDistribution = '|' Expression '|' "make all negative values positive"
   
   Filter = TakeHighest | TakeLowest | TakeMedian |Comparator
   
   TakeHighest = 'h' N "take the higest N values"
   
   TakeLowest = 'l' N "take the lowest N values"

   TakeMedian = 'm' N "take the median N values"
   
   Comparator = ('=' | '<' | '>') Int "equal to, less than, or greater than Int"

   Modifier = Count | Explode

   Count = 'c' Condition "count how often Condition applies"
   
   Explode = 'e' N Condition "reroll whenever Condition applies, but at most N levels deep"

   Condition = 'h' | 'l' | Set | Comparator "highest or lowest possible values, multiplied by occurances in set, or matching Comparator"
   
   Set = '{' Int [',' Int]* '}'
   
   Int = [-] N
   
   N = Digit [Digit]*
   
   Digit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'

It will take some time to put this all in.
Trouble with dice mechanics? Check out AnyDice, my online dice distribution calculator!

chance.thirteen

Much appreciated.

If you have a paypal or something, I'll send you enough for a coffee beverage or beer. Or donate to a cause of your choice. Send an IM.

It's not much, but some sugar/caffein to help you along, or a drink to say thanks is at least a gesture.

PS I agree on the non-utility of mapping more than 3 levels of explosion on dice.

Oh! I forgot the Silhouette approach.

They roll some d6s, highest single value is the final result. However, if it is a 6, any additional 6s count as a +1. Don't know if that grabs you.

Selene Tan

You might want to take a look at Troll, a language for specifying dice rolls. It can be used to either make rolls or calculate the probability distribution. There's also a paper (PDF) where the author explains some of his decisions for the language, which I found pretty enlightening.

Having your dice calculator online is pretty nice, especially since Troll requires Moscow ML.

(UeberDice in my sig is another die roll calculator which one of my friends put together. There are some larger/more complex rolls where it gets stuck though.)
RPG Theory Wiki
UeberDice - Dice rolls and distribution statistics with pretty graphs

Jasper Flick

All right, I've released a completely new calculator version. Count, explode, filter, you can do it! Read the instruction on the site for the details. (The old version used a funny triangle-of-pascal approach, which was a curiosity experiment. Adding more complex functionality forced me to use a more standard approach, which is fine.)

Here's the link again: http://catlikecoding.com/dice/

chance.thirteen:

Hey, thanks man, I really appreciate that. I even looked into PayPal for a bit, but it's just too much of a hassle to set up and they're taking too big a share for it to make sense to me. So instead I'll just dare you to create an awesome RPG and send me a free PDF copy. ;)

The Silhouette approach cannot be reproduced in one step, but with a little work it can be found in two steps. I'll use 3d6 as an example. First you compute the regular 3d6h1, which gives the following results:
R    #    %
1    1    0.46
2    7    3.24
3   19    8.80
4   37   17.13
5   61   28.24
6   91   42.13

Then you compute the "overkill" 6s with 3d6ch:
R    #    %
0  125   57.87
1   75   34.72
2   15    6.94
3    1    0.46

Here 0 means you got no 6s, so ignore that. Add 5 to the other values and you get your final "overkill" value. Now we can merge the two graphs to get the final distribution:
R    #    %
1    1    0.46
2    7    3.24
3   19    8.80
4   37   17.13
5   61   28.24
6   75   34.72
7   15    6.94
8    1    0.46

Selene Tan:

Thanks for the links!
Trouble with dice mechanics? Check out AnyDice, my online dice distribution calculator!

Jasper Flick

chance.thirteen asked:
Quoteso how would I roll 4d10 that explode on a 10, at most twice, and sum the highest 2?

I had thought it would be 4d10e2h2 but it doesn't like the last 2.

You can only apply a single filter or modifier per dice, but you can get around that by nesting. You can use "4d(1d10e2h)h2". That literally means "roll a 1d10 that explodes at most twice, do this four times and sum the two highest."
Trouble with dice mechanics? Check out AnyDice, my online dice distribution calculator!

Guy Srinivasan

Feature request: suppose I wanted to count all the times I got a sum of 18-23, 26-31, 34-39, 42-47, 50-55, or 58-63, when rolling a 1d(Xd{0,0,1,8}) for different X from 4 to 7. Right now for (barring some subtle math tricks which might work for this specific case) I have to do something like:

1d(4d{0,0,1,8})c{0,0,0,0,0,0,0,0,0,0,0,1,0,0,0}
...
1d(7d{0,0,1,8})c{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,1,1,1,0,0,1,1,0,0,1,0,0,0}

because the weights are assigned to the possible outcomes in order. How about something like 1d(4d{0,0,1,8})c{18=1,19=1,20=1,21=1,22=1,23=1,26=1,...}? So I can keep around my c{...} without having to change it because there are some new possible outcomes going from 4d to 5d which mess with the ordering?

Basically a generalization of c{...} and c=x.