Documentation ¶
Overview ¶
Package dice implements virtualized standard polyhedral and specialty game dice. The dice roll calculations are intended to be cryptographically pseudo-random through use of crypto/rand, but the entropy source used by the package is globally configurable.
Dice Notation ¶
Dice notation is an algebra-like system for indicating dice rolls in games. Dice rolls are usually given in the form AdX+B, where A is the number of X-sided dice to roll, with an optional modifier B. B could be an integer or potentially another dice notation string. Additionally, A can be omitted if the number of X-sided dice to roll is 1: 1dX can be written as simply dX.
Index ¶
- Variables
- func All(vs []Roller, f func(Roller) bool) bool
- func CryptoInt64() (int64, error)
- func CryptoIntn(max int) (n int, err error)
- func CtxMaxRolls(ctx context.Context) uint64
- func CtxParameters(ctx context.Context) map[string]interface{}
- func CtxTotalRolls(ctx context.Context) *uint64
- func FindNamedCaptureGroups(exp *regexp.Regexp, in string) map[string]string
- func MustCtxTotalRolls(ctx context.Context) *uint64
- func NewContextFromContext(ctx context.Context) context.Context
- func Ptr[T any](v T) *T
- type CompareOp
- type CompareTarget
- type CriticalFailureModifier
- type CriticalSuccessModifier
- type Die
- func (d *Die) Add(r Roller)
- func (d *Die) FullRoll(ctx context.Context) error
- func (d *Die) Parent() Roller
- func (d *Die) Reroll(ctx context.Context) error
- func (d *Die) Roll(ctx context.Context) error
- func (d *Die) SetParent(r Roller)
- func (d *Die) String() string
- func (d *Die) ToGraphviz() string
- func (d *Die) Total(ctx context.Context) (float64, error)
- func (d *Die) Value(ctx context.Context) (float64, error)
- type DieType
- type DropKeepMethod
- type DropKeepModifier
- type ErrNotImplemented
- type ErrParseError
- type ExplodeModifier
- type Group
- func (g Group) Add(r Roller)
- func (g Group) Copy() []Roller
- func (g Group) Drop(_ context.Context, _ bool)
- func (g Group) Expression() string
- func (g Group) FullRoll(ctx context.Context) (err error)
- func (g Group) IsDropped(_ context.Context) bool
- func (g Group) Len() int
- func (g Group) Less(i, j int) bool
- func (g Group) Parent() Roller
- func (g Group) Reroll(ctx context.Context) (err error)
- func (g Group) Roll(ctx context.Context) (err error)
- func (g Group) SetParent(Roller)
- func (g Group) String() string
- func (g Group) Swap(i, j int)
- func (g Group) ToGraphviz() string
- func (g Group) Total(ctx context.Context) (total float64, err error)
- func (g Group) Value(ctx context.Context) (float64, error)
- type Modifier
- type ModifierList
- type RerollModifier
- type Result
- type Roller
- func Filter(vs []Roller, f func(Roller) bool) []Roller
- func MustNewDie(props *RollerProperties) Roller
- func MustNewRoller(props *RollerProperties) Roller
- func NewDie(props *RollerProperties) (Roller, error)
- func NewDieWithParent(props *RollerProperties, parent Roller) (Roller, error)
- func NewRoller(props *RollerProperties) (Roller, error)
- func NewRollerWithParent(props *RollerProperties, parent Roller) (Roller, error)
- type RollerFactory
- type RollerGroup
- type RollerProperties
- type SortDirection
- type SortModifier
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( CtxKeyTotalRolls = &contextKey{name: "total rolls"} CtxKeyMaxRolls = &contextKey{name: "max rolls"} CtxKeyParameters = &contextKey{name: "parameters"} )
var ( // ErrImpossibleDie is returned when an attempt to create a die with a // negative number of sides is made. ErrImpossibleDie = errors.New("die cannot have negative sides") // ErrNilDie is returned when a die's passed reference is nil. ErrNilDie = errors.New("nil die passed") // ErrMaxRolls is returned when a maximum number of rolls/rerolls has been // met or surpassed. ErrMaxRolls = errors.New("max rolls reached") // ErrUnrolled is returned when an operation that requires a rolled die is // preformed on an unrolled die ErrUnrolled = errors.New("die is unrolled") // ErrRolled is returned when an attempt is made to roll a die that had been // rolled already ErrRolled = errors.New("die already rolled") // ErrRerolled is returned when it must be noted that a die's value has // changed due to being rerolled. ErrRerolled = errors.New("die rerolled") // ErrInvalidExpression is returned when a dice expression is invalid or // there is a general issue evaluating it. ErrInvalidExpression = errors.New("invalid expression") // ErrImpossibleRoll is returned when a given dice roll is deemed // impossible, illogical, or will never be able to yield a result. As an // example, a roll of "3d6r<6" should return this error at some stage in its // evaluation, as no die in the set will ever be able to settle with the // given reroll modifier. ErrImpossibleRoll = errors.New("impossible roll") // ErrContextKeyMissing is returned if a context key is not found in a // request context. ErrContextKeyMissing = errors.New("context key missing") // ErrMaxDepth is returned if a replacement operation recurses beyond // MaxDepth. ErrMaxDepth = errors.New("max replacement depth") )
var ( // DiceNotationPattern is the base XdY notation pattern for matching dice // strings. DiceNotationPattern = `(?i)(?P<count>\d+)?d(?P<size>\d{1,}|f|F)` // DiceNotationRegex is the compiled RegEx for parsing supported dice // notations. DiceNotationRegex = regexp.MustCompile(DiceNotationPattern) // ComparePointpattern is the base pattern that matches compare points // within dice modifiers. ComparePointPattern = `(?P<compare>[=<>])?(?P<point>\d+)` // ComparePointRegex is the compiled RegEx for parsing supported dice // modifiers' core compare points. ComparePointRegex = regexp.MustCompile(ComparePointPattern) )
Regexes for parsing basic dice notation strings.
var DiceWithModifiersExpressionRegex = regexp.MustCompile( DiceNotationPattern + `(?P<modifiers>[!a-zA-Z=<>\d]*)`)
DiceWithModifiersExpressionRegex is the compiled RegEx for parsing a dice notation with modifier strings appended.
var MaxDepth int = 3
MaxDepth is the maximum number of replacement iterations allowed for a parse.
var MaxRolls uint64 = math.MaxUint64
MaxRolls is the maximum number of rolls allowed for a request.
var RollerFactoryMap = map[DieType]RollerFactory{ TypePolyhedron: NewDieWithParent, TypeFudge: NewDieWithParent, }
RollerFactoryMap is the package-wide mapping of die types and the function to use to create a new die of that type. This map can be modified to create dice using different functions or to implement new die types.
var Source *rand.Rand
Source is the dice package's global RNG source. Source uses the system's native cryptographically secure pseudorandom number generator by default.
Source must be safe for concurrent use: to use something akin to math/rand's thread safe global reader try binding a Source64 with a Mutex. See math/rand's globalRand variable source code for an example.
Functions ¶
func All ¶
All is a helper function that returns true if all Rollers of a slice match a predicate. All will return false on the first failure.
func CryptoInt64 ¶
CryptoInt64 is a convenience function that returns a cryptographically random int64 using the system's CSPRNG. If there is a problem generating enough entropy it will return a non-nil error.
This function was designed to seed math/rand Sources with uniform random values. It will not use the package's global Source.
func CryptoIntn ¶
CryptoIntn is a convenience wrapper for emulating rand.Intn using crypto/rand. Panics if max <= 0, and any other errors encountered when generating the integer are passed through by err.
CryptoIntn does not use the package's global Source, it uses crypto.Reader.
func CtxMaxRolls ¶
CtxMaxRolls returns the context's maximum allowed number of rolls, or the default.
func CtxParameters ¶
CtxParameters returns the context's arbitrary parameters.
func CtxTotalRolls ¶
CtxTotalRolls returns the pointer to total number of rolls made by the context.
func FindNamedCaptureGroups ¶
FindNamedCaptureGroups finds string submatches within an input string based on a compiled Regexp and returns a map of the named capture groups with their captured submatches.
func MustCtxTotalRolls ¶
func NewContextFromContext ¶
NewContextFromContext makes a child context from a given context, including setting the context's maximum rolls and adding a roll counter if not present.
Types ¶
type CompareOp ¶
type CompareOp int
CompareOp is an comparison operator usable in modifiers.
Comparison operators.
func LookupCompareOp ¶
LookupCompareOp returns the CompareOp that is represented by a given string.
func (*CompareOp) MarshalJSON ¶
MarshalJSON ensures the CompareOp is encoded as its string representation.
func (*CompareOp) UnmarshalJSON ¶
UnmarshalJSON enables JSON encoded string versions of CompareOps to be converted to their appropriate counterparts.
type CompareTarget ¶
type CompareTarget struct { Compare CompareOp `json:"compare,omitempty"` Target int `json:"target"` }
CompareTarget is the base comparison
type CriticalFailureModifier ¶
type CriticalFailureModifier struct {
*CompareTarget
}
A CriticalFailureModifier shifts or sets the compare point/range used to classify a die's result as a critical failure.
func (*CriticalFailureModifier) String ¶
func (m *CriticalFailureModifier) String() string
type CriticalSuccessModifier ¶
type CriticalSuccessModifier struct {
*CompareTarget
}
A CriticalSuccessModifier shifts or sets the compare point/range used to classify a die's result as a critical success.
func (*CriticalSuccessModifier) String ¶
func (m *CriticalSuccessModifier) String() string
type Die ¶
type Die struct { // Generic properties Type DieType `json:"type,omitempty" mapstructure:"type"` Size int `json:"size" mapstructure:"size"` Rerolls int `json:"rerolls" mapstructure:"rerolls"` *Result `json:"result,omitempty" mapstructure:"result"` Modifiers ModifierList `json:"modifiers,omitempty" mapstructure:"modifiers"` // contains filtered or unexported fields }
Die represents an internally-typed die. If Result is a non-nil pointer, it is considered rolled.
Example ¶
die := &Die{ Size: 20, } fateDie := &Die{ Type: TypeFudge, Size: 1, } fmt.Println(die, fateDie)
Output: d20 dF
func (*Die) FullRoll ¶
FullRoll rolls the Die. The die will be reset if it had been rolled previously.
func (*Die) String ¶
String returns an expression-like representation of a rolled die or its type, if it has not been rolled.
func (*Die) ToGraphviz ¶
type DieType ¶
type DieType string
DieType is the enum of types that a die or dice can be
type DropKeepMethod ¶
type DropKeepMethod string
A DropKeepMethod is a method to use when evaluating a drop/keep modifier against a dice group.
const ( DropKeepMethodUnknown DropKeepMethod = "" DropKeepMethodDrop DropKeepMethod = "d" DropKeepMethodDropLowest DropKeepMethod = "dl" DropKeepMethodDropHighest DropKeepMethod = "dh" DropKeepMethodKeep DropKeepMethod = "k" DropKeepMethodKeepLowest DropKeepMethod = "kl" DropKeepMethodKeepHighest DropKeepMethod = "kh" )
Drop/keep methods.
type DropKeepModifier ¶
type DropKeepModifier struct { Method DropKeepMethod `json:"op,omitempty"` Num int `json:"num"` }
A DropKeepModifier is a modifier to drop the highest or lowest Num dice within a group by marking them as Dropped. The Method used to apply the modifier defines if the dice are dropped or kept (meaning the Num highest dice are not dropped).
func (*DropKeepModifier) Apply ¶
func (d *DropKeepModifier) Apply(ctx context.Context, r Roller) error
Apply executes a DropKeepModifier against a Roller. If the Roller is not a Group an error is returned.
func (*DropKeepModifier) String ¶
func (d *DropKeepModifier) String() string
type ErrNotImplemented ¶
type ErrNotImplemented struct {
// contains filtered or unexported fields
}
ErrNotImplemented is an error returned when a feature is not yet implemented.
func NewErrNotImplemented ¶
func NewErrNotImplemented(message string) *ErrNotImplemented
NewErrNotImplemented returns a new not implemented error.
func (*ErrNotImplemented) Error ¶
func (e *ErrNotImplemented) Error() string
type ErrParseError ¶
ErrParseError is an error encountered when parsing a string into dice notation.
func (*ErrParseError) Error ¶
func (e *ErrParseError) Error() string
type ExplodeModifier ¶
type ExplodeModifier struct { *CompareTarget Once bool `json:"once,omitempty"` }
func (*ExplodeModifier) Apply ¶
func (m *ExplodeModifier) Apply(ctx context.Context, r Roller) error
func (*ExplodeModifier) String ¶
func (m *ExplodeModifier) String() string
type Group ¶
type Group []Roller
A Group is a slice of rollables.
func (Group) Expression ¶
Expression returns an expression to represent the group's total. Dice in the group that are unrolled are replaced with their roll notations and dropped dice results are omitted.
func (Group) FullRoll ¶
FullRoll implements the Roller interface's FullRoll method by rolling each object/Roller within the group.
func (Group) Swap ¶
Swap swaps the positions of two Rollers in a Group. This method is not thread safe.
func (Group) ToGraphviz ¶
type Modifier ¶
type Modifier interface { // Apply executes a modifier against a Die. Apply(context.Context, Roller) error fmt.Stringer }
A Modifier is a dice modifier that can apply to a set or a single die.
type ModifierList ¶
type ModifierList []Modifier
ModifierList is a slice of modifiers that implements Stringer.
func (ModifierList) String ¶
func (m ModifierList) String() string
type RerollModifier ¶
type RerollModifier struct { *CompareTarget Once bool `json:"once,omitempty"` }
RerollModifier is a modifier that rerolls a Die if a comparison against the compare target is true.
func (*RerollModifier) Apply ¶
func (m *RerollModifier) Apply(ctx context.Context, r Roller) error
Apply executes a RerollModifier against a Roller. The modifier may be slightly modified the first time it is applied to ensure property consistency.
The full roll needs to be recalculated in the event that one result may be acceptable for one reroll criteria, but not for one that was already evaluated. An ErrRerolled error will be returned if the die was rerolled in case other modifiers on the die need to be reapplied. Impossible rerolls and impossible combinations of rerolls may cause a stack overflow from recursion without a safeguard like MaxRerolls.
func (*RerollModifier) MarshalJSON ¶
func (m *RerollModifier) MarshalJSON() ([]byte, error)
MarshalJSON marshals the modifier into JSON and includes an internal type property.
func (*RerollModifier) String ¶
func (m *RerollModifier) String() string
type Result ¶
type Result struct { Value float64 `json:"value"` Dropped bool `json:"dropped,omitempty"` CritSuccess bool `json:"crit,omitempty"` CritFailure bool `json:"fumble,omitempty"` }
A Result is a value a die has rolled. By default, CritSuccess and CritFailure should be set to true if the maximum or minimum value of a die is rolled respectively, but the range in which a critical success/failure must be overridable through modifiers.
type Roller ¶
type Roller interface { // FullRoll rolls the object at the macro level, inclusive of testing and // applying modifiers. FullRoll(context.Context) error // Roll rolls and records the object's Result. Roll should not apply // modifiers. However, it should always increment the appropriate roll // count context key. Roll(context.Context) error // Reroll resets the object and should re-roll the core die by calling Roll. // Methods used by Reroll should not call FullRoll without safeguards to // prevent a stack overflow. Reroll(context.Context) error // Total returns the summed results, omitting any dropped results. Total(context.Context) (float64, error) // Value returns the rolled face value of the Roller, regardless of whether // the Roller was dropped. Value should be used when sorting. Value(context.Context) (float64, error) // Drop marks the object dropped based on a provided boolean. Drop(context.Context, bool) // IsDropped returns the dropped status of the Roller. IsDropped(context.Context) bool // Parent returns the parent of the Roller, or nil. Parent() Roller // SetParent sets the parent of the Roller. SetParent(Roller) // Add associates a Roller as a child. Add(Roller) // Must implement a String method; if the object has not been rolled String // should return a stringified representation of that can be re-parsed to // yield an equivalent property set. fmt.Stringer ToGraphviz() string }
Roller must be implemented for an object to be considered rollable. Internally, a Roller and should maintain a "total rolls" count.
func Filter ¶
Filter is a helper function that returns a slice of Rollers that match a predicate out of an input slice.
func MustNewDie ¶
func MustNewDie(props *RollerProperties) Roller
MustNewDie creates a new die off of a properties list. It will tweak the properties list to better suit reuse. Panics on a non-nil error.
func MustNewRoller ¶
func MustNewRoller(props *RollerProperties) Roller
MustNewRoller creates a new Roller from a properties set using NewRoller and panics if NewRoller returns an error.
func NewDie ¶
func NewDie(props *RollerProperties) (Roller, error)
NewDie creates a new die off of a properties list. It will tweak the properties list to better suit reuse.
func NewDieWithParent ¶
func NewDieWithParent(props *RollerProperties, parent Roller) (Roller, error)
NewDieWithParent creates a new die off of a properties list. It will tweak the properties list to better suit reuse.
func NewRoller ¶
func NewRoller(props *RollerProperties) (Roller, error)
NewRoller wraps NewRollerWithParent but a parent is not bound to the Roller.
Example ¶
ctx := context.Background() roll, _ := NewRoller(&RollerProperties{ Type: TypePolyhedron, Size: 6, }) die := roll.(*Die) fmt.Println(die) _ = roll.FullRoll(ctx) fmt.Println(die)
Output:
func NewRollerWithParent ¶
func NewRollerWithParent(props *RollerProperties, parent Roller) (Roller, error)
NewRollerWithParent creates a new Die to roll off of a supplied property set. The property set is modified/linted to better suit defaults in the event a properties list is reused.
New dice created with this function are created by the per-DieType factories declared within the package-level RollerFactoryMap.
type RollerFactory ¶
type RollerFactory func(*RollerProperties, Roller) (Roller, error)
A RollerFactory is a function that takes a properties object and returns a valid rollable die based off of the properties list. If there is an error creating a die off of the properties list an error should be returned.
type RollerGroup ¶
type RollerGroup struct { Group `json:"group" mapstructure:"group"` Modifiers ModifierList `json:"modifiers,omitempty" mapstructure:"modifiers"` // contains filtered or unexported fields }
RollerGroup is a wrapper around a Group that implements Roller. The Modifiers supplied at this level should be group-level modifiers, like drop/keep modifiers.
func MustNewRollerGroup ¶
func MustNewRollerGroup(props *RollerProperties) *RollerGroup
MustNewRollerGroup creates a new RollerGroup from properties using NewRollerGroup and panics if the method returns an error.
func NewRollerGroup ¶
func NewRollerGroup(props *RollerProperties) (*RollerGroup, error)
NewRollerGroup creates a new dice group with the count provided by the properties list. If a count of dice was not specified within the properties list it will default to a count of 1 and tweak the provided properties object accordingly.
func (*RollerGroup) Add ¶
func (d *RollerGroup) Add(r Roller)
Add adds a Roller to the RollerGroup's embedded Group and sets this as the Roller's parent.
func (*RollerGroup) FullRoll ¶
func (d *RollerGroup) FullRoll(ctx context.Context) error
FullRoll rolls each die embedded in the dice group.
func (*RollerGroup) Reroll ¶
func (d *RollerGroup) Reroll(ctx context.Context) error
Reroll re-rolls each die within the dice group.
func (*RollerGroup) ToGraphviz ¶
func (d *RollerGroup) ToGraphviz() string
type RollerProperties ¶
type RollerProperties struct { Type DieType `json:"type,omitempty" mapstructure:"type"` Size int `json:"size,omitempty" mapstructure:"size"` Result *Result `json:"result,omitempty" mapstructure:"result"` Count int `json:"count,omitempty" mapstructure:"count"` // Modifiers for the dice or parent set DieModifiers ModifierList `json:"die_modifiers,omitempty" mapstructure:"die_modifiers"` GroupModifiers ModifierList `json:"group_modifiers,omitempty" mapstructure:"group_modifiers"` }
A RollerProperties object is the set of properties (usually extracted from a notation) that should be used to define a Die or group of like dice (a slice of multiple Die).
This may be best broken into two properties types, a RollerProperties and a RollerGroupProperties.
func ParseNotation ¶
func ParseNotation(ctx context.Context, notation string) (RollerProperties, error)
ParseNotation parses the provided notation with updated regular expressions that also extract dice group modifiers.
type SortDirection ¶
type SortDirection uint8
SortDirection is a possible direction for sorting dice.
const ( SortDirectionAscending SortDirection = iota SortDirectionDescending )
Sort directions for sorting modifiers.
type SortModifier ¶
type SortModifier struct {
Direction SortDirection `json:"direction"`
}
SortModifier is a modifier that will sort the Roller group.
func (*SortModifier) Apply ¶
func (s *SortModifier) Apply(ctx context.Context, r Roller) error
Apply applies a sort to a Roller.
func (*SortModifier) String ¶
func (s *SortModifier) String() string
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
cmd
|
|
dice
Package dice defines a CLI for the package.
|
Package dice defines a CLI for the package. |
dice/command
Package command defines the subcommands available to the dice CLI.
|
Package command defines the subcommands available to the dice CLI. |
Package math implements dice expression mathematics and functions.
|
Package math implements dice expression mathematics and functions. |