UNPKG

@randsum/dice

Version:

A flexible, type-safe dice roller for tabletop RPGs, game development, and probability simulations

64 lines (63 loc) 2.35 kB
import { CapModifier, DropModifier, ExplodeModifier, MinusModifier, PlusModifier, ReplaceModifier, RerollModifier, UniqueModifier, coreNotationPattern, isDiceNotation, optionsConverter } from '@randsum/core'; import { D } from '../D'; import { isD } from '../guards/isD'; export function normalizeArgument(argument) { const options = optionsFromArgument(argument); return { argument, options, die: dieForArgument(argument), notation: optionsConverter.toNotation(options), description: optionsConverter.toDescription(options) }; } function optionsFromArgument(argument) { if (isD(argument)) { return argument.toOptions; } if (isDiceNotation(argument)) { const coreNotationMatch = argument.match(coreNotationPattern) ?? ''; const coreMatch = coreNotationMatch[0]; const modifiersString = argument.replace(coreMatch, ''); const [quantity, sides = ''] = coreMatch.split(/[Dd]/); if (sides.includes('{')) { return { quantity: Number(quantity), sides: [...sides.replaceAll(/{|}/g, '')] }; } return { quantity: Number(quantity), sides: Number(sides), ...{ modifiers: { ...DropModifier.parse(modifiersString), ...ExplodeModifier.parse(modifiersString), ...UniqueModifier.parse(modifiersString), ...ReplaceModifier.parse(modifiersString), ...RerollModifier.parse(modifiersString), ...CapModifier.parse(modifiersString), ...PlusModifier.parse(modifiersString), ...MinusModifier.parse(modifiersString) } } }; } if (Array.isArray(argument)) { return { quantity: 1, sides: argument.map(String) }; } if (typeof argument === 'string' || typeof argument === 'number') { return { quantity: 1, sides: Number(argument) }; } return argument; } function dieForArgument(argument) { if (isD(argument)) { return argument; } const options = optionsFromArgument(argument); if (Array.isArray(options.sides)) { return D(options.sides); } return D(options.sides); }