Add debug logging to loopCountCheck

This commit is contained in:
Ean Milligan 2025-08-05 17:48:24 -04:00
parent c80b7c2235
commit e06abac9cf
20 changed files with 74 additions and 55 deletions

View File

@ -23,6 +23,7 @@ export interface SolvedRoll {
line1: string;
line2: string;
line3: string;
footer: string;
counts: CountDetails;
rollDistributions: RollDistributionMap;
}

View File

@ -5,12 +5,12 @@ import { tokenizeCmd } from 'artigen/cmdTokenizer.ts';
import { Modifiers } from 'artigen/dice/getModifiers.ts';
import { loopCountCheck } from 'artigen/managers/loopManager.ts';
import { getLoopCount, loopCountCheck } from 'artigen/managers/loopManager.ts';
import { QueuedRoll } from 'artigen/managers/manager.d.ts';
import { reduceCountDetails } from 'artigen/utils/counter.ts';
import { cmdSplitRegex, escapeCharacters, withYVarsDash } from 'artigen/utils/escape.ts';
import { loggingEnabled } from 'artigen/utils/logFlag.ts';
import { loggingEnabled, loopLoggingEnabled } from 'artigen/utils/logFlag.ts';
import { assertPrePostBalance } from 'artigen/utils/parenBalance.ts';
import { reduceRollDistMaps } from 'artigen/utils/rollDist.ts';
import { compareTotalRolls, compareTotalRollsReverse, sortYVars } from 'artigen/utils/sortFuncs.ts';
@ -26,6 +26,7 @@ export const runCmd = (rollRequest: QueuedRoll): SolvedRoll => {
line1: '',
line2: '',
line3: '',
footer: '',
counts: {
total: 0,
successful: 0,
@ -120,7 +121,7 @@ export const runCmd = (rollRequest: QueuedRoll): SolvedRoll => {
const line2Space = rollRequest.modifiers.noSpaces ? '' : ' ';
// Fill out all of the details and results now
tempReturnData.forEach((e, i) => {
loopCountCheck();
loopCountCheck('artigen.ts - tempReturnData');
loggingEnabled && log(LT.LOG, `Parsing roll ${rollRequest.rollCmd} | Making return text ${JSON.stringify(e)}`);
let preFormat = '';
@ -178,5 +179,7 @@ export const runCmd = (rollRequest: QueuedRoll): SolvedRoll => {
[returnMsg.errorCode, returnMsg.errorMsg] = translateError(solverError);
}
if (loopLoggingEnabled) returnMsg.footer = `Loop Count: ${getLoopCount()}`;
return returnMsg;
};

View File

@ -32,7 +32,7 @@ export const tokenizeCmd = (
// Wrapped commands still exist, unwrap them
while (cmd.includes(config.prefix)) {
loopCountCheck();
loopCountCheck('cmdTokenizer.ts - while cmd includes prefix');
const openIdx = cmd.indexOf(config.prefix);
const closeIdx = getMatchingPostfixIdx(cmd, openIdx);
@ -49,7 +49,7 @@ export const tokenizeCmd = (
const simulatedData: ReturnData[] = [];
for (let i = 0; i < simulatedLoopCount; i++) {
loopCountCheck();
loopCountCheck('cmdTokenizer.ts - simulate nominal loop');
loggingEnabled && log(LT.LOG, `In simLoop:${i} "${currentCmd}" of ${JSON.stringify(cmd)}`);
@ -78,7 +78,7 @@ export const tokenizeCmd = (
loggingEnabled && log(LT.LOG, `ConfirmCrit on ${JSON.stringify(currentCmd)}`);
let done = false;
while (!done) {
loopCountCheck();
loopCountCheck('cmdTokenizer.ts - confirming crit');
// Keep running the same roll again until its not successful
const [ccTempData, ccTempCounts, ccTempDists] = tokenizeCmd(
@ -194,7 +194,7 @@ export const tokenizeCmd = (
const tempInitConf = data.initConfig.split(internalGrpWrapRegex).filter((x) => x);
loggingEnabled && log(LT.LOG, `Split solved math into tempInitConf ${JSON.stringify(tempInitConf)}`);
while (tempInitConf.includes(openInternalGrp)) {
loopCountCheck();
loopCountCheck('cmdTokenizer.ts - handling internal group result merging');
const openIdx = tempInitConf.indexOf(openInternalGrp);
const closeIdx = getMatchingInternalGrpIdx(tempInitConf, openIdx);
@ -214,7 +214,7 @@ export const tokenizeCmd = (
.filter((x) => x);
loggingEnabled && log(LT.LOG, `Split tempInitConfig into initConf ${JSON.stringify(initConf)}`);
while (initConf.includes(openInternal)) {
loopCountCheck();
loopCountCheck('cmdTokenizer.ts - handling internal nested roll result merging');
const openIdx = initConf.indexOf(openInternal);
const closeIdx = getMatchingInternalIdx(initConf, openIdx);

View File

@ -80,7 +80,7 @@ export const executeRoll = (rollStr: string, modifiers: RollModifiers): Executed
for (let i = 0; i < rollConf.dieCount; i++) {
loggingEnabled && log(LT.LOG, `${getLoopCount()} Handling ${rollConf.type} ${rollStr} | Initial rolling ${i} of ${JSON.stringify(rollConf)}`);
// If loopCount gets too high, stop trying to calculate infinity
loopCountCheck();
loopCountCheck('executeRoll.ts - handling initial rolling');
// Copy the template to fill out for this iteration
const rolling = getTemplateRoll();
@ -104,7 +104,7 @@ export const executeRoll = (rollStr: string, modifiers: RollModifiers): Executed
for (let i = 0; i < rollSet.length; i++) {
loggingEnabled && log(LT.LOG, `${getLoopCount()} Handling ${rollConf.type} ${rollStr} | Handling rerolling and exploding ${JSON.stringify(rollSet[i])}`);
// If loopCount gets too high, stop trying to calculate infinity
loopCountCheck();
loopCountCheck('executeRoll.ts - handling rerolling and exploding');
// This big boolean statement first checks if reroll is on, if the roll is within the reroll range, and finally if ro is ON, make sure we haven't already rerolled the roll
if (rollConf.reroll.on && rollConf.reroll.nums.includes(rollSet[i].roll) && (!rollConf.reroll.once || !rollSet[i ? i - 1 : i].rerolled)) {
@ -117,7 +117,7 @@ export const executeRoll = (rollStr: string, modifiers: RollModifiers): Executed
if (modifiers.maxRoll && !minMaxOverride) {
// If maximizeRoll is on and we've entered the reroll code, dieSize is not allowed, determine the next best option and always return that
mmMaxLoop: for (let m = rollConf.dieSize - 1; m > 0; m--) {
loopCountCheck();
loopCountCheck('executeRoll.ts - maximizeRoll');
if (!rollConf.reroll.nums.includes(m)) {
minMaxOverride = m;
@ -127,7 +127,7 @@ export const executeRoll = (rollStr: string, modifiers: RollModifiers): Executed
} else if (modifiers.minRoll && !minMaxOverride) {
// If minimizeRoll is on and we've entered the reroll code, 1 is not allowed, determine the next best option and always return that
mmMinLoop: for (let m = rollConf.dPercent.on ? 1 : 2; m <= rollConf.dieSize; m++) {
loopCountCheck();
loopCountCheck('executeRoll.ts - minimizeRoll');
if (!rollConf.reroll.nums.includes(m)) {
minMaxOverride = m;
@ -181,7 +181,7 @@ export const executeRoll = (rollStr: string, modifiers: RollModifiers): Executed
for (const penRoll of rollSet) {
loggingEnabled && log(LT.LOG, `${getLoopCount()} Handling ${rollConf.type} ${rollStr} | Handling penetrating explosions ${JSON.stringify(penRoll)}`);
// If loopCount gets too high, stop trying to calculate infinity
loopCountCheck();
loopCountCheck('executeRoll.ts - penetrating explosion');
// If the die was from an explosion, decrement it by one
if (penRoll.exploding) {
@ -195,7 +195,7 @@ export const executeRoll = (rollStr: string, modifiers: RollModifiers): Executed
for (let i = 0; i < rollSet.length; i++) {
loggingEnabled && log(LT.LOG, `${getLoopCount()} Handling ${rollConf.type} ${rollStr} | Handling compounding explosions ${JSON.stringify(rollSet[i])}`);
// If loopCount gets too high, stop trying to calculate infinity
loopCountCheck();
loopCountCheck('executeRoll.ts - compounding explosion');
// Compound the exploding rolls, including the exploding flag and
if (rollSet[i].exploding) {
@ -215,8 +215,7 @@ export const executeRoll = (rollStr: string, modifiers: RollModifiers): Executed
let rerollCount = 0;
if (rollConf.reroll.on) {
for (let j = 0; j < rollSet.length; j++) {
// If loopCount gets too high, stop trying to calculate infinity
loopCountCheck();
loopCountCheck('executeRoll.ts - count rerolls');
loggingEnabled && log(LT.LOG, `${getLoopCount()} Handling ${rollConf.type} ${rollStr} | Setting originalIdx on ${JSON.stringify(rollSet[j])}`);
rollSet[j].origIdx = j;
@ -265,8 +264,7 @@ export const executeRoll = (rollStr: string, modifiers: RollModifiers): Executed
// Now its time to drop all dice needed
let i = 0;
while (dropCount > 0 && i < rollSet.length) {
// If loopCount gets too high, stop trying to calculate infinity
loopCountCheck();
loopCountCheck('executeRoll.ts - dropping/keeping');
loggingEnabled && log(LT.LOG, `${getLoopCount()} Handling ${rollConf.type} ${rollStr} | Dropping dice ${dropCount} ${JSON.stringify(rollSet[i])}`);
// Skip all rolls that were rerolled
@ -290,7 +288,7 @@ export const executeRoll = (rollStr: string, modifiers: RollModifiers): Executed
// Drop all dice that are not a part of the max
for (const ovaRoll of rollSet) {
loopCountCheck();
loopCountCheck('executeRoll.ts - OVA');
loggingEnabled &&
log(LT.LOG, `${getLoopCount()} Handling ${rollConf.type} ${rollStr} | checking if this roll should be dropped ${ovaRoll.roll} | to keep: ${maxRoll}`);
@ -311,7 +309,7 @@ export const executeRoll = (rollStr: string, modifiers: RollModifiers): Executed
const labels = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
let labelIdx = 0;
const rollLabels: Array<string> = rollVals.map((count) => {
loopCountCheck();
loopCountCheck('executeRoll.ts - matching');
if (labelIdx >= labels.length) {
throw new Error(`TooManyLabels_${labels.length}`);
@ -327,7 +325,7 @@ export const executeRoll = (rollStr: string, modifiers: RollModifiers): Executed
// Apply labels
for (const roll of rollSet) {
loopCountCheck();
loopCountCheck('executeRoll.ts - labeling matches');
loggingEnabled && log(LT.LOG, `${getLoopCount()} Handling ${rollConf.type} ${rollStr} | trying to add a label to ${JSON.stringify(roll)}`);
if (rollLabels[roll.roll - 1]) {

View File

@ -20,7 +20,7 @@ export const formatRoll = (executedRoll: ExecutedRoll, modifiers: RollModifiers)
// Loop thru all parts of the roll to document everything that was done to create the total roll
loggingEnabled && log(LT.LOG, `Formatting roll ${JSON.stringify(executedRoll)}`);
executedRoll.rollSet.forEach((e) => {
loopCountCheck();
loopCountCheck('generateFormattedRoll.ts - formatting executed roll');
loggingEnabled && log(LT.LOG, `At ${JSON.stringify(e)}`);
let preFormat = '';

View File

@ -14,7 +14,7 @@ export const getGroupConf = (groupStr: string, rawStr: string): GroupConf => {
let biggest = parseInt(numberMatches.length ? numberMatches[0] : '1');
for (const num of numberMatches) {
loopCountCheck();
loopCountCheck('getGroupConf.ts - finding biggest number for die size');
const curNum = parseInt(num);
loggingEnabled && log(LT.LOG, `Finding biggest number to use as die size, ${curNum} ${biggest}`);
@ -37,7 +37,7 @@ export const getGroupConf = (groupStr: string, rawStr: string): GroupConf => {
let maxFail: number | null = null;
while (groupSplit.length) {
loopCountCheck();
loopCountCheck('getGroupConf.ts - parsing groupConf');
const option = groupSplit.shift() ?? '';
const value = parseInt(groupSplit.shift() ?? '');

View File

@ -126,7 +126,7 @@ export const getRollConf = (rollStr: string, customTypes: CustomDiceShapes = new
const difficulty = parseInt(tempDifficulty.slice(0, afterDifficultyIdx) || '10');
for (let i = difficulty; i <= rollConf.dieSize; i++) {
loopCountCheck();
loopCountCheck('getRollConf.ts - setting cwod difficulty');
loggingEnabled && log(LT.LOG, `${getLoopCount()} Handling cwod ${rollStr} | Parsing difficulty ${i}`);
rollConf.success.range.push(i);
@ -216,7 +216,7 @@ export const getRollConf = (rollStr: string, customTypes: CustomDiceShapes = new
// Loop until all remaining args are parsed
while (remains.length > 0) {
loopCountCheck();
loopCountCheck('getRollConf.ts - parsing rollConf');
loggingEnabled && log(LT.LOG, `${getLoopCount()} Handling ${rollConf.type} ${rollStr} | Parsing remains ${remains}`);
// Find the next number in the remains to be able to cut out the rule name
@ -232,7 +232,7 @@ export const getRollConf = (rollStr: string, customTypes: CustomDiceShapes = new
let noNumberAfter = false;
if (!(Object.values(DiceOptions) as string[]).includes(tempSep)) {
NumberlessDiceOptions.some((opt) => {
loopCountCheck();
loopCountCheck('getRollConf.ts - parsing numberlessDiceOptions');
loggingEnabled && log(LT.LOG, `In NumberlessDiceOptions ${opt} ${tempSep.startsWith(opt) && tempSep !== opt}`);
if (tempSep.startsWith(opt) && tempSep !== opt) {
afterSepIdx = opt.length;

View File

@ -30,7 +30,7 @@ export const handleGroup = (
// Nested groups still exist, unwrap them
while (groupParts.includes('{')) {
loopCountCheck();
loopCountCheck('groupHandler.ts - handling nested groups');
loggingEnabled && log(LT.LOG, `Handling Nested Groups | Current cmd: ${JSON.stringify(groupParts)}`);
@ -72,7 +72,7 @@ export const handleGroup = (
const groupResults: ReturnData[] = [];
for (const part of commaParts) {
loopCountCheck();
loopCountCheck('groupHandler.ts - solving commaParts');
loggingEnabled && log(LT.LOG, `Solving commaPart: ${part}`);
const [tempData, tempCounts, tempDists] = tokenizeMath(part, modifiers, previousResults, prevGrpReturnData);
@ -131,7 +131,7 @@ export const handleGroup = (
let i = 0;
while (dropCount > 0 && i < groupResults.length) {
loopCountCheck();
loopCountCheck('groupHandler.ts - handling group drop/keep');
loggingEnabled && log(LT.LOG, `Handling group dropping | Dropping ${dropCount}`);
@ -148,7 +148,7 @@ export const handleGroup = (
let failCnt = 0;
if (groupConf.success.on || groupConf.fail.on) {
groupResults.forEach((rd, idx) => {
loopCountCheck();
loopCountCheck('groupHandler.ts - handling group success/fail');
if (!resultFlags[idx].dropped) {
if (
@ -265,7 +265,7 @@ export const handleGroup = (
const initConf = retData.initConfig.split(internalGrpWrapRegex).filter((x) => x);
loggingEnabled && log(LT.LOG, `Split retData into initConf ${JSON.stringify(initConf)}`);
while (initConf.includes(openInternalGrp)) {
loopCountCheck();
loopCountCheck('groupHandler.ts - handling merging nested groups up');
const openIdx = initConf.indexOf(openInternalGrp);
const closeIdx = getMatchingInternalGrpIdx(initConf, openIdx);

View File

@ -1,12 +1,13 @@
import { closeLog, initLog } from '@Log4Deno';
import { runCmd } from 'artigen/artigen.ts';
import { SolvedRoll } from 'artigen/artigen.d.ts';
import { QueuedRoll } from 'artigen/managers/manager.d.ts';
import { loggingEnabled } from 'artigen/utils/logFlag.ts';
import { loggingEnabled, loopLoggingEnabled } from 'artigen/utils/logFlag.ts';
loggingEnabled && initLog('logs/worker', loggingEnabled);
(loggingEnabled || loopLoggingEnabled) && initLog('logs/worker', loggingEnabled || loopLoggingEnabled);
// Extend the BigInt prototype to support JSON.stringify
interface BigIntX extends BigInt {
@ -23,13 +24,14 @@ self.postMessage('ready');
// Handle the roll
self.onmessage = async (e: MessageEvent<QueuedRoll>) => {
const payload = e.data;
const returnMsg = runCmd(payload) || {
const returnMsg: SolvedRoll = runCmd(payload) || {
error: true,
errorCode: 'EmptyMessage',
errorMsg: 'Error: Empty message',
line1: '',
line2: '',
line3: '',
footer: '',
counts: {
total: 0,
successful: 0,
@ -37,6 +39,9 @@ self.onmessage = async (e: MessageEvent<QueuedRoll>) => {
rerolled: 0,
dropped: 0,
exploded: 0,
success: 0,
fail: 0,
matches: new Map<string, number>(),
},
};
self.postMessage(returnMsg);

View File

@ -1,10 +1,15 @@
import { log, LogTypes as LT } from '@Log4Deno';
import config from '~config';
import { loopLoggingEnabled } from 'artigen/utils/logFlag.ts';
let loopCount = 0;
// Will ensure if maxLoops is 10, 10 loops will be allowed, 11 will not.
export const loopCountCheck = (): void => {
export const loopCountCheck = (location = 'unset'): void => {
loopCount++;
loopLoggingEnabled && log(LT.LOG, `Loop #${loopCount} at "${location}"`);
if (loopCount > config.limits.maxLoops) {
throw new Error('MaxLoopsExceeded');
}

View File

@ -34,7 +34,7 @@ export const mathSolver = (conf: MathConf[], wrapDetails = false): SolvedStep =>
// Evaluate all parenthesis
while (conf.includes('(')) {
loopCountCheck();
loopCountCheck('mathSolver.ts - evaluating parens');
loggingEnabled && log(LT.LOG, `Evaluating roll ${JSON.stringify(conf)} | Looking for (`);
// Get first open parenthesis
@ -75,7 +75,7 @@ export const mathSolver = (conf: MathConf[], wrapDetails = false): SolvedStep =>
// Start at index 1 as there will never be implicit multiplication before the first element
loggingEnabled && log(LT.LOG, `Checking for missing implicit multiplication ${JSON.stringify(conf)}`);
for (let i = 1; i < conf.length; i++) {
loopCountCheck();
loopCountCheck('mathSolver.ts - checking for implicit multiplication');
const prevConfAsStr = <string> conf[i - 1];
const curConfAsStr = <string> conf[i];
@ -94,10 +94,11 @@ export const mathSolver = (conf: MathConf[], wrapDetails = false): SolvedStep =>
['+', '-'],
];
allCurOps.forEach((curOps) => {
// No loopCountCheck here since its finite/will always be 3 loops
loggingEnabled && log(LT.LOG, `Evaluating roll ${JSON.stringify(conf)} | Evaluating ${JSON.stringify(curOps)}`);
// Iterate thru all operators/operands in the conf
for (let i = 0; i < conf.length; i++) {
loopCountCheck();
loopCountCheck('mathSolver.ts - evaluating roll');
loggingEnabled && log(LT.LOG, `Evaluating roll ${JSON.stringify(conf)} | Evaluating ${JSON.stringify(curOps)} | Checking ${JSON.stringify(conf[i])}`);
// Check if the current index is in the active tier of operators

View File

@ -49,7 +49,7 @@ export const tokenizeMath = (
// Evaluate all rolls into stepSolve format and all numbers into floats
for (let i = 0; i < mathConf.length; i++) {
loopCountCheck();
loopCountCheck('mathTokenizer.ts - parsing all tokens into MathConf');
loggingEnabled && log(LT.LOG, `Parsing roll ${JSON.stringify(cmd)} | Evaluating rolls into math-able items ${JSON.stringify(mathConf[i])}`);
@ -272,7 +272,7 @@ export const tokenizeMath = (
let i = 0;
while (dropCount > 0 && i < allRollSets.length) {
loopCountCheck();
loopCountCheck('mathTokenizer.ts - handling group dropping');
loggingEnabled && log(LT.LOG, `Handling group dropping | Dropping ${dropCount}, looking at ${JSON.stringify(allRollSets[i])}`);
@ -293,7 +293,7 @@ export const tokenizeMath = (
// Handle marking new successes/fails
if (groupConf.success.on || groupConf.fail.on) {
allRollSets.forEach((rs) => {
loopCountCheck();
loopCountCheck('mathTokenizer.ts - handling group success/fails');
if (!rs.dropped && !rs.rerolled) {
if (groupConf.success.on && groupConf.success.range.includes(rs.roll)) {

View File

@ -16,7 +16,7 @@ export const rollCounter = (rollSet: RollSet[]): CountDetails => {
};
rollSet.forEach((roll) => {
loopCountCheck();
loopCountCheck('counter.ts - summing RollSet into CountDetails');
countDetails.total++;
if (roll.critHit) countDetails.successful++;
if (roll.critFail) countDetails.failed++;
@ -34,9 +34,9 @@ export const rollCounter = (rollSet: RollSet[]): CountDetails => {
export const reduceCountDetails = (counts: CountDetails[]): CountDetails =>
counts.reduce(
(acc, cur) => {
loopCountCheck();
loopCountCheck('counter.ts - merging array of CountDetails down to single CountDetail');
cur.matches.forEach((cnt, label) => {
loopCountCheck();
loopCountCheck('counter.ts - merging matches');
acc.matches.set(label, (acc.matches.get(label) ?? 0) + cnt);
});
return {

View File

@ -259,13 +259,17 @@ export const generateRollEmbed = (
// Embed desc limit is 4096
// Discord only formats 200 items per message
if (fullDesc.length < 4_000 && formattingCount <= 200) {
const fullSize = fullDesc.length + returnDetails.footer.length;
if (fullSize < 4_000 && formattingCount <= 200) {
// Response is valid size
return {
charCount: fullDesc.length,
charCount: fullSize,
embed: {
color: infoColor2,
description: fullDesc,
footer: {
text: returnDetails.footer,
},
},
hasAttachment: false,
};

View File

@ -11,7 +11,7 @@ import { loggingEnabled } from 'artigen/utils/logFlag.ts';
export const escapeCharacters = (str: string, esc: string): string => {
// Loop thru each esc char one at a time
for (const e of esc) {
loopCountCheck();
loopCountCheck('escape.ts - escaping characters');
loggingEnabled && log(LT.LOG, `Escaping character ${e} | ${str}, ${esc}`);
// Create a new regex to look for that char that needs replaced and escape it

View File

@ -1 +1,2 @@
export const loggingEnabled = false;
export const loopLoggingEnabled = false;

View File

@ -22,7 +22,8 @@ const checkBalance = (
// Verify there are equal numbers of opening and closing parenthesis by adding 1 for opening parens and subtracting 1 for closing parens
for (let i = openIdx; i < conf.length; i++) {
countLoops && loopCountCheck();
countLoops &&
loopCountCheck(`parenBalance.ts - ${getMatching ? 'Looking for matching' : 'Checking'} ${openStr}/${closeStr} ${getMatching ? '' : 'balance '}`);
loggingEnabled &&
log(
LT.LOG,

View File

@ -14,7 +14,7 @@ export const addToRange = (tSep: string, range: Array<number>, tNum: number) =>
const internalAddMultipleToRange = (tSep: string, range: Array<number>, start: number, end: number) => {
for (let i = start; i <= end; i++) {
loopCountCheck();
loopCountCheck(`rangeAdder.ts - ${tSep} range adder`);
addToRange(tSep, range, i);
}
};

View File

@ -10,7 +10,7 @@ export const createRollDistMap = (rollSet: RollSet[]): RollDistributionMap => {
const rollDistMap = new Map<string, number[]>();
rollSet.forEach((roll) => {
loopCountCheck();
loopCountCheck('rollDist.ts - convert RollSet into RollDist');
const tempArr: number[] = rollDistMap.get(rollDistKey(roll.type, roll.size)) ?? new Array<number>(roll.type === 'fate' ? roll.size + 2 : roll.size).fill(0);
tempArr[roll.type === 'fate' ? roll.roll + 1 : roll.roll - 1]++;
rollDistMap.set(rollDistKey(roll.type, roll.size), tempArr);
@ -22,17 +22,17 @@ export const createRollDistMap = (rollSet: RollSet[]): RollDistributionMap => {
// Collapses an array of RollDistMaps into a single RollDistMap
export const reduceRollDistMaps = (rollDistArr: RollDistributionMap[]): RollDistributionMap =>
rollDistArr.reduce((acc, cur) => {
loopCountCheck();
loopCountCheck('rollDist.ts - merge array of RollDists into single RollDist');
cur
.entries()
.toArray()
.forEach(([key, value]) => {
loopCountCheck();
loopCountCheck('rollDist.ts - doing the merge on each item of current');
const tempArr = acc.get(key) ?? new Array<number>(value.length).fill(0);
for (let i = 0; i < tempArr.length; i++) {
loopCountCheck();
loopCountCheck('rollDist.ts - doing the merge');
tempArr[i] += value[i];
}

View File

@ -12,7 +12,7 @@ export const generateRollVals = (rollConf: RollConf, rollSet: RollSet[], rollStr
// Count up all rolls
for (const ovaRoll of rollSet) {
loopCountCheck();
loopCountCheck('rollValCounter.ts - counting roll vals');
loggingEnabled && log(LT.LOG, `${getLoopCount()} Handling ${rollConf.type} ${rollStr} | incrementing rollVals for ${JSON.stringify(ovaRoll)}`);
if (!ovaRoll.dropped && !ovaRoll.rerolled) {