@yipe/dice 0.9.0 → 0.11.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.
- package/dist/builder/ac.d.ts.map +1 -1
- package/dist/builder/ast.d.ts +32 -2
- package/dist/builder/ast.d.ts.map +1 -1
- package/dist/builder/attack.d.ts +19 -0
- package/dist/builder/attack.d.ts.map +1 -1
- package/dist/builder/dc.d.ts.map +1 -1
- package/dist/builder/example.d.ts +4 -4
- package/dist/builder/example.d.ts.map +1 -1
- package/dist/builder/index.cjs +614 -121
- package/dist/builder/index.cjs.map +1 -1
- package/dist/builder/index.js +614 -122
- package/dist/builder/index.js.map +1 -1
- package/dist/builder/nodes.d.ts +1 -0
- package/dist/builder/nodes.d.ts.map +1 -1
- package/dist/builder/roll.d.ts +13 -1
- package/dist/builder/roll.d.ts.map +1 -1
- package/dist/builder/save.d.ts.map +1 -1
- package/dist/builder/types.d.ts +1 -0
- package/dist/builder/types.d.ts.map +1 -1
- package/dist/common/bounce.d.ts +45 -0
- package/dist/common/bounce.d.ts.map +1 -1
- package/dist/common/types.d.ts +33 -0
- package/dist/common/types.d.ts.map +1 -1
- package/dist/index.cjs +235 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +232 -16
- package/dist/index.js.map +1 -1
- package/dist/parser/dice.d.ts +14 -0
- package/dist/parser/dice.d.ts.map +1 -1
- package/dist/pmf/pmf.d.ts +22 -4
- package/dist/pmf/pmf.d.ts.map +1 -1
- package/dist/turn/plan.d.ts +29 -6
- package/dist/turn/plan.d.ts.map +1 -1
- package/dist/turn/state.d.ts +16 -8
- package/dist/turn/state.d.ts.map +1 -1
- package/dist/turn/turn.d.ts +35 -0
- package/dist/turn/turn.d.ts.map +1 -1
- package/dist/turn/types.d.ts +32 -10
- package/dist/turn/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/CHANGELOG.md +0 -456
package/dist/builder/nodes.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nodes.d.ts","sourceRoot":"","sources":["../../src/builder/nodes.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,cAAc,GACtB,OAAO,GACP,YAAY,GACZ,OAAO,GACP,OAAO,GACP,QAAQ,GACR,WAAW,GACX,QAAQ,GACR,SAAS,GACT,SAAS,CAAC;AAEd,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,EAAE,KAAK,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAGF,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,EAAE,KAAK,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"nodes.d.ts","sourceRoot":"","sources":["../../src/builder/nodes.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,cAAc,GACtB,OAAO,GACP,YAAY,GACZ,OAAO,GACP,OAAO,GACP,QAAQ,GACR,WAAW,GACX,QAAQ,GACR,SAAS,GACT,SAAS,CAAC;AAEd,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,EAAE,KAAK,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAGF,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,EAAE,KAAK,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,cAAc,CAAC;IAGtB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,EAAE,KAAK,CAAC;IACZ,QAAQ,EAAE;QAAE,IAAI,EAAE,cAAc,CAAC;QAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAA;KAAE,EAAE,CAAC;CACpD,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,OAAO,GAAG,QAAQ,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,EAAE,WAAW,GAAG,cAAc,GAAG,gBAAgB,CAAC;IAC1D,KAAK,EAAE,cAAc,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,cAAc,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,cAAc,CAAC;CACvB,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,OAAO,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,GAAG,OAAO,GAAG,MAAM,CAAC;IACrC,KAAK,EAAE,cAAc,CAAC;CACvB,CAAC"}
|
package/dist/builder/roll.d.ts
CHANGED
|
@@ -37,7 +37,15 @@ export declare class RollBuilder {
|
|
|
37
37
|
reroll(value: number): RollBuilder;
|
|
38
38
|
/** Set finite explode count for max-face explosions (Infinity allowed). */
|
|
39
39
|
explode(count?: number | undefined): RollBuilder;
|
|
40
|
-
/**
|
|
40
|
+
/**
|
|
41
|
+
* Set a pool-wide exploding-dice budget: at most `budget` extra dice may be added across the
|
|
42
|
+
* WHOLE pool (shared), as opposed to {@link explode}'s per-die cap (`n` dice each individually
|
|
43
|
+
* allowed up to `explode(k)` extra dice). `budget` must be a finite non-negative integer —
|
|
44
|
+
* unlike `explode()`, `Infinity` is not accepted (it would make the pool-wide DP non-terminating).
|
|
45
|
+
*/
|
|
46
|
+
explodePool(budget: number): RollBuilder;
|
|
47
|
+
/** Apply per-die minimum value (floors each die roll at `val`, e.g. `minimum(3)` treats a 1 or
|
|
48
|
+
* 2 as a 3 -- the 2024 Great Weapon Fighting style). */
|
|
41
49
|
minimum(val: number | undefined): RollBuilder;
|
|
42
50
|
bestOf(count: number | undefined): RollBuilder;
|
|
43
51
|
keepHighest(total: number, count: number): RollBuilder;
|
|
@@ -97,6 +105,7 @@ export declare class HalfRollBuilder extends RollBuilder {
|
|
|
97
105
|
toExpression(): string;
|
|
98
106
|
toAST(): ExpressionNode;
|
|
99
107
|
toPMF(eps?: number): PMF;
|
|
108
|
+
scaleDice(scale: number): RollBuilder;
|
|
100
109
|
copy(): HalfRollBuilder;
|
|
101
110
|
}
|
|
102
111
|
/**
|
|
@@ -117,6 +126,7 @@ export declare class ScaleRollBuilder extends RollBuilder {
|
|
|
117
126
|
toExpression(): string;
|
|
118
127
|
toAST(): ExpressionNode;
|
|
119
128
|
toPMF(eps?: number): PMF;
|
|
129
|
+
scaleDice(scale: number): RollBuilder;
|
|
120
130
|
copy(): ScaleRollBuilder;
|
|
121
131
|
}
|
|
122
132
|
export declare class MaxOfRollBuilder extends RollBuilder {
|
|
@@ -132,6 +142,7 @@ export declare class MaxOfRollBuilder extends RollBuilder {
|
|
|
132
142
|
toExpression(): string;
|
|
133
143
|
toAST(): ExpressionNode;
|
|
134
144
|
toPMF(eps?: number): PMF;
|
|
145
|
+
scaleDice(scale: number): RollBuilder;
|
|
135
146
|
copy(): MaxOfRollBuilder;
|
|
136
147
|
}
|
|
137
148
|
export declare class AlwaysHitBuilder extends RollBuilder {
|
|
@@ -199,6 +210,7 @@ export declare class PooledRollBuilder extends RollBuilder {
|
|
|
199
210
|
d(_sides: number | undefined): RollBuilder;
|
|
200
211
|
reroll(_value: number): RollBuilder;
|
|
201
212
|
explode(_count?: number | undefined): RollBuilder;
|
|
213
|
+
explodePool(_budget: number): RollBuilder;
|
|
202
214
|
minimum(_val: number | undefined): RollBuilder;
|
|
203
215
|
bestOf(_count: number | undefined): RollBuilder;
|
|
204
216
|
keepHighest(_total: number, _count: number): RollBuilder;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"roll.d.ts","sourceRoot":"","sources":["../../src/builder/roll.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AACtC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AAGtC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"roll.d.ts","sourceRoot":"","sources":["../../src/builder/roll.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"save.d.ts","sourceRoot":"","sources":["../../src/builder/save.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AACjC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"save.d.ts","sourceRoot":"","sources":["../../src/builder/save.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AACjC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AACtC,OAAO,EAAqB,KAAK,WAAW,EAAE,MAAM,QAAQ,CAAC;AAC7D,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE5D,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,MAAM,CAAC;AAU5C,8FAA8F;AAC9F,wBAAgB,cAAc,IAAI,IAAI,CAErC;AAED,qBAAa,WAAY,YAAW,YAAY;IAE5C,QAAQ,CAAC,KAAK,EAAE,SAAS;IACzB,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC;IAC/B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAH9B,YACW,KAAK,EAAE,SAAS,EACR,aAAa,CAAC,EAAE,WAAW,YAAA,EAC3B,WAAW,GAAE,WAAsB,EAClD;IAEJ,QAAQ,IAAI,WAAW,CAEtB;IAED,YAAY,IAAI,MAAM,CAOrB;IAED,OAAO,CAAC,GAAG,GAAE,MAAY,GAAG,cAAc,CA8BzC;IAED;;;;;OAKG;IACH,OAAO,CAAC,QAAQ;IAehB,KAAK,CAAC,GAAG,GAAE,MAAU,GAAG,GAAG,CAQ1B;IAED,IAAI,GAAG,QAEN;IAGD,OAAO,CAAC,GAAG,GAAE,MAAU,GAAG,SAAS,CAElC;CACF"}
|
package/dist/builder/types.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/builder/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAE1C,YAAY,EAAE,QAAQ,EAAE,CAAC;AAEzB,MAAM,MAAM,WAAW,GAAG;IACxB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;IAChE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;IAClE,CAAC,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,WAAW,CAAC;IACvC,IAAI,IAAI,WAAW,CAAC;IACpB,EAAE,IAAI,WAAW,CAAC;IAClB,EAAE,IAAI,WAAW,CAAC;IAClB,EAAE,IAAI,WAAW,CAAC;IAClB,GAAG,IAAI,WAAW,CAAC;IACnB,GAAG,IAAI,WAAW,CAAC;IACnB,GAAG,IAAI,WAAW,CAAC;IACnB,IAAI,IAAI,WAAW,CAAC;IACpB,IAAI,CAAC,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;AAG5C,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/builder/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAE1C,YAAY,EAAE,QAAQ,EAAE,CAAC;AAEzB,MAAM,MAAM,WAAW,GAAG;IACxB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;IAChE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;IAClE,CAAC,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,WAAW,CAAC;IACvC,IAAI,IAAI,WAAW,CAAC;IACpB,EAAE,IAAI,WAAW,CAAC;IAClB,EAAE,IAAI,WAAW,CAAC;IAClB,EAAE,IAAI,WAAW,CAAC;IAClB,GAAG,IAAI,WAAW,CAAC;IACnB,GAAG,IAAI,WAAW,CAAC;IACnB,GAAG,IAAI,WAAW,CAAC;IACnB,IAAI,IAAI,WAAW,CAAC;IACpB,IAAI,CAAC,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;AAG5C,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAIhB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,QAAQ,CAAA;KAAE,GAAG,SAAS,CAAC;IACnE,QAAQ,EAAE,QAAQ,CAAC;IACnB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,GAAG,EAAE,GAAG,CAAC;IACT,KAAK,EAAE,GAAG,CAAC;IACX,OAAO,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;CACpC,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,UAAU,GAAG;IAC1C,GAAG,EAAE,GAAG,CAAC;IACT,IAAI,EAAE,GAAG,CAAC;IACV,IAAI,EAAE,GAAG,CAAC;IACV,OAAO,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CACtD,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG;IACxC,QAAQ,EAAE,GAAG,CAAC;IACd,WAAW,EAAE,GAAG,CAAC;IACjB,OAAO,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CAC5C,CAAC;AAEF,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,UAAU,CAAC;IAClC,YAAY,IAAI,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC;CACnB"}
|
package/dist/common/bounce.d.ts
CHANGED
|
@@ -20,6 +20,16 @@ export interface BounceOddsOptions {
|
|
|
20
20
|
/** Number of dice that may be rerolled once — e.g. CHA modifier for Empowered Spell. */
|
|
21
21
|
rerollDamageDice?: number;
|
|
22
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* Exact per-face probability marginal for a single die, honoring threshold `reroll(k)` and
|
|
25
|
+
* `minimum(v)` — the SAME two transforms `resolveSingleDie` (`builder/ast.ts`) applies, in the
|
|
26
|
+
* same order (reroll, then minimum-floor), so a caller building `weights` for
|
|
27
|
+
* `jointSumAndMatch`/`explodingPoolMatchProbability` gets face weights consistent with the pool's
|
|
28
|
+
* actual resolved PMF. Returns a 1-indexed array (`weights[v - 1] = P(shows v)`, `1 <= v <= faces`);
|
|
29
|
+
* a face collapsed onto by `minimum` carries its collapsed neighbors' mass, and a face below
|
|
30
|
+
* `minimum` carries zero.
|
|
31
|
+
*/
|
|
32
|
+
export declare function faceWeights(faces: number, minimum?: number, reroll?: number): number[];
|
|
23
33
|
/**
|
|
24
34
|
* P(at least two of `diceCount` dice with `dieFaces` faces match), honoring
|
|
25
35
|
* Elemental Adept and Empowered Spell. Returns a probability in [0, 1].
|
|
@@ -29,4 +39,39 @@ export interface BounceOddsOptions {
|
|
|
29
39
|
* @param options Optional metamagic / feat modifiers.
|
|
30
40
|
*/
|
|
31
41
|
export declare function calculateBounceOdds(diceCount: number, dieFaces: number, options?: BounceOddsOptions): number;
|
|
42
|
+
/**
|
|
43
|
+
* Exact joint P(sum ∧ match), K = 2 hardcoded (per design: every shipped 5e bounce mechanic is
|
|
44
|
+
* "two or more" — see `CHROMATIC_ORB.md`). `K > 2` (a face with multiplicity ≥ K) is a harder
|
|
45
|
+
* combinatorial problem with no consumer; a `match` parameter whose only legal value is 2 would
|
|
46
|
+
* advertise a generality this DP does not have, so it is not offered.
|
|
47
|
+
*
|
|
48
|
+
* `weights` is the resolved single-die marginal's per-face probabilities, 1-indexed
|
|
49
|
+
* (`weights[v - 1] = P(one die shows v)`) — NOT assumed uniform, so `minimum`/threshold `reroll`
|
|
50
|
+
* (which collapse or reweight faces) compose correctly. Dice are i.i.d. and homogeneous (same
|
|
51
|
+
* `weights` for all of them): a mixed-face-size pool (e.g. 2d6 + 1d4) is a genuinely different,
|
|
52
|
+
* harder problem (dice are no longer exchangeable) with no consumer here.
|
|
53
|
+
*/
|
|
54
|
+
/** Exact P(sum = s) for `dice` i.i.d. dice sharing `weights`, as a sum -> mass map. */
|
|
55
|
+
export declare function diceSumDistribution(dice: number, weights: readonly number[]): Map<number, number>;
|
|
56
|
+
/**
|
|
57
|
+
* Exact joint P(sum = s ∧ match) for `dice` i.i.d. dice sharing `weights`
|
|
58
|
+
* (`P(sum ∧ match) = P(sum) − P(sum ∧ all distinct)`). Returns a sum -> mass map; sums with zero
|
|
59
|
+
* match mass are omitted. `dice <= 1` returns an empty map (no match possible).
|
|
60
|
+
*/
|
|
61
|
+
export declare function jointSumAndMatch(dice: number, weights: readonly number[]): Map<number, number>;
|
|
62
|
+
/**
|
|
63
|
+
* P(match) for a pool sharing ONE pool-wide exploding-dice budget (see
|
|
64
|
+
* `RollBuilder.explodePool()`). The plain `jointSumAndMatch`/`calculateBounceOdds` formulas assume
|
|
65
|
+
* `dice` i.i.d. dice — false for an exploded pool, since conditioning on a realized size already
|
|
66
|
+
* reveals some die rolled max. Exploiting that max is the only exploding face: condition on `m`
|
|
67
|
+
* (dice showing max) and `k` (dice showing anything else) —
|
|
68
|
+
*
|
|
69
|
+
* `m ≥ 2` → match is certain (two dice already share the max face).
|
|
70
|
+
* `m ≤ 1` → match iff the `k` non-max dice collide among themselves, uniform over `faces - 1`
|
|
71
|
+
* non-max faces (they cannot collide with the max face, so the two parts separate).
|
|
72
|
+
*
|
|
73
|
+
* `pMax` and `faces` describe the single (non-exploding-budget) die's resolved marginal —
|
|
74
|
+
* `pMax = weights[faces - 1]`.
|
|
75
|
+
*/
|
|
76
|
+
export declare function explodingPoolMatchProbability(pMax: number, faces: number, count: number, budget: number): number;
|
|
32
77
|
//# sourceMappingURL=bounce.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bounce.d.ts","sourceRoot":"","sources":["../../src/common/bounce.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,6DAA6D;AAC7D,MAAM,WAAW,iBAAiB;IAChC,uFAAuF;IACvF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,wFAAwF;IACxF,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAuDD;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,MAAM,CAgCR"}
|
|
1
|
+
{"version":3,"file":"bounce.d.ts","sourceRoot":"","sources":["../../src/common/bounce.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,6DAA6D;AAC7D,MAAM,WAAW,iBAAiB;IAChC,uFAAuF;IACvF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,wFAAwF;IACxF,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,SAAI,EAAE,MAAM,SAAI,GAAG,MAAM,EAAE,CAwB5E;AAuDD;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,MAAM,CAgCR;AAED;;;;;;;;;;;GAWG;AAEH,uFAAuF;AACvF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAejG;AA0CD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAY9F;AAoED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,6BAA6B,CAC3C,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,MAAM,CAoBR"}
|
package/dist/common/types.d.ts
CHANGED
|
@@ -11,6 +11,39 @@ export interface Bin {
|
|
|
11
11
|
/** Optional per-outcome damage attribution at this damage. */
|
|
12
12
|
attr?: OutcomeLabelMap;
|
|
13
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* One homogeneous die-type's resolved shape within a damage pool — count of dice, faces per die,
|
|
16
|
+
* and the per-die `minimum`/threshold-`reroll` that shape its resolved marginal (see
|
|
17
|
+
* `RollBuilder.getSubRollConfigs()`). The raw material for `dice-match` trigger slicing.
|
|
18
|
+
*/
|
|
19
|
+
export interface DicePoolDescriptor {
|
|
20
|
+
readonly count: number;
|
|
21
|
+
readonly faces: number;
|
|
22
|
+
readonly minimum: number;
|
|
23
|
+
readonly reroll: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Exact P(match | this branch's own final damage value = d) for a resolved hit/crit branch,
|
|
27
|
+
* keyed by the SAME damage values the branch's PMF uses (post flat `modifier`, post crit
|
|
28
|
+
* doubling) — so a consumer splits a PMF bin-by-bin with no sum/modifier bookkeeping of its own.
|
|
29
|
+
*/
|
|
30
|
+
export interface DiceMatchInfo {
|
|
31
|
+
readonly matchProbabilityByDamage: ReadonlyMap<number, number>;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Optional capability of a `dice-match`-eligible damage source (implemented by `AttackBuilder`):
|
|
35
|
+
* exposes the exact per-branch match-probability breakdown needed to slice its hit/crit PMF into
|
|
36
|
+
* matched / did-not-match halves. Absence (a bare `PMF`, a plain non-attack `RollBuilder`, or a
|
|
37
|
+
* `null` branch — `noCrit()`, a parsed/pooled/`keep` source) is a defined "no match slice
|
|
38
|
+
* available" state, not a crash: naming such a source in a `dice-match` trigger is a
|
|
39
|
+
* `TurnSpecError`, not a silent zero.
|
|
40
|
+
*/
|
|
41
|
+
export interface HasDiceMatchInfo {
|
|
42
|
+
diceMatchInfo(eps?: number): {
|
|
43
|
+
hit: DiceMatchInfo | null;
|
|
44
|
+
crit: DiceMatchInfo | null;
|
|
45
|
+
};
|
|
46
|
+
}
|
|
14
47
|
export interface CritConfig {
|
|
15
48
|
critThreshold: number;
|
|
16
49
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/common/types.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,MAAM,MAAM,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAE9D,kEAAkE;AAClE,eAAO,MAAM,GAAG,QAAQ,CAAC;AAEzB,qDAAqD;AACrD,MAAM,WAAW,GAAG;IAClB,mDAAmD;IACnD,CAAC,EAAE,MAAM,CAAC;IACV,iEAAiE;IACjE,KAAK,EAAE,eAAe,CAAC;IACvB,8DAA8D;IAC9D,IAAI,CAAC,EAAE,eAAe,CAAC;CACxB;AAED,MAAM,WAAW,UAAU;IACvB,aAAa,EAAE,MAAM,CAAC;CACzB;AAED,uDAAuD;AACvD,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACxD,+DAA+D;AAC/D,MAAM,MAAM,WAAW,GACnB,MAAM,GACN,KAAK,GACL,UAAU,GACV,YAAY,GACZ,UAAU,GACV,UAAU,GACV,IAAI,CAAC;AAET,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,CAAC;AAE3D,4FAA4F;AAC5F,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,WAAW,GAAG,cAAc,GAAG,gBAAgB,CAAC;AAEhF;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,GAAE,QAAiB,GAAG,MAAM,CAatF;AAED;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,EAAE,WAAwB,CAAC;AAEzD;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,EAAE,WAAW,EAQ1C,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,qBAAqB,EAAE,WAAW,EAQ9C,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,MAAM,EAC3C,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,EACrB,KAAK,GAAE,SAAS,MAAM,EAAsB,GAC3C,CAAC,EAAE,CAUL;AAED,eAAO,MAAM,QAAQ,EAAE,WAAW,EAAoB,CAAC;AACvD,eAAO,MAAM,UAAU,EAAE,WAAW,EAAa,CAAC;AAClD,eAAO,MAAM,SAAS,EAAE,WAAW,EAAY,CAAC;AAChD,eAAO,MAAM,UAAU,EAAE,WAAW,EAA+B,CAAC;AACpE,eAAO,MAAM,gBAAgB,EAAE,WAAW,EAAmB,CAAC;AAC9D,eAAO,MAAM,cAAc,EAAE,WAAW,EAAiB,CAAC;AAC1D,eAAO,MAAM,cAAc,EAAE,WAAW,EAAiB,CAAC;AAC1D,eAAO,MAAM,mBAAmB,EAAE,WAAW,EAAW,CAAC"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/common/types.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,MAAM,MAAM,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAE9D,kEAAkE;AAClE,eAAO,MAAM,GAAG,QAAQ,CAAC;AAEzB,qDAAqD;AACrD,MAAM,WAAW,GAAG;IAClB,mDAAmD;IACnD,CAAC,EAAE,MAAM,CAAC;IACV,iEAAiE;IACjE,KAAK,EAAE,eAAe,CAAC;IACvB,8DAA8D;IAC9D,IAAI,CAAC,EAAE,eAAe,CAAC;CACxB;AAED;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,wBAAwB,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChE;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAgB;IAC/B,aAAa,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG;QAAE,GAAG,EAAE,aAAa,GAAG,IAAI,CAAC;QAAC,IAAI,EAAE,aAAa,GAAG,IAAI,CAAA;KAAE,CAAC;CACxF;AAED,MAAM,WAAW,UAAU;IACvB,aAAa,EAAE,MAAM,CAAC;CACzB;AAED,uDAAuD;AACvD,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACxD,+DAA+D;AAC/D,MAAM,MAAM,WAAW,GACnB,MAAM,GACN,KAAK,GACL,UAAU,GACV,YAAY,GACZ,UAAU,GACV,UAAU,GACV,IAAI,CAAC;AAET,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,CAAC;AAE3D,4FAA4F;AAC5F,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,WAAW,GAAG,cAAc,GAAG,gBAAgB,CAAC;AAEhF;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,GAAE,QAAiB,GAAG,MAAM,CAatF;AAED;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,EAAE,WAAwB,CAAC;AAEzD;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,EAAE,WAAW,EAQ1C,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,qBAAqB,EAAE,WAAW,EAQ9C,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,MAAM,EAC3C,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,EACrB,KAAK,GAAE,SAAS,MAAM,EAAsB,GAC3C,CAAC,EAAE,CAUL;AAED,eAAO,MAAM,QAAQ,EAAE,WAAW,EAAoB,CAAC;AACvD,eAAO,MAAM,UAAU,EAAE,WAAW,EAAa,CAAC;AAClD,eAAO,MAAM,SAAS,EAAE,WAAW,EAAY,CAAC;AAChD,eAAO,MAAM,UAAU,EAAE,WAAW,EAA+B,CAAC;AACpE,eAAO,MAAM,gBAAgB,EAAE,WAAW,EAAmB,CAAC;AAC9D,eAAO,MAAM,cAAc,EAAE,WAAW,EAAiB,CAAC;AAC1D,eAAO,MAAM,cAAc,EAAE,WAAW,EAAiB,CAAC;AAC1D,eAAO,MAAM,mBAAmB,EAAE,WAAW,EAAW,CAAC"}
|
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,27 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
// src/common/bounce.ts
|
|
4
|
+
function faceWeights(faces, minimum = 0, reroll = 0) {
|
|
5
|
+
const f = Math.max(0, Math.floor(faces));
|
|
6
|
+
if (f <= 0) return [];
|
|
7
|
+
let weights = new Array(f).fill(1 / f);
|
|
8
|
+
const r = Math.max(0, Math.min(Math.floor(reroll), f));
|
|
9
|
+
if (r > 0) {
|
|
10
|
+
const rerollMass = r / f;
|
|
11
|
+
const uniformReroll = rerollMass / f;
|
|
12
|
+
weights = weights.map((_, i) => (i < r ? 0 : 1 / f) + uniformReroll);
|
|
13
|
+
}
|
|
14
|
+
const minV = Math.max(0, Math.floor(minimum));
|
|
15
|
+
if (minV > 1) {
|
|
16
|
+
const collapsed = new Array(f).fill(0);
|
|
17
|
+
for (let v = 1; v <= f; v++) {
|
|
18
|
+
const target = Math.min(f, Math.max(v, minV));
|
|
19
|
+
collapsed[target - 1] += weights[v - 1];
|
|
20
|
+
}
|
|
21
|
+
weights = collapsed;
|
|
22
|
+
}
|
|
23
|
+
return weights;
|
|
24
|
+
}
|
|
4
25
|
function binom(n, k) {
|
|
5
26
|
if (k < 0 || k > n) return 0;
|
|
6
27
|
let result = 1;
|
|
@@ -49,6 +70,128 @@ function calculateBounceOdds(diceCount, dieFaces, options) {
|
|
|
49
70
|
);
|
|
50
71
|
return Math.min(1, pMatchFirst + pNoMatchFirst * pMatchAfterReroll);
|
|
51
72
|
}
|
|
73
|
+
function diceSumDistribution(dice, weights) {
|
|
74
|
+
let dist = /* @__PURE__ */ new Map([[0, 1]]);
|
|
75
|
+
for (let die = 0; die < dice; die++) {
|
|
76
|
+
const next = /* @__PURE__ */ new Map();
|
|
77
|
+
for (const [sum, mass] of dist) {
|
|
78
|
+
for (let face = 1; face <= weights.length; face++) {
|
|
79
|
+
const w = weights[face - 1] ?? 0;
|
|
80
|
+
if (w <= 0) continue;
|
|
81
|
+
const s = sum + face;
|
|
82
|
+
next.set(s, (next.get(s) ?? 0) + mass * w);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
dist = next;
|
|
86
|
+
}
|
|
87
|
+
return dist;
|
|
88
|
+
}
|
|
89
|
+
function sumAllDistinctDistribution(dice, weights) {
|
|
90
|
+
const faceCount = weights.length;
|
|
91
|
+
let dp = /* @__PURE__ */ new Map([[0, /* @__PURE__ */ new Map([[0, 1]])]]);
|
|
92
|
+
for (let face = 1; face <= faceCount; face++) {
|
|
93
|
+
const w = weights[face - 1] ?? 0;
|
|
94
|
+
const next = /* @__PURE__ */ new Map();
|
|
95
|
+
for (const [count, sumMap] of dp) next.set(count, new Map(sumMap));
|
|
96
|
+
if (w > 0) {
|
|
97
|
+
for (const [count, sumMap] of dp) {
|
|
98
|
+
const nextCount = count + 1;
|
|
99
|
+
if (nextCount > dice) continue;
|
|
100
|
+
const target = next.get(nextCount) ?? /* @__PURE__ */ new Map();
|
|
101
|
+
for (const [sum, mass] of sumMap) {
|
|
102
|
+
const s = sum + face;
|
|
103
|
+
target.set(s, (target.get(s) ?? 0) + mass * w);
|
|
104
|
+
}
|
|
105
|
+
next.set(nextCount, target);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
dp = next;
|
|
109
|
+
}
|
|
110
|
+
let factorial = 1;
|
|
111
|
+
for (let i = 2; i <= dice; i++) factorial *= i;
|
|
112
|
+
const chosen = dp.get(dice) ?? /* @__PURE__ */ new Map();
|
|
113
|
+
const result = /* @__PURE__ */ new Map();
|
|
114
|
+
for (const [sum, mass] of chosen) result.set(sum, mass * factorial);
|
|
115
|
+
return result;
|
|
116
|
+
}
|
|
117
|
+
function jointSumAndMatch(dice, weights) {
|
|
118
|
+
if (dice <= 1) return /* @__PURE__ */ new Map();
|
|
119
|
+
const total = diceSumDistribution(dice, weights);
|
|
120
|
+
const distinct = sumAllDistinctDistribution(dice, weights);
|
|
121
|
+
const result = /* @__PURE__ */ new Map();
|
|
122
|
+
for (const [sum, mass] of total) {
|
|
123
|
+
const matchMass = Math.max(0, mass - (distinct.get(sum) ?? 0));
|
|
124
|
+
if (matchMass > 0) result.set(sum, matchMass);
|
|
125
|
+
}
|
|
126
|
+
return result;
|
|
127
|
+
}
|
|
128
|
+
function explodingPoolMkDistribution(pMax, count, budget) {
|
|
129
|
+
const binomial = (n, p) => {
|
|
130
|
+
const result = new Array(n + 1).fill(0);
|
|
131
|
+
result[0] = 1;
|
|
132
|
+
for (let trial = 0; trial < n; trial++) {
|
|
133
|
+
const next = new Array(n + 1).fill(0);
|
|
134
|
+
for (let successes = 0; successes <= trial; successes++) {
|
|
135
|
+
const mass = result[successes];
|
|
136
|
+
if (mass <= 0) continue;
|
|
137
|
+
next[successes] += mass * (1 - p);
|
|
138
|
+
next[successes + 1] += mass * p;
|
|
139
|
+
}
|
|
140
|
+
for (let i = 0; i <= n; i++) result[i] = next[i];
|
|
141
|
+
}
|
|
142
|
+
return result;
|
|
143
|
+
};
|
|
144
|
+
const memo = /* @__PURE__ */ new Map();
|
|
145
|
+
const f = (pending, remainingBudget) => {
|
|
146
|
+
if (pending === 0) return /* @__PURE__ */ new Map([["0,0", 1]]);
|
|
147
|
+
if (remainingBudget === 0) {
|
|
148
|
+
const binom2 = binomial(pending, pMax);
|
|
149
|
+
const result2 = /* @__PURE__ */ new Map();
|
|
150
|
+
for (let m = 0; m <= pending; m++) {
|
|
151
|
+
const mass = binom2[m];
|
|
152
|
+
if (mass > 0) result2.set(`${m},${pending - m}`, mass);
|
|
153
|
+
}
|
|
154
|
+
return result2;
|
|
155
|
+
}
|
|
156
|
+
const key = `${pending},${remainingBudget}`;
|
|
157
|
+
const cached = memo.get(key);
|
|
158
|
+
if (cached) return cached;
|
|
159
|
+
const result = /* @__PURE__ */ new Map();
|
|
160
|
+
const accumulate = (mk, mass) => {
|
|
161
|
+
result.set(mk, (result.get(mk) ?? 0) + mass);
|
|
162
|
+
};
|
|
163
|
+
for (const [mk, mass] of f(pending, remainingBudget - 1)) {
|
|
164
|
+
const [m, k] = mk.split(",").map(Number);
|
|
165
|
+
accumulate(`${m + 1},${k}`, mass * pMax);
|
|
166
|
+
}
|
|
167
|
+
for (const [mk, mass] of f(pending - 1, remainingBudget)) {
|
|
168
|
+
const [m, k] = mk.split(",").map(Number);
|
|
169
|
+
accumulate(`${m},${k + 1}`, mass * (1 - pMax));
|
|
170
|
+
}
|
|
171
|
+
memo.set(key, result);
|
|
172
|
+
return result;
|
|
173
|
+
};
|
|
174
|
+
return f(count, budget);
|
|
175
|
+
}
|
|
176
|
+
function explodingPoolMatchProbability(pMax, faces, count, budget) {
|
|
177
|
+
if (count <= 1) return 0;
|
|
178
|
+
const mkDistribution = explodingPoolMkDistribution(pMax, count, budget);
|
|
179
|
+
const nonMaxFaces = Math.max(1, faces - 1);
|
|
180
|
+
let pMatchTotal = 0;
|
|
181
|
+
for (const [mk, weight] of mkDistribution) {
|
|
182
|
+
const [m, k] = mk.split(",").map(Number);
|
|
183
|
+
if (m >= 2) {
|
|
184
|
+
pMatchTotal += weight;
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
let pAllDistinctAmongNonMax = 1;
|
|
188
|
+
for (let i = 0; i < k; i++) {
|
|
189
|
+
pAllDistinctAmongNonMax *= (nonMaxFaces - i) / nonMaxFaces;
|
|
190
|
+
}
|
|
191
|
+
pMatchTotal += weight * (1 - Math.max(0, pAllDistinctAmongNonMax));
|
|
192
|
+
}
|
|
193
|
+
return Math.min(1, Math.max(0, pMatchTotal));
|
|
194
|
+
}
|
|
52
195
|
|
|
53
196
|
// src/common/errors.ts
|
|
54
197
|
var DiceParseError = class _DiceParseError extends Error {
|
|
@@ -1568,7 +1711,7 @@ var _PMF = class _PMF {
|
|
|
1568
1711
|
const id = this.identifier;
|
|
1569
1712
|
let key = `${id}`;
|
|
1570
1713
|
for (let i = 1; i < n; i++) key += `+${id}`;
|
|
1571
|
-
return `${key}@${eps}`;
|
|
1714
|
+
return `${key}@${eps}|${this.fingerprint()}`;
|
|
1572
1715
|
}
|
|
1573
1716
|
/**
|
|
1574
1717
|
* Efficiently computes this PMF convolved with itself `n` times.
|
|
@@ -1880,6 +2023,30 @@ var _PMF = class _PMF {
|
|
|
1880
2023
|
`freq(${this.identifier},${freq})`
|
|
1881
2024
|
);
|
|
1882
2025
|
}
|
|
2026
|
+
/**
|
|
2027
|
+
* Splits this PMF into two complementary PMFs by an arbitrary per-damage-value factor in
|
|
2028
|
+
* `[0, 1]` — bin `d`'s mass, `count`, and `attr` split `factor(d)` / `1 - factor(d)` between the
|
|
2029
|
+
* two results (via the same proportional scaling {@link applyHitFrequency} uses, `scaleBin`), so
|
|
2030
|
+
* `a.add(b)` recovers this PMF exactly and both halves stay chart-attributable. Unlike
|
|
2031
|
+
* {@link applyHitFrequency}, mass is NOT redistributed to a miss bin at 0 — each bin stays at its
|
|
2032
|
+
* own damage value in whichever half it lands in. `factor` outside `[0, 1]` is clamped.
|
|
2033
|
+
*
|
|
2034
|
+
* Built for `dice-match` trigger slicing: splitting a hit/crit sub-PMF into "matched" and
|
|
2035
|
+
* "did not match" halves by the exact per-damage-value match probability.
|
|
2036
|
+
*/
|
|
2037
|
+
splitByFactor(factor) {
|
|
2038
|
+
const a = /* @__PURE__ */ new Map();
|
|
2039
|
+
const b = /* @__PURE__ */ new Map();
|
|
2040
|
+
for (const [damage, bin] of this.map) {
|
|
2041
|
+
const f = Math.min(1, Math.max(0, factor(damage)));
|
|
2042
|
+
if (f > 0) a.set(damage, _PMF.scaleBin(bin, f));
|
|
2043
|
+
if (f < 1) b.set(damage, _PMF.scaleBin(bin, 1 - f));
|
|
2044
|
+
}
|
|
2045
|
+
return [
|
|
2046
|
+
new _PMF(a, this.epsilon, false, `split+(${this.identifier})`),
|
|
2047
|
+
new _PMF(b, this.epsilon, false, `split-(${this.identifier})`)
|
|
2048
|
+
];
|
|
2049
|
+
}
|
|
1883
2050
|
scaleMass(factor) {
|
|
1884
2051
|
if (factor === 1) return this;
|
|
1885
2052
|
const scaledMap = /* @__PURE__ */ new Map();
|
|
@@ -1919,16 +2086,27 @@ var _PMF = class _PMF {
|
|
|
1919
2086
|
return `v4:${raw ? "RAW" : "N"}:${id1}+${id2}@${eps}|${p1.fingerprint()}|${p2.fingerprint()}`;
|
|
1920
2087
|
}
|
|
1921
2088
|
/**
|
|
1922
|
-
* A
|
|
1923
|
-
* cache keys change
|
|
1924
|
-
*
|
|
1925
|
-
*
|
|
2089
|
+
* A content fingerprint of every bin (probability, per-label `count`, per-label `attr`) plus
|
|
2090
|
+
* the `normalized` flag, so convolution/power cache keys change whenever the underlying
|
|
2091
|
+
* numbers do. Mass/bin-count/face-sum alone are not content-unique: `mapDamage` variants can
|
|
2092
|
+
* keep the same identifier, support, mass, and face sum while differing in per-bin
|
|
2093
|
+
* probabilities or in the `count`/`attr` channels `convolve()`/`power()` actually propagate --
|
|
2094
|
+
* that previously let `power()` return one PMF's cached result for a different PMF. Memoized
|
|
2095
|
+
* because a PMF is immutable once constructed -- this avoids re-deriving the key on every
|
|
2096
|
+
* convolve()/power() call (including cache hits). Bin order is sorted by damage value (and
|
|
2097
|
+
* label keys sorted within each bin) so two equal-content PMFs built via different code paths
|
|
2098
|
+
* fingerprint identically regardless of Map insertion order.
|
|
1926
2099
|
*/
|
|
1927
2100
|
fingerprint() {
|
|
1928
2101
|
if (this._fingerprint === void 0) {
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
2102
|
+
const bins = [...this.map.entries()].sort((a, b) => a[0] - b[0]);
|
|
2103
|
+
const parts = [];
|
|
2104
|
+
for (const [damageValue, bin] of bins) {
|
|
2105
|
+
const countStr = Object.keys(bin.count).sort().map((k) => `${k}:${bin.count[k]}`).join(",");
|
|
2106
|
+
const attrStr = bin.attr ? Object.keys(bin.attr).sort().map((k) => `${k}:${bin.attr[k]}`).join(",") : "";
|
|
2107
|
+
parts.push(`${damageValue}:${bin.p}[${countStr}]{${attrStr}}`);
|
|
2108
|
+
}
|
|
2109
|
+
this._fingerprint = `${this.normalized ? 1 : 0}|${parts.join(";")}`;
|
|
1932
2110
|
}
|
|
1933
2111
|
return this._fingerprint;
|
|
1934
2112
|
}
|
|
@@ -2160,11 +2338,13 @@ var _PMF = class _PMF {
|
|
|
2160
2338
|
/** Quantile / inverse CDF for p in [0,1]. Returns smallest x with CDF ≥ p. */
|
|
2161
2339
|
quantile(p) {
|
|
2162
2340
|
if (this.map.size === 0) return 0;
|
|
2341
|
+
const totalMass = this.mass();
|
|
2342
|
+
if (totalMass <= 0) return 0;
|
|
2163
2343
|
const s = this.support().sort((a, b) => a - b);
|
|
2164
2344
|
let acc = 0;
|
|
2165
2345
|
for (const x of s) {
|
|
2166
2346
|
acc += this.pAt(x);
|
|
2167
|
-
if (acc >= p) return x;
|
|
2347
|
+
if (acc / totalMass >= p) return x;
|
|
2168
2348
|
}
|
|
2169
2349
|
return s[s.length - 1];
|
|
2170
2350
|
}
|
|
@@ -3025,6 +3205,12 @@ function combineDiceWithNormalization(dice, normValue, outcomeType, currentNorm,
|
|
|
3025
3205
|
finalResult = finalResult.combine(dice);
|
|
3026
3206
|
return { newNorm: currentNorm * normValue, updatedResult: finalResult };
|
|
3027
3207
|
}
|
|
3208
|
+
function subtractCounts(a, b) {
|
|
3209
|
+
const result = new Dice();
|
|
3210
|
+
for (const [key, value] of a.getFaceEntries()) result.increment(key, value);
|
|
3211
|
+
for (const [key, value] of b.getFaceEntries()) result.increment(key, -value);
|
|
3212
|
+
return result;
|
|
3213
|
+
}
|
|
3028
3214
|
function parseExpression(arr, n) {
|
|
3029
3215
|
const result = (() => {
|
|
3030
3216
|
const res = parseArgument(arr, n);
|
|
@@ -3032,8 +3218,29 @@ function parseExpression(arr, n) {
|
|
|
3032
3218
|
})();
|
|
3033
3219
|
let op = parseOperation(arr);
|
|
3034
3220
|
let finalResult = result;
|
|
3221
|
+
let baseDieMeta = result.privateData?.checkDie && !result.privateData.checkDie.rerollOne ? result.privateData.checkDie : void 0;
|
|
3222
|
+
let bonusOnly = Dice.scalar(0);
|
|
3035
3223
|
while (op != null) {
|
|
3036
3224
|
const arg = !op.unary ? parseArgument(arr, n) : finalResult;
|
|
3225
|
+
let acAlreadyApplied = false;
|
|
3226
|
+
if (baseDieMeta) {
|
|
3227
|
+
if (op === Dice.prototype.addNonZero) {
|
|
3228
|
+
bonusOnly = bonusOnly.add(arg);
|
|
3229
|
+
} else if (op === Dice.prototype.subtract) {
|
|
3230
|
+
bonusOnly = bonusOnly.subtract(arg);
|
|
3231
|
+
} else if (op === Dice.prototype.ac && typeof arg === "number") {
|
|
3232
|
+
const natMaxSlice = bonusOnly.add(baseDieMeta.sides);
|
|
3233
|
+
const restSlice = subtractCounts(finalResult, natMaxSlice);
|
|
3234
|
+
const gatedNatMaxSlice = natMaxSlice.ac(arg);
|
|
3235
|
+
finalResult = restSlice.ac(arg).combine(gatedNatMaxSlice);
|
|
3236
|
+
finalResult.privateData.checkDie = baseDieMeta;
|
|
3237
|
+
finalResult.privateData.natMaxCritSlice = gatedNatMaxSlice;
|
|
3238
|
+
acAlreadyApplied = true;
|
|
3239
|
+
baseDieMeta = void 0;
|
|
3240
|
+
} else {
|
|
3241
|
+
baseDieMeta = void 0;
|
|
3242
|
+
}
|
|
3243
|
+
}
|
|
3037
3244
|
let crit;
|
|
3038
3245
|
let critNorm = 1;
|
|
3039
3246
|
if (arr[0] === "x" || arr[0] === "c") {
|
|
@@ -3044,11 +3251,17 @@ function parseExpression(arr, n) {
|
|
|
3044
3251
|
assertToken(arr, "i");
|
|
3045
3252
|
assertToken(arr, "t");
|
|
3046
3253
|
const count = isXcrit ? parseNumber(arr, n) : 1;
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
|
|
3254
|
+
const trackedCritSlice = finalResult.privateData?.natMaxCritSlice;
|
|
3255
|
+
if (count === 1 && trackedCritSlice) {
|
|
3256
|
+
crit = trackedCritSlice;
|
|
3257
|
+
finalResult = subtractCounts(finalResult, trackedCritSlice);
|
|
3258
|
+
} else {
|
|
3259
|
+
crit = new Dice();
|
|
3260
|
+
for (let i = 0; i < count; i++) {
|
|
3261
|
+
const max = finalResult.maxFace();
|
|
3262
|
+
crit.setFace(max, finalResult.get(max));
|
|
3263
|
+
finalResult = finalResult.deleteFace(max);
|
|
3264
|
+
}
|
|
3052
3265
|
}
|
|
3053
3266
|
critNorm = crit.total();
|
|
3054
3267
|
crit = op.call(crit, parseBinaryArgument(arg, arr, n));
|
|
@@ -3099,7 +3312,9 @@ function parseExpression(arr, n) {
|
|
|
3099
3312
|
missNorm = miss && missNorm ? miss.total() / missNorm : 1;
|
|
3100
3313
|
}
|
|
3101
3314
|
let norm = finalResult.total();
|
|
3102
|
-
|
|
3315
|
+
if (!acAlreadyApplied) {
|
|
3316
|
+
finalResult = op.call(finalResult, arg);
|
|
3317
|
+
}
|
|
3103
3318
|
norm = norm ? finalResult.total() / norm : 1;
|
|
3104
3319
|
if (crit) {
|
|
3105
3320
|
const result2 = combineDiceWithNormalization(
|
|
@@ -3290,6 +3505,7 @@ function parseDice(s, n) {
|
|
|
3290
3505
|
if (rerollOne) {
|
|
3291
3506
|
result = result.reroll(1);
|
|
3292
3507
|
}
|
|
3508
|
+
result.privateData.checkDie = { sides, rerollOne };
|
|
3293
3509
|
return result;
|
|
3294
3510
|
}
|
|
3295
3511
|
function peek(arr, expected) {
|
|
@@ -3589,7 +3805,11 @@ exports.PMF = PMF;
|
|
|
3589
3805
|
exports.calculateBounceOdds = calculateBounceOdds;
|
|
3590
3806
|
exports.clearParserCache = clearParserCache;
|
|
3591
3807
|
exports.critProbability = critProbability;
|
|
3808
|
+
exports.diceSumDistribution = diceSumDistribution;
|
|
3809
|
+
exports.explodingPoolMatchProbability = explodingPoolMatchProbability;
|
|
3810
|
+
exports.faceWeights = faceWeights;
|
|
3592
3811
|
exports.getCachingEnabled = getCachingEnabled;
|
|
3812
|
+
exports.jointSumAndMatch = jointSumAndMatch;
|
|
3593
3813
|
exports.onAnyHit = onAnyHit;
|
|
3594
3814
|
exports.onCritOnly = onCritOnly;
|
|
3595
3815
|
exports.onHitOnly = onHitOnly;
|