Class Dice

Namespace
Wolfgang.D20
Assembly
Wolfgang.D20.Dice.dll

Represents a collection of Die rolled together, with an optional flat modifier.

public sealed class Dice : IDice, IReadOnlyCollection<Die>, IEnumerable<Die>, IEnumerable, IEquatable<Dice>
Inheritance
Dice
Implements
Inherited Members
Extension Methods

Remarks

The dice need not be homogeneous; a single Dice can contain dice with differing side counts, for example 2d6+1d4+3. Dice is immutable: the "with" builders (WithDie(Die), Without(Die), WithModifier(int)) return a new instance rather than modifying the current one, so an instance is safe to use as a dictionary key and to share across threads.

Constructors

Dice(IEnumerable<Die>, int)

Constructs a new instance of Dice from an existing sequence of Die and an optional modifier.

[SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "This constructor was released in 0.8.0 alongside the (int, int, int) overload; changing either signature is a SemVer breaking change.")]
public Dice(IEnumerable<Die> dice, int modifier = 0)

Parameters

dice IEnumerable<Die>

The dice to include in the collection

modifier int

An optional modifier to add to the result

Examples

// 1d6+1d4+1: a heterogeneous pool built from individual dice.
var dice = new Dice(new[] { new Die(6), new Die(4) }, modifier: 1);

Exceptions

ArgumentNullException

dice is null

ArgumentException

dice contains a null element

Dice(int, int, int)

Constructs a new instance of Dice containing the specified number of identical dice and an optional modifier.

[SuppressMessage("ApiDesign", "RS0026:Do not add multiple overloads with optional parameters", Justification = "This constructor was released in 0.8.0 alongside the (IEnumerable<Die>, int) overload; changing either signature is a SemVer breaking change.")]
public Dice(int dieCount = 1, int sideCount = 6, int modifier = 0)

Parameters

dieCount int

The number of dice

sideCount int

The number of sides on each die

modifier int

An optional modifier to add to the result

Examples

// 2d6+3: two six-sided dice plus a flat +3.
var attack = new Dice(dieCount: 2, sideCount: 6, modifier: 3);
int total = attack.Roll(); // a value in [5, 15]

Remarks

This convenience constructor builds a homogeneous collection of dieCount dice, each with sideCount sides. A sideCount of 2 represents a coin toss.

Exceptions

ArgumentOutOfRangeException

dieCount is less than 1

ArgumentOutOfRangeException

sideCount is less than 2

Properties

Count

The number of dice in the collection. IReadOnlyCollection<T> implementation; equal to DieCount.

public int Count { get; }

Property Value

int

DieCount

The number of dice in the collection.

public int DieCount { get; }

Property Value

int

MaxValue

The maximum value that can be rolled with the dice in the collection and the modifier.

public int MaxValue { get; }

Property Value

int

MinValue

The minimum value that can be rolled with the dice in the collection and the modifier.

public int MinValue { get; }

Property Value

int

Modifier

An optional modifier to add to the total of the dice rolled.

public int Modifier { get; }

Property Value

int

Examples

var attack = new Dice(1, 20, 2);        // 1d20+2 — modifier set at construction
var blessed = attack.WithModifier(5);   // 1d20+5 — a new pool; 'attack' is unchanged

Remarks

The value can be positive or negative, and can be used to adjust the result of the roll. It is fixed at construction; use WithModifier(int) to obtain a copy with a different modifier.

Methods

Equals(object?)

Checks if this instance is equal to another object.

public override bool Equals(object? obj)

Parameters

obj object

The object to compare with this instance. It can be null or of any type.

Returns

bool

True if the object is a Dice instance equal to this instance; otherwise, false.

Equals(Dice?)

Checks if this instance is equal to another instance of Dice.

public bool Equals(Dice? other)

Parameters

other Dice

The other instance of Dice to compare with this instance.

Returns

bool

True if both instances have the same Modifier and the same multiset of dice (matching side counts, regardless of order); otherwise, false.

