-
Notifications
You must be signed in to change notification settings - Fork 30
Dice Rolling
The GoRogue.DiceNotation interface provides functions capable of parsing and rolling dice via an extended version of Dice Notation syntax.
Code examples in this section show only code in the Main function. The code provided assumes that the following "using" statements are at the top of the code file:
using GoRogue.DiceNotation;
using Troschuetz.Random;
using Troschuetz.Random.Generators;
Basic dice rolls are easy to perform with the Dice.Roll function. This function takes the dice notation expression to parse and (optionally) a random number generator (see Random Number Generation for details):
// Rolls 1 6-sided die. When no RNG is specified, SingletonRandom.DefaultRNG is used.
int result = Dice.Roll("1d6");
System.Console.WriteLine("Rolling 1d6: " + result);
// Custom RNG; see Random Number Generation docs for usage details
IGenerator customRNG = new MT19937Generator();
// Rolls 2d6 and adds 3 to the sum of the result. We also specify a custom RNG to use
// for rolling:
int result3 = Dice.Roll("2d6+3", customRNG);
System.Console.WriteLine("Rolling 2d6+3 with custom RNG: " + result3);
// We can also do multiplication and division in the expression
// Rolls 2d6, adds 2, multiplies that result by 3, and returns the result
int result4 = Dice.Roll("(2d6+2)*3");
System.Console.WriteLine("Rolling (2d6+2)*3: " + result4);
// Rolls 2d6,subtracts 2, divides that result by 3, and returns the result
int result5 = Dice.Roll("(2d6-2)/3");
System.Console.WriteLine("Rolling (2d6-2)/3: " + result5);
// GoRogue also supports "keep" expressions
// Rolls 3 d6, adds only the highest 2 together, and returns the result
int result6 = Dice.Roll("3d6k2");
System.Console.WriteLine("Rolling 3d6k2: " + result6);
// This version of dice notation also supports parenthesized dice expressions, allowing
// for very complex dice expressions
// Rolls 1d12, adds 4. Then, rolls a dice whose number of sides is equal
// to the result of the first roll, and adds 3, and returns the result.
int result7 = Dice.Roll("1d(1d12+4)+3");
See general information on Dice Notation syntax for details.
Even in the case where we use Basic Dice Rolling, for reasonable expressions, performance is typically very fast. However, in the case where the dice expression is extremely complex, and/or a given dice expression is used multiple times and performance is critical, the Dice.Parse function may prove useful. It can generate an IDiceExpression instance that can later be used to roll the expression one or more times, thus avoiding expensive parsing of a dice notation expression for each roll:
IDiceExpression expr = Dice.Parse("2d6+2");
int result1 = expr.Roll(); // Rolls 2d6+2 with the default RNG
IGenerator rng = new MT19937Generator();
int result2 = expr.Roll(rng); // Rolls 2d6+2, using the RNG specified.
// Prints the result of the rolls
System.Console.WriteLine("result1 result: " + result1);
System.Console.WriteLine("result2 result: " + result2);
For convenience, IDiceExpression instances also provide MaxRoll and MinRoll functions that allow retrieval of the maximum possible and minimum possible values that could be rolled, respectively:
IDiceExpression expr = Dice.Parse("2d6+2");
int minResult = expr.MinRoll(); // Gets the minimum possible result (4)
int maxResult = expr.MaxRoll(); // Gets the maximum possible result (14)
System.Console.WriteLine("Min for 2d6+2: " + minResult);
System.Console.WriteLine("Max for 2d6+2: " + maxResult);
The GoRogue.DiceNotation namespace also provides a number of interfaces and functions to enable more advanced or custom functionality with respect to dice and dice expressions.
GoRogue's default implementation of IDiceExpression works by holding the final term in an expression (the root of that expression's expression tree). Each time the expression is rolled, the root term is evaluated, which then in turn evaluates all the other terms in the correct order.
Particularly in the case of building a custom parser, it may be useful to provide a custom implementation of the IDiceExpression interface, that represents the expression differently or provides additional information.
A "term", in the context of the dice expression parser provided, is defined as a constant, or another expression that evaluates to a constant. Thus, terms can not only represent integer constants, but can also be defined as an operation on two or more existing terms that produces a numeric result.
Several types of terms are implemented for the default parser, including terms for constant values, dice themselves, keep expressions, and addition, subtraction, multiplication, and division operators. All of the existing terms implement ITerm, and the provided IDiceExpression implementation operates using ITerms. Thus, if custom operations are being defined, it may be possible to implement them as custom ITerm implementations (and create a parser capable of producing them), and use the existing dice expression representation.
The default parser for dice notation implements the IParser interface. This interface simply defines a Parse function that takes a dice expression string, and produces an IDiceExpression instance.
The Dice class has a settable (static) field DiceParser that defines the IParser instance that the Roll and Parse functions use. Thus, if a custom syntax is being supported, it is possible to create a custom implementation of the IParser interface, and set the Dice class to use that custom implementation in its Roll and Parse functions.
- Home
- Getting Started
- GoRogue 1.0 to 2.0 Upgrade Guide
- Grid System
- Dice Rolling
- Effects System
- Field of View
- Map Generation (docs coming soon)
- Map View System
- Pathfinding (docs coming soon)
- Random Number Generation (docs coming soon)
- Sense Mapping (docs coming soon)
- Spatial Maps (docs coming soon)
- Utility/Miscellaneous (docs coming soon)