@mcptoolshop/roll 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/LICENSE +21 -0
  3. package/README.es.md +204 -0
  4. package/README.fr.md +204 -0
  5. package/README.hi.md +204 -0
  6. package/README.it.md +204 -0
  7. package/README.ja.md +204 -0
  8. package/README.md +204 -0
  9. package/README.pt-BR.md +204 -0
  10. package/README.zh.md +204 -0
  11. package/dist/analyze/distribution.d.ts +6 -0
  12. package/dist/analyze/distribution.d.ts.map +1 -0
  13. package/dist/analyze/distribution.js +252 -0
  14. package/dist/analyze/distribution.js.map +1 -0
  15. package/dist/analyze/montecarlo.d.ts +5 -0
  16. package/dist/analyze/montecarlo.d.ts.map +1 -0
  17. package/dist/analyze/montecarlo.js +19 -0
  18. package/dist/analyze/montecarlo.js.map +1 -0
  19. package/dist/analyze/stats.d.ts +16 -0
  20. package/dist/analyze/stats.d.ts.map +1 -0
  21. package/dist/analyze/stats.js +66 -0
  22. package/dist/analyze/stats.js.map +1 -0
  23. package/dist/bin.d.ts +3 -0
  24. package/dist/bin.d.ts.map +1 -0
  25. package/dist/bin.js +267 -0
  26. package/dist/bin.js.map +1 -0
  27. package/dist/display/box.d.ts +5 -0
  28. package/dist/display/box.d.ts.map +1 -0
  29. package/dist/display/box.js +26 -0
  30. package/dist/display/box.js.map +1 -0
  31. package/dist/display/color.d.ts +12 -0
  32. package/dist/display/color.d.ts.map +1 -0
  33. package/dist/display/color.js +19 -0
  34. package/dist/display/color.js.map +1 -0
  35. package/dist/display/format.d.ts +13 -0
  36. package/dist/display/format.d.ts.map +1 -0
  37. package/dist/display/format.js +134 -0
  38. package/dist/display/format.js.map +1 -0
  39. package/dist/display/histogram.d.ts +7 -0
  40. package/dist/display/histogram.d.ts.map +1 -0
  41. package/dist/display/histogram.js +48 -0
  42. package/dist/display/histogram.js.map +1 -0
  43. package/dist/engine/random.d.ts +6 -0
  44. package/dist/engine/random.d.ts.map +1 -0
  45. package/dist/engine/random.js +17 -0
  46. package/dist/engine/random.js.map +1 -0
  47. package/dist/engine/roller.d.ts +19 -0
  48. package/dist/engine/roller.d.ts.map +1 -0
  49. package/dist/engine/roller.js +168 -0
  50. package/dist/engine/roller.js.map +1 -0
  51. package/dist/index.d.ts +27 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/index.js +37 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/loot/table.d.ts +27 -0
  56. package/dist/loot/table.d.ts.map +1 -0
  57. package/dist/loot/table.js +92 -0
  58. package/dist/loot/table.js.map +1 -0
  59. package/dist/parser/ast.d.ts +27 -0
  60. package/dist/parser/ast.d.ts.map +1 -0
  61. package/dist/parser/ast.js +2 -0
  62. package/dist/parser/ast.js.map +1 -0
  63. package/dist/parser/lexer.d.ts +7 -0
  64. package/dist/parser/lexer.d.ts.map +1 -0
  65. package/dist/parser/lexer.js +126 -0
  66. package/dist/parser/lexer.js.map +1 -0
  67. package/dist/parser/parser.d.ts +7 -0
  68. package/dist/parser/parser.d.ts.map +1 -0
  69. package/dist/parser/parser.js +188 -0
  70. package/dist/parser/parser.js.map +1 -0
  71. package/dist/parser/tokens.d.ts +25 -0
  72. package/dist/parser/tokens.d.ts.map +1 -0
  73. package/dist/parser/tokens.js +21 -0
  74. package/dist/parser/tokens.js.map +1 -0
  75. package/package.json +55 -0
