Class Dice
java.lang.Object
com.github.yellowstonegames.core.Dice
Class for emulating various traditional RPG-style dice rolls.
Supports rolling multiple virtual dice of arbitrary size, summing all, the highest n, or the lowest n
dice, treating dice as "exploding" as in some tabletop games (where the max result is rolled again and added),
getting a value from inside a range, and applying simple arithmetic modifiers to the result (like adding a number).
Typically, you'll want to use the
Based on code from the Blacken library.
roll(String) method if you have a String like "2d8+6" that you
want to evaluate once, or the various other methods if you have int variables for things like "number of dice to
roll" and "sides on each die." Important to note are the Dice.Rule inner class and the code that uses it, such as
parseRollRule(String) to parse dice notation and generate a Rule, and runRollRule(Rule) to roll
dice according to that rule. Using Rule-related code is preferred if you want to perform a roll more than a few times
or to hold onto the instructions for a die roll to use at a later time.
Based on code from the Blacken library.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic classA rule for how to roll a particular set of dice and operations to perform on them, such as "3d6+4" to roll three 6-sided dice and add 4 to the result. -
Constructor Summary
ConstructorsConstructorDescriptionDice()Creates a new dice roller that uses a random RNG seed for an RNG that it owns.Dice(long seed) Creates a new dice roller that will use its own WhiskerRandom as its RNG, seeded with the given seed.Dice(com.github.tommyettinger.random.EnhancedRandom rng) Creates a new dice roller that uses the given EnhancedRandom, which can be seeded before it's given here.Dice(CharSequence seed) Creates a new dice roller that will use its own WhiskerRandom as its RNG, seeded with a hash of the given String seed. -
Method Summary
Modifier and TypeMethodDescriptionintFind the best n totals from the provided number of dice rolled according to the roll group string.com.github.tommyettinger.ds.IntListindependentRolls(int n, int sides) Get a list of the independent results of n rolls of dice with the given number of sides.static Dice.RuleparseRollRule(String rollCode) Parses the StringrollCodeas dice roll notation and returns instructions as a Rule so the roll can be performed later withrunRollRule(Rule).static Dice.RuleparseRollRuleInto(Dice.Rule into, String rollCode) Parses the StringrollCodeas dice roll notation and appends instructions intointoso rolls can be performed later withrunRollRule(Rule).intEvaluate the StringrollCodeas dice roll notation and roll to get a random result of that dice roll.introllDice(int n, int sides) Emulate a dice roll and return the sum.introllExplodingDice(int n, int sides) Emulate an exploding dice roll and return the sum.intrunRollRule(Dice.Rule rule) Performs a roll of the givenrule, which should store instructions fromparseRollRule(String)orparseRollRuleInto(Rule, String).voidsetRandom(com.github.tommyettinger.random.EnhancedRandom rng) Sets the random number generator to be used.intFind the worst n totals from the provided number of dice rolled according to the roll group string.
-
Constructor Details
-
Dice
public Dice()Creates a new dice roller that uses a random RNG seed for an RNG that it owns. -
Dice
public Dice(com.github.tommyettinger.random.EnhancedRandom rng) Creates a new dice roller that uses the given EnhancedRandom, which can be seeded before it's given here. The EnhancedRandom will be shared, not copied, so requesting a random number from the same EnhancedRandom in another place may change the value of the next die roll this makes, and dice rolls this makes will change the state of the shared EnhancedRandom.- Parameters:
rng- an EnhancedRandom, such asWhiskerRandom; will be shared (dice rolls will change the generator's state outside here)
-
Dice
public Dice(long seed) Creates a new dice roller that will use its own WhiskerRandom as its RNG, seeded with the given seed.- Parameters:
seed- a long to use as a seed for a new WhiskerRandom (can also be an int, short, or byte)
-
Dice
Creates a new dice roller that will use its own WhiskerRandom as its RNG, seeded with a hash of the given String seed. This can take any CharSequence, not just String, and usesHasher.dantalion,Hasher.dantalion_,Hasher.decarabia, andHasher.decarabia_to hash the seed.- Parameters:
seed- a String or other CharSequence to use as a seed for a new WhiskerRandom
-
-
Method Details
-
setRandom
public void setRandom(com.github.tommyettinger.random.EnhancedRandom rng) Sets the random number generator to be used. This method does not need to be called before using the methods of this class.- Parameters:
rng- an EnhancedRandom as the source of randomness
-
bestOf
Find the best n totals from the provided number of dice rolled according to the roll group string.- Parameters:
n- number of roll groups to totaldice- number of roll groups to rollgroup- string encoded roll grouping- Returns:
- the sum
-
worstOf
Find the worst n totals from the provided number of dice rolled according to the roll group string.- Parameters:
n- number of roll groups to totaldice- number of roll groups to rollgroup- string encoded roll grouping- Returns:
- the sum
-
rollDice
public int rollDice(int n, int sides) Emulate a dice roll and return the sum.- Parameters:
n- number of dice to sumsides- positive integer; number of sides on the rolled dice- Returns:
- sum of rolled dice
-
rollExplodingDice
public int rollExplodingDice(int n, int sides) Emulate an exploding dice roll and return the sum.- Parameters:
n- number of dice to sumsides- number of sides on the rollDice; should be greater than 1- Returns:
- sum of rollDice
-
independentRolls
public com.github.tommyettinger.ds.IntList independentRolls(int n, int sides) Get a list of the independent results of n rolls of dice with the given number of sides.- Parameters:
n- number of dice usedsides- positive integer; number of sides on each die- Returns:
- list of results
-
roll
Evaluate the StringrollCodeas dice roll notation and roll to get a random result of that dice roll. You should consider whether you want to parse the rollCode every time (which can be computationally costly); if you make a lot of similar dice rolls, you can useparseRollRuleInto(Rule, String)to get a reusable rule for rolls.
This can handle a good amount of dice terminology. One of the more frequent uses is rolling some amount of dice and summing their values, which can be done with e.g. "4d10" to roll four ten-sided dice and add up their results. You can choose to sum only some of the dice, either the "n highest" or "n lowest" values in a group, with "3>4d6" to sum the three greatest-value dice in four rolls of six-sided dice, or "2<3d8" to sum the two lowest-value dice in three rolls of eight-sided dice. You can apply modifiers to these results, such as "1d20+7" to roll one twenty-sided die and add 7 to its result. These modifiers can be other dice, such as "1d10-1d6", and while multiplication and division are supported, order of operations isn't, so it just rolls dice from left to right and applies operators it finds along the way. You can get a random value in an inclusive range with "50:100", which is equivalent to "1d51+49" but is easier to read and understand. You can treat dice as "exploding," where any dice that get the maximum result are rolled again and added to the total along with the previous maximum result. As an example, if two exploding six-sided dice are rolled, and their results are 3 and 6, then because 6 is the maximum value it is rolled again and added to the earlier rolls; if the additional roll is a 5, then the sum is 3 + 6 + 5 (for a total of 14), but if the additional roll was a 6, then it would be rolled again and added again, potentially many times if 6 is rolled continually. Some players may be familiar with this game mechanic from various tabletop games, but many potential players might not be, so it should be explained if you show the kinds of dice being rolled to players. The syntax used for exploding dice replaces the "d" in "3d6" for normal dice with "!", making "3!6" for three six-sided exploding dice. Inclusive ranges are not supported with best-of and worst-of notation, but exploding dice are. If using a range, the upper bound can be random, decided by dice rolls such as with "1:6d6" (which rolls six 6-sided dice and uses that as the upper bound of the range) or by other ranges such as with "10:100:200", which gets a random number between 100 and 200, then returns a random number between 10 and that. While it is technically allowed to end a dice string with an operator, the partial operator will be ignored. If you start a dice string with an operator, its left-hand-side will always be 0. If you have two operators in a row, only the last will be used, unless one is '-' and can be treated as part of a negative number (this allows "1d20 * -3" to work). Whitespace is allowed between most parts of a dice string.
The following notation is supported:42: simple absolute string; can start with-to make it negative3d6: sum of 3 6-sided diced6: synonym for1d63>4d6: best 3 of 4 6-sided dice3:4d6: gets a random value between 3 and a roll of4d6; this syntax has changed2<5d6: worst 2 of 5 6-sided dice10:20: simple random range (inclusive between 10 and 20):20: synonym for0:203!6: sum of 3 "exploding" 6-sided dice; see above for the semantics of "exploding" dice!6: synonym for1!6
+4: add 4 to the value-3: subtract 3 from the value*100: multiply value by 100/8: integer-divide value by 8
- Parameters:
rollCode- dice string using the above notation- Returns:
- a random number that is possible with the given dice string
-
parseRollRule
Parses the StringrollCodeas dice roll notation and returns instructions as a Rule so the roll can be performed later withrunRollRule(Rule). This method allocates a new Rule every time, which may not be optimal; consider reusing a Rule withparseRollRuleInto(Rule, String).
This effectively allows storing instructions for how to roll a particular set of dice, but leaves the actual roll for later. By storing the instructions instead of parsing them every time, this can save quite a bit of effort for dice-roll-heavy games.
This can handle a good amount of dice terminology. One of the more frequent uses is rolling some amount of dice and summing their values, which can be done with e.g. "4d10" to roll four ten-sided dice and add up their results. You can choose to sum only some of the dice, either the "n highest" or "n lowest" values in a group, with "3>4d6" to sum the three greatest-value dice in four rolls of six-sided dice, or "2<3d8" to sum the two lowest-value dice in three rolls of eight-sided dice. You can apply modifiers to these results, such as "1d20+7" to roll one twenty-sided die and add 7 to its result. These modifiers can be other dice, such as "1d10-1d6", and while multiplication and division are supported, order of operations isn't, so it just rolls dice from left to right and applies operators it finds along the way. You can get a random value in an inclusive range with "50:100", which is equivalent to "1d51+49" but is easier to read and understand. You can treat dice as "exploding," where any dice that get the maximum result are rolled again and added to the total along with the previous maximum result. As an example, if two exploding six-sided dice are rolled, and their results are 3 and 6, then because 6 is the maximum value it is rolled again and added to the earlier rolls; if the additional roll is a 5, then the sum is 3 + 6 + 5 (for a total of 14), but if the additional roll was a 6, then it would be rolled again and added again, potentially many times if 6 is rolled continually. Some players may be familiar with this game mechanic from various tabletop games, but many potential players might not be, so it should be explained if you show the kinds of dice being rolled to players. The syntax used for exploding dice replaces the "d" in "3d6" for normal dice with "!", making "3!6" for three six-sided exploding dice. Inclusive ranges are not supported with best-of and worst-of notation, but exploding dice are. If using a range, the upper bound can be random, decided by dice rolls such as with "1:6d6" (which rolls six 6-sided dice and uses that as the upper bound of the range) or by other ranges such as with "10:100:200", which gets a random number between 100 and 200, then returns a random number between 10 and that. While it is technically allowed to end a dice string with an operator, the partial operator will be ignored. If you start a dice string with an operator, its left-hand-side will always be 0. If you have two operators in a row, only the last will be used, unless one is '-' and can be treated as part of a negative number (this allows "1d20 * -3" to work). Whitespace is allowed between most parts of a dice string.
The following notation is supported:42: simple absolute string; can start with-to make it negative3d6: sum of 3 6-sided diced6: synonym for1d63>4d6: best 3 of 4 6-sided dice3:4d6: gets a random value between 3 and a roll of4d6; this syntax has changed2<5d6: worst 2 of 5 6-sided dice10:20: simple random range (inclusive between 10 and 20):20: synonym for0:203!6: sum of 3 "exploding" 6-sided dice; see above for the semantics of "exploding" dice!6: synonym for1!6
+4: add 4 to the value-3: subtract 3 from the value*100: multiply value by 100/8: integer-divide value by 8
- Parameters:
rollCode- dice string using the above notation- Returns:
- a roll rule that can be run with
runRollRule(Rule)
-
parseRollRuleInto
Parses the StringrollCodeas dice roll notation and appends instructions intointoso rolls can be performed later withrunRollRule(Rule). This method does not clearinto, so you should clear it yourself if you don't want to save its contents (or it didn't store a roll rule). You can append to an existing roll rule, which is about the same as adding a+between the two roll codes and parsing that.
This is the main way of using the Dice class. This effectively allows storing instructions for how to roll a particular set of dice, but leaves the actual roll for later. By storing the instructions instead of parsing them every time, this can save quite a bit of effort for dice-roll-heavy games.
This can handle a good amount of dice terminology. One of the more frequent uses is rolling some amount of dice and summing their values, which can be done with e.g. "4d10" to roll four ten-sided dice and add up their results. You can choose to sum only some of the dice, either the "n highest" or "n lowest" values in a group, with "3>4d6" to sum the three greatest-value dice in four rolls of six-sided dice, or "2<3d8" to sum the two lowest-value dice in three rolls of eight-sided dice. You can apply modifiers to these results, such as "1d20+7" to roll one twenty-sided die and add 7 to its result. These modifiers can be other dice, such as "1d10-1d6", and while multiplication and division are supported, order of operations isn't, so it just rolls dice from left to right and applies operators it finds along the way. You can get a random value in an inclusive range with "50:100", which is equivalent to "1d51+49" but is easier to read and understand. You can treat dice as "exploding," where any dice that get the maximum result are rolled again and added to the total along with the previous maximum result. As an example, if two exploding six-sided dice are rolled, and their results are 3 and 6, then because 6 is the maximum value it is rolled again and added to the earlier rolls; if the additional roll is a 5, then the sum is 3 + 6 + 5 (for a total of 14), but if the additional roll was a 6, then it would be rolled again and added again, potentially many times if 6 is rolled continually. Some players may be familiar with this game mechanic from various tabletop games, but many potential players might not be, so it should be explained if you show the kinds of dice being rolled to players. The syntax used for exploding dice replaces the "d" in "3d6" for normal dice with "!", making "3!6" for three six-sided exploding dice. Inclusive ranges are not supported with best-of and worst-of notation, but exploding dice are. If using a range, the upper bound can be random, decided by dice rolls such as with "1:6d6" (which rolls six 6-sided dice and uses that as the upper bound of the range) or by other ranges such as with "10:100:200", which gets a random number between 100 and 200, then returns a random number between 10 and that. While it is technically allowed to end a dice string with an operator, the partial operator will be ignored. If you start a dice string with an operator, its left-hand-side will always be 0. If you have two operators in a row, only the last will be used, unless one is '-' and can be treated as part of a negative number (this allows "1d20 * -3" to work). Whitespace is allowed between most parts of a dice string.
The following notation is supported:42: simple absolute string; can start with-to make it negative3d6: sum of 3 6-sided diced6: synonym for1d63>4d6: best 3 of 4 6-sided dice3:4d6: gets a random value between 3 and a roll of4d6; this syntax has changed2<5d6: worst 2 of 5 6-sided dice10:20: simple random range (inclusive between 10 and 20):20: synonym for0:203!6: sum of 3 "exploding" 6-sided dice; see above for the semantics of "exploding" dice!6: synonym for1!6
+4: add 4 to the value-3: subtract 3 from the value*100: multiply value by 100/8: integer-divide value by 8
- Parameters:
into- a Rule that this will append to, placing instructions for how to perform a rollrollCode- dice string using the above notation- Returns:
- a roll rule that can be run with
runRollRule(Rule)
-
runRollRule
Performs a roll of the givenrule, which should store instructions fromparseRollRule(String)orparseRollRuleInto(Rule, String). Two rolls of the same roll rule have no guarantee of having the same or different result, just that they will use the same dice and operations.- Parameters:
rule- a Rule generated byparseRollRule(String)orparseRollRuleInto(Rule, String)- Returns:
- the result of rolling the dice as instructed by rollRule
-