Skip to content

Commit

Permalink
Turn to models (#633)
Browse files Browse the repository at this point in the history
  • Loading branch information
alxjrvs authored Sep 23, 2024
1 parent 17f3e0b commit 3623b72
Show file tree
Hide file tree
Showing 22 changed files with 489 additions and 471 deletions.
4 changes: 4 additions & 0 deletions src/D.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ class D<Sides extends string[] | number> {
}

roll(): Result<Faces<Sides>> {
return this._rawRollResult()
}

protected _rawRollResult(): Result<Faces<Sides>> {
return this.faces[this._rawRoll()] as Result<Faces<Sides>>
}

Expand Down
3 changes: 1 addition & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
export * from './D'
export { roll } from './roll'
export { validateDiceNotation } from './validateDiceNotation'
export { parameterizeRollArgument } from './parameterizeRollArgument'
export * from './models'
export * from './types'
96 changes: 96 additions & 0 deletions src/models/ArgumentsModel/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import {
RandsumRollArgument,
DicePools,
RandsumRollOptions,
RandsumRollParameters
} from '~types'
import { uuidv7 as uuid } from 'uuidv7'
import {
isD,
isCustomSidesD,
isDicePoolOptions,
isDiceNotationArg
} from '~guards'
import { NotationModel, OptionsModel } from '~models'
import { D } from '~src/D'

function formDicePools(args: RandsumRollArgument[]): DicePools {
return {
dicePools: args.reduce(
(acc, arg) => ({ ...acc, [uuid()]: parameterize(arg) }),
{}
)
}
}

function normalizeArgument(argument: RandsumRollArgument): RandsumRollOptions {
if (isD(argument)) {
return {
quantity: 1,
sides: isCustomSidesD(argument) ? argument.faces : argument.sides
}
}

if (isDicePoolOptions(argument)) {
return argument
}

if (isDiceNotationArg(argument)) {
return NotationModel.toOptions(argument)
}

if (Array.isArray(argument)) {
return {
quantity: 1,
sides: argument.map(String)
}
}

return {
quantity: 1,
sides: Number(argument || 20)
}
}

function parameterize(argument: RandsumRollArgument): RandsumRollParameters {
const options = normalizeArgument(argument)
const die = new D(options.sides)
return {
options,
argument,
die,
notation: OptionsModel.toNotation(options),
description: OptionsModel.toDescription(options)
}
}

function normalize(argument: RandsumRollArgument): RandsumRollOptions {
if (isD(argument)) {
return {
quantity: 1,
sides: isCustomSidesD(argument) ? argument.faces : argument.sides
}
}

if (isDicePoolOptions(argument)) {
return argument
}

if (isDiceNotationArg(argument)) {
return NotationModel.toOptions(argument)
}

if (Array.isArray(argument)) {
return {
quantity: 1,
sides: argument.map(String)
}
}

return {
quantity: 1,
sides: Number(argument || 20)
}
}

export default { formDicePools, normalize, parameterize }
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
import {
RandsumRollParameters,
DicePoolType,
DicePools,
RandsumRollResult
} from '~types'
import { applyModifiers } from './applyModifiers'
import { generateRawRolls } from './generateRawRolls'
import { isFullNumArray } from '~guards'
import { ParametersModel, RawRollsModel } from '~models'
import { DicePools, DicePoolType, RandsumRollResult } from '~types'

function calculateType(dicePools: DicePools['dicePools']): DicePoolType {
switch (true) {
Expand All @@ -32,17 +26,15 @@ function calculateTotal(rolls: number[] | string[], bonus = 0): number {
return 0
}

function generateModifiedRolls(
export function generateModifiedRolls(
DicePools: DicePools,
rawRolls: RandsumRollResult['rawRolls']
): RandsumRollResult['modifiedRolls'] {
return Object.fromEntries(
Object.keys(DicePools.dicePools).map((key) => {
const pool = DicePools.dicePools[key] as
| RandsumRollParameters<string>
| RandsumRollParameters<number>
const params = DicePools.dicePools[key]
const rolls = rawRolls[key]
const modified = applyModifiers(pool, rolls)
const modified = ParametersModel.applyModifiers(params, rolls)
const modifiedRoll = {
rolls: modified.rolls,
total: calculateTotal(modified.rolls, modified.simpleMathModifier)
Expand All @@ -53,7 +45,7 @@ function generateModifiedRolls(
}

function generateRollResult(DicePools: DicePools): RandsumRollResult {
const rawRolls = generateRawRolls(DicePools.dicePools)
const rawRolls = RawRollsModel.generate(DicePools.dicePools)
const modifiedRolls = generateModifiedRolls(DicePools, rawRolls)
const modifiedValues = Object.values(modifiedRolls)
const rawResult = Object.values(rawRolls)
Expand All @@ -71,5 +63,6 @@ function generateRollResult(DicePools: DicePools): RandsumRollResult {
total
}
}

export { generateRollResult }
export default {
generateRollResult
}
32 changes: 30 additions & 2 deletions src/models/NotationModel/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import { coreNotationPattern } from '~patterns'
import { RandsumNotation, RandsumRollOptions } from '~types'
import {
DicePoolType,
RandsumNotation,
RandsumNotationValidationResult,
RandsumRollOptions
} from '~types'
import { parseCoreNotation, parseModifiers } from './optionsParsers'
import { isDiceNotationArg, isCustomSidesArg } from '~guards'
import { OptionsModel } from '~models'

function toOptions(
notationString: RandsumNotation
Expand All @@ -14,4 +21,25 @@ function toOptions(
}
}

export default { toOptions }
function validate(notation: string): RandsumNotationValidationResult {
if (!isDiceNotationArg(notation)) {
return {
valid: false,
description: []
}
}

const digested = toOptions(notation)

return {
valid: true,
digested,
notation: OptionsModel.toNotation(digested),
type: isCustomSidesArg(digested.sides)
? DicePoolType.custom
: DicePoolType.numerical,
description: OptionsModel.toDescription(digested)
}
}

export default { toOptions, validate }
117 changes: 117 additions & 0 deletions src/models/ParametersModel/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import { isCustomParameters } from '~guards'
import { RandsumRollParameters } from '~types'
import {
applyReroll,
applyUnique,
applyReplace,
applyDrop,
applyExplode,
applySingleCap
} from './modifierApplicators'

type RollBonuses = {
rolls: number[]
simpleMathModifier: number
}

type ModifiedRollBonuses = {
rolls: string[]
simpleMathModifier: 0
}
function applyModifiers(
poolParameters: RandsumRollParameters<string> | RandsumRollParameters<number>,
initialRolls: number[] | string[]
): RollBonuses | ModifiedRollBonuses {
if (isCustomParameters(poolParameters)) {
return {
simpleMathModifier: 0,
rolls: initialRolls as string[]
}
}

const rollBonuses: RollBonuses = {
simpleMathModifier: 0,
rolls: initialRolls as number[]
}

const {
options: { sides, quantity, modifiers = {} }
} = poolParameters

const rollOne: () => number = () => poolParameters.die.roll()

return Object.keys(modifiers).reduce((bonuses, key) => {
switch (key) {
case 'reroll':
return {
...bonuses,
rolls: modifiers.reroll
? applyReroll(bonuses.rolls, modifiers.reroll, rollOne)
: bonuses.rolls
}

case 'unique':
return {
...bonuses,
rolls: modifiers.unique
? applyUnique(
bonuses.rolls,
{ sides, quantity: quantity || 1, unique: modifiers.unique },
rollOne
)
: bonuses.rolls
}

case 'replace':
return {
...bonuses,
rolls: modifiers.replace
? applyReplace(bonuses.rolls, modifiers.replace)
: bonuses.rolls
}

case 'cap':
return {
...bonuses,
rolls: modifiers.cap
? bonuses.rolls.map(applySingleCap(modifiers.cap))
: bonuses.rolls
}

case 'drop':
return {
...bonuses,
rolls: modifiers.drop
? applyDrop(bonuses.rolls, modifiers.drop)
: bonuses.rolls
}

case 'explode':
return {
...bonuses,
rolls: modifiers.explode
? applyExplode(bonuses.rolls, { sides }, rollOne)
: bonuses.rolls
}

case 'plus':
return {
...bonuses,
simpleMathModifier:
bonuses.simpleMathModifier + Number(modifiers.plus)
}

case 'minus':
return {
...bonuses,
simpleMathModifier:
bonuses.simpleMathModifier - Number(modifiers.minus)
}

default:
throw new Error(`Unknown modifier: ${key}`)
}
}, rollBonuses)
}

export default { applyModifiers }
Loading

0 comments on commit 3623b72

Please sign in to comment.