@@ -0,0 +1,134 @@
1
+ import { bold, dim, red, green, yellow, cyan, boldGreen, boldRed, boldYellow, magenta } from "./color.js";
2
+ import { drawBox } from "./box.js";
3
+ const DICE_FACES = ["⚀", "⚁", "⚂", "⚃", "⚄", "⚅"];
4
+ function dieFace(value, sides) {
5
+ if (sides === 6 && value >= 1 && value <= 6) {
6
+ return DICE_FACES[value - 1];
7
+ }
8
+ return String(value);
9
+ }
10
+ function formatDie(die, maxSide) {
11
+ const face = dieFace(die.value, maxSide);
12
+ if (!die.kept)
13
+ return dim(`[${face}]`);
14
+ if (die.exploded)
15
+ return magenta(`${face}!`);
16
+ if (die.value === maxSide && maxSide > 1)
17
+ return boldGreen(face); // crit
18
+ if (die.value === 1 && maxSide > 1)
19
+ return boldRed(face); // fumble
20
+ return face;
21
+ }
22
+ function formatGroup(group) {
23
+ // Determine max side for crit/fumble detection
24
+ const maxSide = inferMaxSide(group.expression);
25
+ const dice = group.dice.map((d) => formatDie(d, maxSide)).join(" ");
26
+ return `${dim(group.expression)}: ${dice} ${dim("=")} ${bold(String(group.total))}`;
27
+ }
28
+ function inferMaxSide(expr) {
29
+ const match = expr.match(/d(\d+)/);
30
+ if (match)
31
+ return parseInt(match[1], 10);
32
+ if (expr.includes("d%"))
33
+ return 100;
34
+ if (expr.includes("dF"))
35
+ return 1;
36
+ return 6;
37
+ }
38
+ /** Format a roll result for terminal display. */
39
+ export function formatRollResult(result, expression) {
40
+ const lines = [];
41
+ // Show each dice group
42
+ for (const group of result.groups) {
43
+ lines.push(formatGroup(group));
44
+ }
45
+ // Total
46
+ const totalStr = boldYellow(` ${result.total} `);
47
+ lines.push("");
48
+ lines.push(`${bold("Total:")} ${totalStr}`);
49
+ return drawBox(lines, `${cyan("roll")} ${expression}`);
50
+ }
51
+ /** Format stats summary for terminal display. */
52
+ export function formatStats(stats) {
53
+ const lines = [];
54
+ lines.push(`${bold("Mean:")} ${stats.mean.toFixed(2)}`);
55
+ lines.push(`${bold("Median:")} ${stats.median}`);
56
+ lines.push(`${bold("Mode:")} ${stats.mode}`);
57
+ lines.push(`${bold("Std Dev:")} ${stats.stddev.toFixed(2)}`);
58
+ lines.push(`${bold("Range:")} ${stats.min}${dim("–")}${stats.max}`);
59
+ lines.push(`${bold("Entropy:")} ${stats.entropy.toFixed(2)} bits`);
60
+ lines.push("");
61
+ lines.push(bold("Percentiles:"));
62
+ const pctKeys = [10, 25, 50, 75, 90, 95];
63
+ const pctLine = pctKeys
64
+ .map((k) => `${dim(`p${k}:`)}${stats.percentiles[k] ?? "?"}`)
65
+ .join(" ");
66
+ lines.push(` ${pctLine}`);
67
+ return drawBox(lines, "Statistics");
68
+ }
69
+ /** Format probability for --at-least display. */
70
+ export function formatAtLeast(target, probability, expression) {
71
+ const pct = (probability * 100).toFixed(2);
72
+ const lines = [];
73
+ // Visual probability bar
74
+ const barWidth = 40;
75
+ const filled = Math.round(probability * barWidth);
76
+ const bar = green("█".repeat(filled)) + dim("░".repeat(barWidth - filled));
77
+ lines.push(`P(${bold(expression)} >= ${bold(String(target))})`);
78
+ lines.push("");
79
+ lines.push(` ${bar} ${boldYellow(pct + "%")}`);
80
+ lines.push("");
81
+ if (probability >= 0.95)
82
+ lines.push(green(" Almost certain"));
83
+ else if (probability >= 0.75)
84
+ lines.push(green(" Very likely"));
85
+ else if (probability >= 0.5)
86
+ lines.push(yellow(" Likely"));
87
+ else if (probability >= 0.25)
88
+ lines.push(yellow(" Possible"));
89
+ else if (probability >= 0.05)
90
+ lines.push(red(" Unlikely"));
91
+ else
92
+ lines.push(red(" Very unlikely"));
93
+ return drawBox(lines, "At Least");
94
+ }
95
+ /** Format a comparison of two distributions side by side. */
96
+ export function formatComparison(expr1, stats1, expr2, stats2) {
97
+ const w = 12;
98
+ const lines = [];
99
+ const header = `${"".padEnd(10)}${bold(expr1.padEnd(w))}${bold(expr2.padEnd(w))}${bold("Diff")}`;
100
+ lines.push(header);
101
+ lines.push(dim("─".repeat(10 + w * 2 + 8)));
102
+ function row(label, v1, v2, decimals = 2) {
103
+ const s1 = v1.toFixed(decimals).padEnd(w);
104
+ const s2 = v2.toFixed(decimals).padEnd(w);
105
+ const diff = v1 - v2;
106
+ const diffStr = diff > 0 ? green(`+${diff.toFixed(decimals)}`) : diff < 0 ? red(diff.toFixed(decimals)) : dim("0");
107
+ lines.push(`${dim(label.padEnd(10))}${s1}${s2}${diffStr}`);
108
+ }
109
+ row("Mean", stats1.mean, stats2.mean);
110
+ row("Median", stats1.median, stats2.median, 0);
111
+ row("Mode", stats1.mode, stats2.mode, 0);
112
+ row("Std Dev", stats1.stddev, stats2.stddev);
113
+ row("Min", stats1.min, stats2.min, 0);
114
+ row("Max", stats1.max, stats2.max, 0);
115
+ row("Entropy", stats1.entropy, stats2.entropy);
116
+ return drawBox(lines, "Comparison");
117
+ }
118
+ /** Format roll result as JSON. */
119
+ export function formatJson(result, expression) {
120
+ return JSON.stringify({
121
+ expression,
122
+ total: result.total,
123
+ groups: result.groups.map((g) => ({
124
+ expression: g.expression,
125
+ total: g.total,
126
+ dice: g.dice.map((d) => ({
127
+ value: d.value,
128
+ kept: d.kept,
129
+ ...(d.exploded ? { exploded: true } : {}),
130
+ })),
131
+ })),
132
+ }, null, 2);
133
+ }
134
+ //# sourceMappingURL=format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/display/format.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { Distribution } from "../analyze/distribution.js";
2
+ import type { DistributionStats } from "../analyze/stats.js";
3
+ /** Render a horizontal bar chart of a probability distribution. */
4
+ export declare function renderHistogram(dist: Distribution, stats: DistributionStats, maxWidth?: number): string;
5
+ /** Render a compact sparkline for inline display. */
6
+ export declare function renderSparkline(dist: Distribution): string;
7
+ //# sourceMappingURL=histogram.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"histogram.d.ts","sourceRoot":"","sources":["../../src/display/histogram.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAM7D,mEAAmE;AACnE,wBAAgB,eAAe,CAC7B,IAAI,EAAE,YAAY,EAClB,KAAK,EAAE,iBAAiB,EACxB,QAAQ,SAAK,GACZ,MAAM,CAqCR;AAED,qDAAqD;AACrD,wBAAgB,eAAe,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAQ1D"}
@@ -0,0 +1,48 @@
1
+ import { bold, dim, cyan, yellow, boldCyan } from "./color.js";
2
+ const FULL_BLOCK = "\u2588";
3
+ const BLOCKS = [" ", "\u2581", "\u2582", "\u2583", "\u2584", "\u2585", "\u2586", "\u2587", "\u2588"];
4
+ /** Render a horizontal bar chart of a probability distribution. */
5
+ export function renderHistogram(dist, stats, maxWidth = 60) {
6
+ const entries = [...dist.entries()].sort((a, b) => a[0] - b[0]);
7
+ if (entries.length === 0)
8
+ return "";
9
+ const maxProb = Math.max(...entries.map(([, p]) => p));
10
+ const lines = [];
11
+ // Header
12
+ lines.push(boldCyan(" Distribution"));
13
+ lines.push("");
14
+ // Determine label width
15
+ const maxLabel = Math.max(...entries.map(([v]) => String(v).length));
16
+ const barWidth = Math.min(maxWidth, (process.stdout.columns || 80) - maxLabel - 15);
17
+ for (const [value, prob] of entries) {
18
+ const label = String(value).padStart(maxLabel);
19
+ const barLen = Math.round((prob / maxProb) * barWidth);
20
+ const bar = FULL_BLOCK.repeat(barLen);
21
+ const pctStr = (prob * 100).toFixed(2).padStart(6) + "%";
22
+ // Highlight mode
23
+ const isMode = value === stats.mode;
24
+ const isMedian = value === stats.median;
25
+ let prefix = " ";
26
+ if (isMode && isMedian)
27
+ prefix = bold("M>");
28
+ else if (isMode)
29
+ prefix = bold("*>");
30
+ else if (isMedian)
31
+ prefix = "~>";
32
+ const coloredBar = isMode ? yellow(bar) : cyan(bar);
33
+ const coloredPct = isMode ? bold(pctStr) : dim(pctStr);
34
+ lines.push(`${prefix}${dim(label)} ${coloredBar} ${coloredPct}`);
35
+ }
36
+ return lines.join("\n");
37
+ }
38
+ /** Render a compact sparkline for inline display. */
39
+ export function renderSparkline(dist) {
40
+ const entries = [...dist.entries()].sort((a, b) => a[0] - b[0]);
41
+ if (entries.length === 0)
42
+ return "";
43
+ const maxProb = Math.max(...entries.map(([, p]) => p));
44
+ return entries
45
+ .map(([, p]) => BLOCKS[Math.round((p / maxProb) * 8)])
46
+ .join("");
47
+ }
48
+ //# sourceMappingURL=histogram.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"histogram.js","sourceRoot":"","sources":["../../src/display/histogram.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export type RngFn = (min: number, max: number) => number;
2
+ /** Cryptographically secure random integer in [min, max] (inclusive). */
3
+ export declare const cryptoRng: RngFn;
4
+ /** Create a seeded PRNG for deterministic testing. Simple mulberry32. */
5
+ export declare function seededRng(seed: number): RngFn;
6
+ //# sourceMappingURL=random.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"random.d.ts","sourceRoot":"","sources":["../../src/engine/random.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,KAAK,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;AAEzD,yEAAyE;AACzE,eAAO,MAAM,SAAS,EAAE,KAEvB,CAAC;AAEF,yEAAyE;AACzE,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,CAS7C"}
@@ -0,0 +1,17 @@
1
+ import { randomInt } from "node:crypto";
2
+ /** Cryptographically secure random integer in [min, max] (inclusive). */
3
+ export const cryptoRng = (min, max) => {
4
+ return randomInt(min, max + 1); // crypto.randomInt upper bound is exclusive
5
+ };
6
+ /** Create a seeded PRNG for deterministic testing. Simple mulberry32. */
7
+ export function seededRng(seed) {
8
+ let state = seed | 0;
9
+ return (min, max) => {
10
+ state = (state + 0x6d2b79f5) | 0;
11
+ let t = Math.imul(state ^ (state >>> 15), 1 | state);
12
+ t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
13
+ const raw = ((t ^ (t >>> 14)) >>> 0) / 4294967296;
14
+ return min + Math.floor(raw * (max - min + 1));
15
+ };
16
+ }
17
+ //# sourceMappingURL=random.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"random.js","sourceRoot":"","sources":["../../src/engine/random.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAIxC,yEAAyE;AACzE,MAAM,CAAC,MAAM,SAAS,GAAU,CAAC,GAAW,EAAE,GAAW,EAAU,EAAE;IACnE,OAAO,SAAS,CAAC,GAAG,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,4CAA4C;AAC9E,CAAC,CAAC;AAEF,yEAAyE;AACzE,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,IAAI,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC;IACrB,OAAO,CAAC,GAAW,EAAE,GAAW,EAAU,EAAE;QAC1C,KAAK,GAAG,CAAC,KAAK,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,KAAK,KAAK,EAAE,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC;QACrD,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAC/C,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,UAAU,CAAC;QAClD,OAAO,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;IACjD,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,19 @@
1
+ import type { ASTNode } from "../parser/ast.js";
2
+ import { type RngFn } from "./random.js";
3
+ export interface DieResult {
4
+ value: number;
5
+ kept: boolean;
6
+ exploded: boolean;
7
+ }
8
+ export interface DiceGroupResult {
9
+ expression: string;
10
+ dice: DieResult[];
11
+ total: number;
12
+ }
13
+ export interface RollResult {
14
+ expression: string;
15
+ total: number;
16
+ groups: DiceGroupResult[];
17
+ }
18
+ export declare function evaluate(ast: ASTNode, rng?: RngFn): RollResult;
19
+ //# sourceMappingURL=roller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"roller.d.ts","sourceRoot":"","sources":["../../src/engine/roller.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAqC,MAAM,kBAAkB,CAAC;AACnF,OAAO,EAAa,KAAK,KAAK,EAAE,MAAM,aAAa,CAAC;AAEpD,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,SAAS,EAAE,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,eAAe,EAAE,CAAC;CAC3B;AAiJD,wBAAgB,QAAQ,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,GAAE,KAAiB,GAAG,UAAU,CAsCzE"}
@@ -0,0 +1,168 @@
1
+ import { cryptoRng } from "./random.js";
2
+ const MAX_EXPLOSIONS = 100;
3
+ function resolveSides(sides) {
4
+ if (sides === "%")
5
+ return 100;
6
+ if (sides === "F")
7
+ return 3; // internal: we roll 0-2 and map to -1,0,+1
8
+ return sides;
9
+ }
10
+ function rollSingleDie(sides, rng) {
11
+ if (sides === "F") {
12
+ return rng(0, 2) - 1; // -1, 0, +1
13
+ }
14
+ const max = sides === "%" ? 100 : sides;
15
+ return rng(1, max);
16
+ }
17
+ function rollDiceGroup(node, rng) {
18
+ const maxSide = resolveSides(node.sides);
19
+ const isFate = node.sides === "F";
20
+ // Determine explosion settings
21
+ const explodeMod = node.modifiers.find((m) => m.kind === "explode");
22
+ const explodeThreshold = explodeMod
23
+ ? explodeMod.value ?? (isFate ? undefined : maxSide)
24
+ : undefined;
25
+ // Roll initial dice
26
+ const rawRolls = [];
27
+ for (let i = 0; i < node.count; i++) {
28
+ let roll = rollSingleDie(node.sides, rng);
29
+ rawRolls.push(roll);
30
+ // Handle exploding
31
+ if (explodeThreshold !== undefined && !isFate) {
32
+ let explosions = 0;
33
+ while (roll >= explodeThreshold && explosions < MAX_EXPLOSIONS) {
34
+ roll = rollSingleDie(node.sides, rng);
35
+ rawRolls.push(roll);
36
+ explosions++;
37
+ }
38
+ }
39
+ }
40
+ // Build die results (all kept initially)
41
+ const dice = rawRolls.map((value) => ({
42
+ value,
43
+ kept: true,
44
+ exploded: false,
45
+ }));
46
+ // Mark exploded dice
47
+ if (explodeThreshold !== undefined && !isFate) {
48
+ let dieIndex = 0;
49
+ for (let i = 0; i < node.count; i++) {
50
+ // Skip the initial die
51
+ dieIndex++;
52
+ // Mark subsequent exploded dice
53
+ while (dieIndex < dice.length &&
54
+ dice[dieIndex - 1].value >= explodeThreshold) {
55
+ dice[dieIndex].exploded = true;
56
+ dieIndex++;
57
+ }
58
+ }
59
+ }
60
+ // Apply keep/drop modifiers
61
+ for (const mod of node.modifiers) {
62
+ if (mod.kind === "explode")
63
+ continue;
64
+ applyKeepDrop(dice, mod);
65
+ }
66
+ const total = dice.filter((d) => d.kept).reduce((sum, d) => sum + d.value, 0);
67
+ // Build expression string
68
+ let expr = `${node.count}d${node.sides === "%" ? "%" : node.sides === "F" ? "F" : node.sides}`;
69
+ for (const mod of node.modifiers) {
70
+ if (mod.kind === "explode") {
71
+ expr += "!";
72
+ if (mod.value !== undefined)
73
+ expr += `>${mod.value}`;
74
+ }
75
+ else {
76
+ expr += mod.kind;
77
+ if (mod.value !== undefined)
78
+ expr += mod.value;
79
+ }
80
+ }
81
+ return { expression: expr, dice, total };
82
+ }
83
+ function applyKeepDrop(dice, mod) {
84
+ const n = mod.value ?? 1;
85
+ const keptDice = dice.filter((d) => d.kept);
86
+ // Sort by value to determine which to keep/drop
87
+ const sorted = [...keptDice].sort((a, b) => a.value - b.value);
88
+ switch (mod.kind) {
89
+ case "kh": {
90
+ // Keep highest N — drop everything else
91
+ const threshold = sorted.length - n;
92
+ let dropped = 0;
93
+ for (const d of sorted) {
94
+ if (dropped < threshold) {
95
+ d.kept = false;
96
+ dropped++;
97
+ }
98
+ }
99
+ break;
100
+ }
101
+ case "kl": {
102
+ // Keep lowest N — drop everything else
103
+ let kept = 0;
104
+ for (const d of sorted) {
105
+ if (kept < n) {
106
+ kept++;
107
+ }
108
+ else {
109
+ d.kept = false;
110
+ }
111
+ }
112
+ break;
113
+ }
114
+ case "dh": {
115
+ // Drop highest N
116
+ let dropped = 0;
117
+ for (let i = sorted.length - 1; i >= 0 && dropped < n; i--) {
118
+ sorted[i].kept = false;
119
+ dropped++;
120
+ }
121
+ break;
122
+ }
123
+ case "dl": {
124
+ // Drop lowest N
125
+ let dropped = 0;
126
+ for (let i = 0; i < sorted.length && dropped < n; i++) {
127
+ sorted[i].kept = false;
128
+ dropped++;
129
+ }
130
+ break;
131
+ }
132
+ }
133
+ }
134
+ export function evaluate(ast, rng = cryptoRng) {
135
+ const groups = [];
136
+ function walk(node) {
137
+ switch (node.type) {
138
+ case "number":
139
+ return node.value;
140
+ case "dice": {
141
+ const group = rollDiceGroup(node, rng);
142
+ groups.push(group);
143
+ return group.total;
144
+ }
145
+ case "binary": {
146
+ const left = walk(node.left);
147
+ const right = walk(node.right);
148
+ switch (node.op) {
149
+ case "+":
150
+ return left + right;
151
+ case "-":
152
+ return left - right;
153
+ case "*":
154
+ return left * right;
155
+ case "/":
156
+ return right === 0 ? 0 : Math.floor(left / right);
157
+ }
158
+ break;
159
+ }
160
+ case "unary_minus":
161
+ return -walk(node.operand);
162
+ }
163
+ return 0;
164
+ }
165
+ const total = walk(ast);
166
+ return { expression: "", total, groups };
167
+ }
168
+ //# sourceMappingURL=roller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"roller.js","sourceRoot":"","sources":["../../src/engine/roller.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ export { parse, ParseError } from "./parser/parser.js";
2
+ export { tokenize, LexerError } from "./parser/lexer.js";
3
+ export type { ASTNode, DiceNode, NumberNode, BinaryOpNode, UnaryMinusNode, DiceModifier, DiceSides } from "./parser/ast.js";
4
+ export { TokenType } from "./parser/tokens.js";
5
+ export type { Token } from "./parser/tokens.js";
6
+ export { evaluate } from "./engine/roller.js";
7
+ export type { RollResult, DiceGroupResult, DieResult } from "./engine/roller.js";
8
+ export { cryptoRng, seededRng } from "./engine/random.js";
9
+ export type { RngFn } from "./engine/random.js";
10
+ export { computeDistribution } from "./analyze/distribution.js";
11
+ export type { Distribution } from "./analyze/distribution.js";
12
+ export { computeStats, probabilityAtLeast } from "./analyze/stats.js";
13
+ export type { DistributionStats } from "./analyze/stats.js";
14
+ export { monteCarloDistribution } from "./analyze/montecarlo.js";
15
+ export { rollLootTable, validateLootTables } from "./loot/table.js";
16
+ export type { LootTable, LootItem, LootDrop, LootTableCollection } from "./loot/table.js";
17
+ import type { RollResult } from "./engine/roller.js";
18
+ import type { RngFn } from "./engine/random.js";
19
+ /** Roll a dice expression and return the result. */
20
+ export declare function roll(expression: string, rng?: RngFn): RollResult;
21
+ /** Analyze a dice expression — returns distribution, stats, and a P(>=target) function. */
22
+ export declare function analyze(expression: string): {
23
+ distribution: import("./analyze/distribution.js").Distribution;
24
+ stats: import("./analyze/stats.js").DistributionStats;
25
+ probabilityAtLeast: (target: number) => number;
26
+ };
27
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACzD,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5H,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,YAAY,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAGhD,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACjF,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC1D,YAAY,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAGhD,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,YAAY,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACtE,YAAY,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAGjE,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACpE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAO1F,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAEhD,oDAAoD;AACpD,wBAAgB,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,KAAK,GAAG,UAAU,CAKhE;AAED,2FAA2F;AAC3F,wBAAgB,OAAO,CAAC,UAAU,EAAE,MAAM;;;iCAOT,MAAM;EAEtC"}
package/dist/index.js ADDED
@@ -0,0 +1,37 @@
1
+ // Parser
2
+ export { parse, ParseError } from "./parser/parser.js";
3
+ export { tokenize, LexerError } from "./parser/lexer.js";
4
+ export { TokenType } from "./parser/tokens.js";
5
+ // Engine
6
+ export { evaluate } from "./engine/roller.js";
7
+ export { cryptoRng, seededRng } from "./engine/random.js";
8
+ // Analysis
9
+ export { computeDistribution } from "./analyze/distribution.js";
10
+ export { computeStats, probabilityAtLeast } from "./analyze/stats.js";
11
+ export { monteCarloDistribution } from "./analyze/montecarlo.js";
12
+ // Loot
13
+ export { rollLootTable, validateLootTables } from "./loot/table.js";
14
+ // Convenience functions
15
+ import { parse as _parse } from "./parser/parser.js";
16
+ import { evaluate as _evaluate } from "./engine/roller.js";
17
+ import { computeDistribution as _computeDist } from "./analyze/distribution.js";
18
+ import { computeStats as _computeStats, probabilityAtLeast as _probAtLeast } from "./analyze/stats.js";
19
+ /** Roll a dice expression and return the result. */
20
+ export function roll(expression, rng) {
21
+ const ast = _parse(expression);
22
+ const result = _evaluate(ast, rng);
23
+ result.expression = expression;
24
+ return result;
25
+ }
26
+ /** Analyze a dice expression — returns distribution, stats, and a P(>=target) function. */
27
+ export function analyze(expression) {
28
+ const ast = _parse(expression);
29
+ const dist = _computeDist(ast);
30
+ const stats = _computeStats(dist);
31
+ return {
32
+ distribution: dist,
33
+ stats,
34
+ probabilityAtLeast: (target) => _probAtLeast(dist, target),
35
+ };
36
+ }
37
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,SAAS;AACT,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEzD,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAG/C,SAAS;AACT,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAG1D,WAAW;AACX,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAEhE,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAEtE,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,OAAO;AACP,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAGpE,wBAAwB;AACxB,OAAO,EAAE,KAAK,IAAI,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,QAAQ,IAAI,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,mBAAmB,IAAI,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAChF,OAAO,EAAE,YAAY,IAAI,aAAa,EAAE,kBAAkB,IAAI,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAIvG,oDAAoD;AACpD,MAAM,UAAU,IAAI,CAAC,UAAkB,EAAE,GAAW;IAClD,MAAM,GAAG,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;IAC/B,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACnC,MAAM,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/B,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,2FAA2F;AAC3F,MAAM,UAAU,OAAO,CAAC,UAAkB;IACxC,MAAM,GAAG,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;IAC/B,MAAM,IAAI,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;IAC/B,MAAM,KAAK,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IAClC,OAAO;QACL,YAAY,EAAE,IAAI;QAClB,KAAK;QACL,kBAAkB,EAAE,CAAC,MAAc,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC;KACnE,CAAC;AACJ,CAAC"}
@@ -0,0 +1,27 @@
1
+ import type { RngFn } from "../engine/random.js";
2
+ export interface LootItem {
3
+ name: string;
4
+ weight: number;
5
+ roll?: string;
6
+ table?: string;
7
+ quantity?: string;
8
+ }
9
+ export interface LootTable {
10
+ table: string;
11
+ items: LootItem[];
12
+ }
13
+ export interface LootDrop {
14
+ item: string;
15
+ quantity: number;
16
+ rollValue?: number;
17
+ rollExpression?: string;
18
+ fromTable: string;
19
+ }
20
+ export interface LootTableCollection {
21
+ tables: LootTable[];
22
+ }
23
+ /** Roll on a loot table, resolving nested tables and dice expressions. */
24
+ export declare function rollLootTable(tables: LootTable[], tableName?: string, rng?: RngFn, depth?: number): LootDrop[];
25
+ /** Validate a loot table collection. Returns errors or empty array. */
26
+ export declare function validateLootTables(tables: LootTable[]): string[];
27
+ //# sourceMappingURL=table.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../../src/loot/table.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAGjD,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,QAAQ,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,SAAS,EAAE,CAAC;CACrB;AAED,0EAA0E;AAC1E,wBAAgB,aAAa,CAC3B,MAAM,EAAE,SAAS,EAAE,EACnB,SAAS,CAAC,EAAE,MAAM,EAClB,GAAG,GAAE,KAAiB,EACtB,KAAK,SAAI,GACR,QAAQ,EAAE,CAgEZ;AAED,uEAAuE;AACvE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,EAAE,CA6BhE"}