GetEnumerator()

Returns an enumerator that iterates through the dice in the collection.

public IEnumerator<Die> GetEnumerator()

Returns

IEnumerator<Die>

An enumerator over the dice.

GetHashCode()

Generates a hash code for this instance based on its Modifier and the multiset of dice side counts (order-independent).

public override int GetHashCode()

Returns

int

A combined hash code.

Remarks

Dice is immutable, so this hash code is stable for the life of the instance and a Dice is safe to use as a key in a hashed collection such as Dictionary<TKey, TValue> or HashSet<T>.

Roll()

Rolls every die in the collection and returns the total value rolled, including any modifier.

public int Roll()

Returns

int

The sum of an independent roll of each die in the collection plus Modifier. Always between MinValue and MaxValue inclusive.

Examples

var dice = new Dice(3, 6); // 3d6
int total = dice.Roll(); // a value in [3, 18]

ToString()

Returns a string representation of the dice in standard dice notation, for example 2d6+1d4+3.

public override string ToString()

Returns

string

The dice grouped by side count (in the order each side count first appears), followed by the modifier. Dice order is not significant. The modifier is omitted when zero, and a negative modifier renders with a leading minus sign. An empty collection renders only the modifier (or an empty string when the modifier is zero).

Examples

string notation = new Dice(2, 6, 3).ToString(); // "2d6+3"

TryParse(string?)

Tries to parse a string representation of dice notation into a Dice instance.

[SuppressMessage("Major Code Smell", "S8969:Remove this null-forgiving operator", Justification = "`notation!` is required on net462/netstandard2.0 whose string.IsNullOrWhiteSpace lacks [NotNullWhen(false)]; the ! is redundant on modern TFMs only.")]
[SuppressMessage("Major Code Smell", "S3267:Loops should be simplified with 'LINQ' expressions", Justification = "The explicit foreach + StringBuilder loop is a zero-allocation hot path; LINQ .Where(...).ToArray() would allocate an IEnumerator plus intermediate char[].")]
public static Result<Dice?> TryParse(string? notation)

Parameters

notation string

The dice notation to parse, for example 2d6+1d4+3. Whitespace is ignored. The notation may contain any number of dice terms (XdY) and flat modifiers (+Z / -Z).

Returns

Result<Dice>

A Wolfgang.TryPattern.Result<T> containing the parsed Dice instance if successful; otherwise, a failed result with Wolfgang.TryPattern.Result.ErrorMessage describing the failure. Accessing Wolfgang.TryPattern.Result<T>.Value on a failed result throws InvalidOperationException.

Examples

var result = Dice.TryParse("2d6+3");
if (result.Succeeded)
{
    Dice dice = result.Value!;
    int total = dice.Roll(); // a value in [5, 15]
}

WithDie(Die)

Returns a new Dice containing every die in this instance plus die, keeping the same Modifier. This instance is not modified.

public Dice WithDie(Die die)

Parameters

die Die

The die to add.

Returns

Dice

A new Dice with die appended.

Examples

var pool = new Dice(2, 6).WithDie(new Die(4)); // 2d6 -> 2d6+1d4

Exceptions

ArgumentNullException

die is null.

WithModifier(int)

Returns a new Dice with the same dice but the specified modifier. This instance is not modified.

public Dice WithModifier(int modifier)

Parameters

modifier int

The flat modifier for the new instance.

Returns

Dice

A new Dice whose Modifier is modifier.

Examples

var attack = new Dice(1, 20, 2);      // 1d20+2
var buffed = attack.WithModifier(5);  // 1d20+5 — derived from attack, which is unchanged

Without(Die)

Returns a new Dice with the first die matching die removed, keeping the same Modifier. If no die matches, an equal copy is returned. This instance is not modified.

public Dice Without(Die die)

Parameters

die Die

The die to remove.

Returns

Dice

A new Dice without the first matching die.

Exceptions

ArgumentNullException

die is null.