@yipe/dice 0.4.0 → 0.6.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 +25 -0
- package/dist/builder/ac.d.ts.map +1 -0
- package/dist/builder/ast.d.ts +9 -0
- package/dist/builder/ast.d.ts.map +1 -0
- package/dist/builder/attack.d.ts +41 -0
- package/dist/builder/attack.d.ts.map +1 -0
- package/dist/builder/d20.d.ts +6 -0
- package/dist/builder/d20.d.ts.map +1 -0
- package/dist/builder/dc.d.ts +26 -0
- package/dist/builder/dc.d.ts.map +1 -0
- package/dist/builder/example.d.ts +356 -0
- package/dist/builder/example.d.ts.map +1 -0
- package/dist/builder/factory.d.ts +17 -0
- package/dist/builder/factory.d.ts.map +1 -0
- package/dist/builder/index.cjs +106 -0
- package/dist/builder/index.cjs.map +1 -1
- package/dist/builder/index.d.ts +8 -379
- package/dist/builder/index.d.ts.map +1 -0
- package/dist/builder/index.js +105 -1
- package/dist/builder/index.js.map +1 -1
- package/dist/builder/nodes.d.ts +61 -0
- package/dist/builder/nodes.d.ts.map +1 -0
- package/dist/builder/prob.d.ts +3 -0
- package/dist/builder/prob.d.ts.map +1 -0
- package/dist/builder/roll.d.ts +205 -0
- package/dist/builder/roll.d.ts.map +1 -0
- package/dist/builder/save.d.ts +19 -0
- package/dist/builder/save.d.ts.map +1 -0
- package/dist/builder/types.d.ts +66 -0
- package/dist/builder/types.d.ts.map +1 -0
- package/dist/common/bounce.d.ts +32 -0
- package/dist/common/bounce.d.ts.map +1 -0
- package/dist/common/errors.d.ts +26 -0
- package/dist/common/errors.d.ts.map +1 -0
- package/dist/common/lru-cache.d.ts +17 -0
- package/dist/common/lru-cache.d.ts.map +1 -0
- package/dist/common/types.d.ts +65 -0
- package/dist/common/types.d.ts.map +1 -0
- package/dist/index.d.ts +9 -111
- package/dist/index.d.ts.map +1 -0
- package/dist/parser/dice.d.ts +70 -0
- package/dist/parser/dice.d.ts.map +1 -0
- package/dist/parser/parser.d.ts +14 -0
- package/dist/parser/parser.d.ts.map +1 -0
- package/dist/pmf/mixture.d.ts +37 -0
- package/dist/pmf/mixture.d.ts.map +1 -0
- package/dist/pmf/pmf.d.ts +380 -0
- package/dist/pmf/pmf.d.ts.map +1 -0
- package/dist/{pmf-D5VRghZI.d.ts → pmf/query.d.ts} +6 -464
- package/dist/pmf/query.d.ts.map +1 -0
- package/package.json +16 -15
- package/.claude/worktrees/amazing-matsumoto-27220c/LICENSE +0 -21
- package/.claude/worktrees/amazing-matsumoto-27220c/README.md +0 -518
- package/.claude/worktrees/vibrant-lovelace-0cc9e7/LICENSE +0 -21
- package/.claude/worktrees/vibrant-lovelace-0cc9e7/README.md +0 -518
- package/.claude/worktrees/wizardly-mclean-e375de/LICENSE +0 -21
- package/.claude/worktrees/wizardly-mclean-e375de/README.md +0 -518
- package/CHANGELOG.md +0 -224
- package/dist/builder/index.d.cts +0 -379
- package/dist/index.d.cts +0 -111
- package/dist/pmf-D5VRghZI.d.cts +0 -1129
package/dist/index.d.ts
CHANGED
|
@@ -1,111 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
|
|
10
|
-
* - **Elemental Adept** (`minimumDieRoll >= 2`): rolls below the minimum are
|
|
11
|
-
* bumped up to it, collapsing the low faces onto a single heavier value.
|
|
12
|
-
* - **Empowered Spell** (`rerollDamageDice > 0`): a number of dice may be
|
|
13
|
-
* rerolled once, giving a second chance at a match.
|
|
14
|
-
*
|
|
15
|
-
* The base and Elemental-Adept cases are computed exactly (see
|
|
16
|
-
* {@link pAllDistinct}); the Empowered-Spell reroll is an explicit model layered
|
|
17
|
-
* on the exact base match probability.
|
|
18
|
-
*/
|
|
19
|
-
/** Options that modify bounce odds via metamagic / feats. */
|
|
20
|
-
interface BounceOddsOptions {
|
|
21
|
-
/** Minimum die roll — e.g. 2 for Elemental Adept, 3 for Great Weapon Fighting 2024. */
|
|
22
|
-
minimumDieRoll?: number;
|
|
23
|
-
/** Number of dice that may be rerolled once — e.g. CHA modifier for Empowered Spell. */
|
|
24
|
-
rerollDamageDice?: number;
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* P(at least two of `diceCount` dice with `dieFaces` faces match), honoring
|
|
28
|
-
* Elemental Adept and Empowered Spell. Returns a probability in [0, 1].
|
|
29
|
-
*
|
|
30
|
-
* @param diceCount Number of dice rolled.
|
|
31
|
-
* @param dieFaces Faces per die (e.g. 8 for d8).
|
|
32
|
-
* @param options Optional metamagic / feat modifiers.
|
|
33
|
-
*/
|
|
34
|
-
declare function calculateBounceOdds(diceCount: number, dieFaces: number, options?: BounceOddsOptions): number;
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Error thrown when a dice expression cannot be parsed.
|
|
38
|
-
*
|
|
39
|
-
* Extends the built-in {@link Error}, so existing `catch (e)` / message checks
|
|
40
|
-
* continue to work, while callers can now narrow with `instanceof DiceParseError`.
|
|
41
|
-
*
|
|
42
|
-
* @example
|
|
43
|
-
* try {
|
|
44
|
-
* parse("d6@3");
|
|
45
|
-
* } catch (e) {
|
|
46
|
-
* if (e instanceof DiceParseError) {
|
|
47
|
-
* // e.expression === "d6@3"
|
|
48
|
-
* }
|
|
49
|
-
* }
|
|
50
|
-
*/
|
|
51
|
-
declare class DiceParseError extends Error {
|
|
52
|
-
/** The original expression that failed to parse, when available. */
|
|
53
|
-
readonly expression?: string;
|
|
54
|
-
/** The underlying error that triggered this one, when available. */
|
|
55
|
-
readonly cause?: unknown;
|
|
56
|
-
constructor(message: string, options?: {
|
|
57
|
-
expression?: string;
|
|
58
|
-
cause?: unknown;
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/** Enable or disable the internal parse cache. */
|
|
63
|
-
declare function setCachingEnabled(enabled: boolean): void;
|
|
64
|
-
/** Returns whether the internal parse cache is currently enabled. */
|
|
65
|
-
declare function getCachingEnabled(): boolean;
|
|
66
|
-
/** Clears the internal parse cache. */
|
|
67
|
-
declare function clearParserCache(): void;
|
|
68
|
-
/**
|
|
69
|
-
* Parse a dice expression into a PMF.
|
|
70
|
-
*
|
|
71
|
-
* - Expression is case-insensitive and ignores spaces.
|
|
72
|
-
*/
|
|
73
|
-
declare function parse(expression: string, n?: number): PMF;
|
|
74
|
-
|
|
75
|
-
/** A labeled mixture builder that preserves provenance in Bin.count. */
|
|
76
|
-
declare class Mixture<L extends string = string> {
|
|
77
|
-
private readonly totals;
|
|
78
|
-
private readonly labelMass;
|
|
79
|
-
private readonly eps;
|
|
80
|
-
constructor(eps?: number);
|
|
81
|
-
/** Remove all accumulated state. */
|
|
82
|
-
clear(): this;
|
|
83
|
-
/** Number of distinct outcome values currently accumulated. */
|
|
84
|
-
size(): number;
|
|
85
|
-
/** Whether a label was ever added. */
|
|
86
|
-
hasLabel(label: L): boolean;
|
|
87
|
-
/**
|
|
88
|
-
* Add a labeled component with a mixture weight.
|
|
89
|
-
* Weight can be any positive finite number. Very small contributions are pruned by eps.
|
|
90
|
-
*/
|
|
91
|
-
add(label: L, pmf: PMF, weight?: number): this;
|
|
92
|
-
buildPMF(eps?: number): PMF;
|
|
93
|
-
/**
|
|
94
|
-
* Produce normalized *per-label* PMFs (labels independent).
|
|
95
|
-
* These are unlabeled PMFs built from the raw mass of that label alone.
|
|
96
|
-
*/
|
|
97
|
-
byOutcome(): Record<L, PMF>;
|
|
98
|
-
/**
|
|
99
|
-
* Mixture weights per label, normalized to sum to 1 over labels that appeared.
|
|
100
|
-
* Uses raw mass before per-outcome normalization.
|
|
101
|
-
*/
|
|
102
|
-
weights(): Record<L, number>;
|
|
103
|
-
toJSON(): {
|
|
104
|
-
totals: Array<[number, number]>;
|
|
105
|
-
labels: Array<[number, Record<L, number>]>;
|
|
106
|
-
eps: number;
|
|
107
|
-
};
|
|
108
|
-
static mix<L extends string = string>(items: Array<[label: L, pmf: PMF, weight: number]>, eps?: number): PMF;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
export { type BounceOddsOptions, DiceParseError, Mixture, PMF, calculateBounceOdds, clearParserCache, getCachingEnabled, parse, setCachingEnabled };
|
|
1
|
+
export * from "./common/bounce.js";
|
|
2
|
+
export * from "./common/errors.js";
|
|
3
|
+
export * from "./common/lru-cache.js";
|
|
4
|
+
export * from "./common/types.js";
|
|
5
|
+
export * from "./parser/parser.js";
|
|
6
|
+
export * from "./pmf/mixture.js";
|
|
7
|
+
export * from "./pmf/pmf.js";
|
|
8
|
+
export * from "./pmf/query.js";
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { DamageDistribution, OutcomeType } from "../common/types.js";
|
|
2
|
+
import { PMF } from "../pmf/pmf.js";
|
|
3
|
+
/** Internal bookkeeping attached to a {@link Dice} during parsing. */
|
|
4
|
+
export interface DicePrivateData {
|
|
5
|
+
/** Marks a DC (saving-throw) check so outcomes are attributed correctly. */
|
|
6
|
+
isDCCheck?: boolean;
|
|
7
|
+
/** The "other" distribution recorded by {@link Dice.combine}. */
|
|
8
|
+
except?: Dice | Record<string, never>;
|
|
9
|
+
/** Keep-highest/lowest selector applied when a die is multiplied out. */
|
|
10
|
+
keep?: (values: number[]) => number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* @internal
|
|
14
|
+
*/
|
|
15
|
+
export declare class Dice {
|
|
16
|
+
private readonly faces;
|
|
17
|
+
privateData: DicePrivateData;
|
|
18
|
+
private outcomeData;
|
|
19
|
+
private hasHitDistributionCalculated;
|
|
20
|
+
identifier?: string;
|
|
21
|
+
constructor(x?: number);
|
|
22
|
+
getOutcomeDistribution(key: OutcomeType): DamageDistribution | undefined;
|
|
23
|
+
getFullOutcomeDistribution(): Partial<Record<OutcomeType, DamageDistribution>>;
|
|
24
|
+
setOutcomeDistribution(key: OutcomeType, data: DamageDistribution | undefined): void;
|
|
25
|
+
hasOutcomeData(key: OutcomeType): boolean;
|
|
26
|
+
getOutcomeCount(key: OutcomeType, face: number): number;
|
|
27
|
+
getAverage(key: OutcomeType): number;
|
|
28
|
+
calculateHitDistribution(): DamageDistribution;
|
|
29
|
+
private ensureHitDistribution;
|
|
30
|
+
private binaryOp;
|
|
31
|
+
private removeFaces;
|
|
32
|
+
getFaceEntries(): [number, number][];
|
|
33
|
+
getFaceMap(): DamageDistribution;
|
|
34
|
+
get(face: number): number;
|
|
35
|
+
keys(): number[];
|
|
36
|
+
values(): number[];
|
|
37
|
+
total(): number;
|
|
38
|
+
setFace(key: number, value: number): void;
|
|
39
|
+
static scalar(value: number): Dice;
|
|
40
|
+
maxFace(): number;
|
|
41
|
+
minFace(): number;
|
|
42
|
+
increment(face: number, count: number): void;
|
|
43
|
+
normalize(scalar: number): Dice;
|
|
44
|
+
add(other: Dice | number): Dice;
|
|
45
|
+
subtract(other: Dice | number): Dice;
|
|
46
|
+
conditionalApply(other: Dice | number): Dice;
|
|
47
|
+
multiply(other: Dice | number): Dice;
|
|
48
|
+
addNonZero(other: Dice | number): Dice;
|
|
49
|
+
eq(other: Dice | number): Dice;
|
|
50
|
+
max(other: Dice | number): Dice;
|
|
51
|
+
min(other: Dice | number): Dice;
|
|
52
|
+
advantage(): Dice;
|
|
53
|
+
ge(other: Dice | number): Dice;
|
|
54
|
+
divide(other: Dice | number): Dice;
|
|
55
|
+
divideRoundUp(other: Dice | number): Dice;
|
|
56
|
+
divideRoundDown(other: Dice | number): Dice;
|
|
57
|
+
and(other: Dice | number): Dice;
|
|
58
|
+
private checkTarget;
|
|
59
|
+
dc(other: Dice | number): Dice;
|
|
60
|
+
ac(other: Dice | number): Dice;
|
|
61
|
+
deleteFace(face: number): Dice;
|
|
62
|
+
reroll(toReroll: Dice | number): Dice;
|
|
63
|
+
combine(other: Dice | number): Dice;
|
|
64
|
+
combineInPlace(other: Dice): void;
|
|
65
|
+
percent(): DamageDistribution;
|
|
66
|
+
average(): number;
|
|
67
|
+
toPMF(numEpsilon?: number): PMF;
|
|
68
|
+
}
|
|
69
|
+
export type _DiceInternal = never;
|
|
70
|
+
//# sourceMappingURL=dice.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dice.d.ts","sourceRoot":"","sources":["../../src/parser/dice.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { PMF } from "../pmf/pmf.js";
|
|
2
|
+
/** Enable or disable the internal parse cache. */
|
|
3
|
+
export declare function setCachingEnabled(enabled: boolean): void;
|
|
4
|
+
/** Returns whether the internal parse cache is currently enabled. */
|
|
5
|
+
export declare function getCachingEnabled(): boolean;
|
|
6
|
+
/** Clears the internal parse cache. */
|
|
7
|
+
export declare function clearParserCache(): void;
|
|
8
|
+
/**
|
|
9
|
+
* Parse a dice expression into a PMF.
|
|
10
|
+
*
|
|
11
|
+
* - Expression is case-insensitive and ignores spaces.
|
|
12
|
+
*/
|
|
13
|
+
export declare function parse(expression: string, n?: number): PMF;
|
|
14
|
+
//# sourceMappingURL=parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/parser/parser.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AA2BtC,kDAAkD;AAClD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAGxD;AAED,qEAAqE;AACrE,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C;AAED,uCAAuC;AACvC,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC;AAED;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,UAAU,EAAE,MAAM,EAAE,CAAC,GAAE,MAAU,GAAG,GAAG,CAyC5D"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { PMF } from "./pmf.js";
|
|
2
|
+
/** A labeled mixture builder that preserves provenance in Bin.count. */
|
|
3
|
+
export declare class Mixture<L extends string = string> {
|
|
4
|
+
private readonly totals;
|
|
5
|
+
private readonly labelMass;
|
|
6
|
+
private readonly eps;
|
|
7
|
+
constructor(eps?: number);
|
|
8
|
+
/** Remove all accumulated state. */
|
|
9
|
+
clear(): this;
|
|
10
|
+
/** Number of distinct outcome values currently accumulated. */
|
|
11
|
+
size(): number;
|
|
12
|
+
/** Whether a label was ever added. */
|
|
13
|
+
hasLabel(label: L): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Add a labeled component with a mixture weight.
|
|
16
|
+
* Weight can be any positive finite number. Very small contributions are pruned by eps.
|
|
17
|
+
*/
|
|
18
|
+
add(label: L, pmf: PMF, weight?: number): this;
|
|
19
|
+
buildPMF(eps?: number): PMF;
|
|
20
|
+
/**
|
|
21
|
+
* Produce normalized *per-label* PMFs (labels independent).
|
|
22
|
+
* These are unlabeled PMFs built from the raw mass of that label alone.
|
|
23
|
+
*/
|
|
24
|
+
byOutcome(): Record<L, PMF>;
|
|
25
|
+
/**
|
|
26
|
+
* Mixture weights per label, normalized to sum to 1 over labels that appeared.
|
|
27
|
+
* Uses raw mass before per-outcome normalization.
|
|
28
|
+
*/
|
|
29
|
+
weights(): Record<L, number>;
|
|
30
|
+
toJSON(): {
|
|
31
|
+
totals: Array<[number, number]>;
|
|
32
|
+
labels: Array<[number, Record<L, number>]>;
|
|
33
|
+
eps: number;
|
|
34
|
+
};
|
|
35
|
+
static mix<L extends string = string>(items: Array<[label: L, pmf: PMF, weight: number]>, eps?: number): PMF;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=mixture.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mixture.d.ts","sourceRoot":"","sources":["../../src/pmf/mixture.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAE5B,wEAAwE;AACxE,qBAAa,OAAO,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM;IAC5C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA6B;IACpD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAwC;IAClE,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAE7B,YAAY,GAAG,GAAE,MAAY,EAE5B;IAED,oCAAoC;IACpC,KAAK,IAAI,IAAI,CAIZ;IAED,+DAA+D;IAC/D,IAAI,IAAI,MAAM,CAEb;IAED,sCAAsC;IACtC,QAAQ,CAAC,KAAK,EAAE,CAAC,GAAG,OAAO,CAG1B;IAED;;;OAGG;IACH,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,SAAI,GAAG,IAAI,CAkBxC;IAED,QAAQ,CAAC,GAAG,GAAE,MAAY,GAAG,GAAG,CAmB/B;IAED;;;OAGG;IACH,SAAS,IAAI,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,CAiB1B;IAED;;;OAGG;IACH,OAAO,IAAI,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAqB3B;IAED,MAAM,IAAI;QACR,MAAM,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;QAChC,MAAM,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;QAC3C,GAAG,EAAE,MAAM,CAAC;KACb,CAMA;IAED,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,EAClC,KAAK,EAAE,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,EAClD,GAAG,GAAE,MAAY,GAChB,GAAG,CAIL;CACF"}
|
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
import { LRUCache } from "../common/lru-cache.js";
|
|
2
|
+
import type { Bin, Rounding } from "../common/types.js";
|
|
3
|
+
import { DiceQuery } from "./query.js";
|
|
4
|
+
export declare const pmfCache: LRUCache<string, PMF>;
|
|
5
|
+
/**
|
|
6
|
+
* Probability Mass Function for discrete damage distributions.
|
|
7
|
+
*/
|
|
8
|
+
export declare class PMF {
|
|
9
|
+
readonly map: Map<number, Bin>;
|
|
10
|
+
readonly epsilon: number;
|
|
11
|
+
readonly normalized: boolean;
|
|
12
|
+
readonly identifier: string;
|
|
13
|
+
private _preservedProvenance;
|
|
14
|
+
private static __anonIdCounter;
|
|
15
|
+
private _support?;
|
|
16
|
+
private _min?;
|
|
17
|
+
private _max?;
|
|
18
|
+
private _totalMass?;
|
|
19
|
+
private _mean?;
|
|
20
|
+
private _variance?;
|
|
21
|
+
private _stdev?;
|
|
22
|
+
private _fingerprint?;
|
|
23
|
+
constructor(map?: Map<number, Bin>, epsilon?: number, normalized?: boolean, identifier?: string, _preservedProvenance?: boolean);
|
|
24
|
+
static empty(epsilon?: number, identifier?: string): PMF;
|
|
25
|
+
static zero(epsilon?: number): PMF;
|
|
26
|
+
static delta(value: number, epsilon?: number): PMF;
|
|
27
|
+
/**
|
|
28
|
+
* Point mass at damage 0 tagged with the canonical `missNone` outcome.
|
|
29
|
+
*
|
|
30
|
+
* Differs from {@link PMF.zero}, which labels its zero bin `miss` — the
|
|
31
|
+
* builder's attack-resolution vocabulary. This uses the `missNone`
|
|
32
|
+
* {@link OutcomeType} that the attribution charts and outcome stats key on,
|
|
33
|
+
* so it is the correct "clean miss / no damage" delta for provenance-aware
|
|
34
|
+
* mixtures feeding those consumers.
|
|
35
|
+
*/
|
|
36
|
+
static missNone(epsilon?: number): PMF;
|
|
37
|
+
static emptyMass(): PMF;
|
|
38
|
+
[Symbol.iterator](): IterableIterator<[number, Bin]>;
|
|
39
|
+
static clearCache(): void;
|
|
40
|
+
/**
|
|
41
|
+
* Creates a conditional PMF from two branches (success and failure) and a probability.
|
|
42
|
+
* This is the core logic for modeling any probabilistic event where there are two
|
|
43
|
+
* distinct outcomes.
|
|
44
|
+
*/
|
|
45
|
+
static branch(successPMF: PMF, failurePMF: PMF, successProbability: number): PMF;
|
|
46
|
+
/**
|
|
47
|
+
* withProbability()
|
|
48
|
+
*
|
|
49
|
+
* A convenience wrapper around branch() for the common case where the "failure" branch is always zero().
|
|
50
|
+
*
|
|
51
|
+
* Think of this as a shortcut for:
|
|
52
|
+
* pmf.gate(p, PMF.zero())
|
|
53
|
+
*
|
|
54
|
+
* Use this to model a *single* Bernoulli event — an outcome that either happens or doesn't,
|
|
55
|
+
* like an opportunity attack that occurs with probability p, or a single attack that either hits or misses.
|
|
56
|
+
*
|
|
57
|
+
* This is **not** for combining multiple independent attacks or mutually exclusive multi-outcome scenarios.
|
|
58
|
+
* - For multiple independent swings, use DiceQuery with separate PMFs for each attack.
|
|
59
|
+
* - For modeling "first success" logic across multiple attacks (like Sneak Attack or Smite)
|
|
60
|
+
* use query.firstSuccessSplit() to get the exact probabilities.
|
|
61
|
+
* - For scenarios with several mutually exclusive outcomes (like crit vs hit vs none), use PMF.exclusive().
|
|
62
|
+
*
|
|
63
|
+
*/
|
|
64
|
+
static withProbability(successPMF: PMF, probability: number): PMF;
|
|
65
|
+
/**
|
|
66
|
+
* gate()
|
|
67
|
+
*
|
|
68
|
+
* A conditional wrapper around branch() that applies this PMF with probability `p`,
|
|
69
|
+
* and applies a provided fallback PMF otherwise.
|
|
70
|
+
*
|
|
71
|
+
* This is useful for modeling a binary choice between two outcomes:
|
|
72
|
+
* - The "success" outcome (this PMF) happens with probability `p`.
|
|
73
|
+
* - The "failure" outcome (fallback PMF) happens with probability `1 - p`.
|
|
74
|
+
*
|
|
75
|
+
* Examples:
|
|
76
|
+
* - 25% chance to include an opportunity attack, otherwise nothing:
|
|
77
|
+
* attackPMF.gate(0.25, PMF.zero())
|
|
78
|
+
*
|
|
79
|
+
* - 50% chance to deal fireball damage, otherwise cone of cold damage:
|
|
80
|
+
* fireballPMF.gate(0.5, coneOfColdPMF)
|
|
81
|
+
*
|
|
82
|
+
* Relationship to other helpers:
|
|
83
|
+
* - **withProbability()** is a shortcut for the common case where the fallback is `PMF.zero()`.
|
|
84
|
+
* - **exclusive()** is for three or more mutually exclusive outcomes (e.g., crit vs hit vs none).
|
|
85
|
+
*
|
|
86
|
+
* @param p Probability of applying this PMF (between 0 and 1).
|
|
87
|
+
* @param fallback PMF to apply when this PMF is *not* selected.
|
|
88
|
+
* @returns A new PMF representing the weighted mixture of this PMF and the fallback.
|
|
89
|
+
*/
|
|
90
|
+
gate(p: number, fallback: PMF): PMF;
|
|
91
|
+
/**
|
|
92
|
+
* PMF.exclusive()
|
|
93
|
+
*
|
|
94
|
+
* Builds a single PMF from a set of mutually exclusive weighted outcomes.
|
|
95
|
+
* Exactly one of the provided options will occur.
|
|
96
|
+
*
|
|
97
|
+
* Each option has:
|
|
98
|
+
* - A PMF representing its outcome (e.g., damage dice).
|
|
99
|
+
* - A weight representing its probability of being selected.
|
|
100
|
+
*
|
|
101
|
+
* Notes:
|
|
102
|
+
* - If total weight < 1 (within eps), leftover mass is assumed to be PMF.zero()
|
|
103
|
+
*
|
|
104
|
+
* @param options Array of `{ pmf, weight }` or `[PMF, number]`.
|
|
105
|
+
* @param eps Optional tolerance for floating point rounding.
|
|
106
|
+
*/
|
|
107
|
+
static exclusive(options: Array<{
|
|
108
|
+
pmf: PMF;
|
|
109
|
+
weight: number;
|
|
110
|
+
} | [PMF, number]>, eps?: number): PMF;
|
|
111
|
+
/**
|
|
112
|
+
* PMF.mix()
|
|
113
|
+
*
|
|
114
|
+
* Builds a PMF as a linear combination of input PMFs with the given weights.
|
|
115
|
+
* Unlike `exclusive`, this does NOT:
|
|
116
|
+
* - enforce that weights sum to 1
|
|
117
|
+
* - add leftover probability to δ0 (PMF.zero())
|
|
118
|
+
*
|
|
119
|
+
* Use when outcomes are not mutually exclusive, or for interpolation/blending.
|
|
120
|
+
*
|
|
121
|
+
* @param options Array of `{ pmf, weight }` or `[PMF, number]`.
|
|
122
|
+
* @param eps Optional tolerance for skipping tiny weights.
|
|
123
|
+
*/
|
|
124
|
+
static mix(options: Array<{
|
|
125
|
+
pmf: PMF;
|
|
126
|
+
weight: number;
|
|
127
|
+
} | [PMF, number]>, eps?: number): PMF;
|
|
128
|
+
/**
|
|
129
|
+
* Adds damage attribution metadata to this PMF based on existing count metadata.
|
|
130
|
+
* For each bin, sets attr[outcome] = damage × count[outcome].
|
|
131
|
+
*
|
|
132
|
+
* This enables damage attribution charts to work with builder-generated PMFs.
|
|
133
|
+
* The parser generates attr automatically, but builder PMFs only have count.
|
|
134
|
+
*
|
|
135
|
+
* @returns New PMF with attr field populated in each bin
|
|
136
|
+
*/
|
|
137
|
+
/**
|
|
138
|
+
* Returns true if this PMF already carries damage attribution metadata.
|
|
139
|
+
*
|
|
140
|
+
* Only the first positive-damage bin is inspected (parser-generated PMFs
|
|
141
|
+
* populate `attr` uniformly), so this is O(1) in practice.
|
|
142
|
+
*/
|
|
143
|
+
hasAttribution(): boolean;
|
|
144
|
+
withAttribution(): PMF;
|
|
145
|
+
/**
|
|
146
|
+
* General-purpose N-way mixture.
|
|
147
|
+
* weights: Array of [weight, PMF].
|
|
148
|
+
*
|
|
149
|
+
* Example: PMF.mixN([
|
|
150
|
+
* [pMiss, zero],
|
|
151
|
+
* [pHit, hitPMF],
|
|
152
|
+
* [pCrit, critPMF],
|
|
153
|
+
* ]);
|
|
154
|
+
*/
|
|
155
|
+
static mixN(weights: [number, PMF][], eps?: number): PMF;
|
|
156
|
+
private setPreservedProvenance;
|
|
157
|
+
preservedProvenance(): boolean;
|
|
158
|
+
private getPowerCacheKey;
|
|
159
|
+
/**
|
|
160
|
+
* Efficiently computes this PMF convolved with itself `n` times.
|
|
161
|
+
* Uses exponentiation by squaring to reduce total convolutions.
|
|
162
|
+
* n must be a positive integer.
|
|
163
|
+
* *
|
|
164
|
+
* * NOTE: This folds multiple independent attacks into a single PMF.
|
|
165
|
+
* As a result, The power() method causes a loss of data provenance.
|
|
166
|
+
* This is ONLY SAFE if you are trying to calculate masses.
|
|
167
|
+
* If you want to query any atLeast probabilities, you should use the DiceQuery class instead without power().
|
|
168
|
+
*/
|
|
169
|
+
power(n: number, eps?: number): PMF;
|
|
170
|
+
replicate(n: number): PMF[];
|
|
171
|
+
mass(): number;
|
|
172
|
+
outcomeMass(outcome: string): number;
|
|
173
|
+
faceTotal(): number;
|
|
174
|
+
normalize(): PMF;
|
|
175
|
+
/**
|
|
176
|
+
* Returns a copy with negligible probabilities removed (p < eps).
|
|
177
|
+
* If keepFinalBin is true, the bin with the largest key is always kept,
|
|
178
|
+
* even if its probability is below eps. count/attr submaps are still cleaned.
|
|
179
|
+
*/
|
|
180
|
+
compact(eps?: number, keepFinalBin?: boolean): PMF;
|
|
181
|
+
support(): number[];
|
|
182
|
+
min(): number;
|
|
183
|
+
max(): number;
|
|
184
|
+
/**
|
|
185
|
+
* Returns the expected (mean) damage value.
|
|
186
|
+
* Cached for performance since this requires iterating through all bins.
|
|
187
|
+
*/
|
|
188
|
+
mean(): number;
|
|
189
|
+
/**
|
|
190
|
+
* Returns the variance of the damage distribution.
|
|
191
|
+
* Cached for performance since this requires mean calculation plus iteration.
|
|
192
|
+
*/
|
|
193
|
+
variance(): number;
|
|
194
|
+
/**
|
|
195
|
+
* Returns the standard deviation of the damage distribution.
|
|
196
|
+
*/
|
|
197
|
+
stdev(): number;
|
|
198
|
+
/** Deep-copies a Bin, cloning its count and (optional) attr maps. */
|
|
199
|
+
private static cloneBin;
|
|
200
|
+
/** Returns a new Bin with p, count, and attr all multiplied by `factor`. */
|
|
201
|
+
private static scaleBin;
|
|
202
|
+
private static mergeInto;
|
|
203
|
+
add(other: PMF): PMF;
|
|
204
|
+
/**
|
|
205
|
+
* Returns a new PMF with a scaled branch added to this one.
|
|
206
|
+
* The branch PMF is scaled by the given probability before merging
|
|
207
|
+
* This will be very useful for conditional effects and for being
|
|
208
|
+
* able to model "I can probably have this opportunity attack 40% of rounds"
|
|
209
|
+
* Example: `pmf.addScaled(critBranch, 0.05)` → PMF including 5% crit outcomes
|
|
210
|
+
*/
|
|
211
|
+
addScaled(branch: PMF, probability: number): PMF;
|
|
212
|
+
/**
|
|
213
|
+
* Redistributes probability mass to model an effect that only occurs with
|
|
214
|
+
* probability `frequency` — a conditional attack, an on-hit rider, or a
|
|
215
|
+
* sub-one AoE target fraction.
|
|
216
|
+
*
|
|
217
|
+
* Every hit outcome (damage > 0) is scaled by `frequency` — probability mass,
|
|
218
|
+
* per-label `count`, AND per-label `attr` — and the freed mass is moved into
|
|
219
|
+
* the miss bin at damage 0, tagged with the canonical `missNone` outcome.
|
|
220
|
+
* Total probability mass is preserved.
|
|
221
|
+
*
|
|
222
|
+
* Unlike a bare {@link scaleMass} or {@link mapDamage}, this keeps damage
|
|
223
|
+
* attribution (`attr`) intact, so a frequency-scaled PMF still renders
|
|
224
|
+
* correctly in the damage-attribution charts.
|
|
225
|
+
*
|
|
226
|
+
* `frequency >= 1` (or non-finite) returns this PMF unchanged; `frequency <= 0`
|
|
227
|
+
* collapses all mass into the miss bin. The miss outcome is assumed to be
|
|
228
|
+
* encoded at damage value 0.
|
|
229
|
+
*
|
|
230
|
+
* @param frequency Probability in [0, 1] that the effect occurs.
|
|
231
|
+
*/
|
|
232
|
+
applyHitFrequency(frequency: number): PMF;
|
|
233
|
+
scaleMass(factor: number): PMF;
|
|
234
|
+
mapDamage(damageTransformFunction: (damageValue: number) => number): PMF;
|
|
235
|
+
scaleDamage(factor: number, rounding?: "floor" | "round" | "ceil"): PMF;
|
|
236
|
+
private getPMFCombineCacheKey;
|
|
237
|
+
/**
|
|
238
|
+
* A small content fingerprint (mass + bin count + face sum) so convolution
|
|
239
|
+
* cache keys change if the underlying numbers do. Memoized because a PMF is
|
|
240
|
+
* immutable once constructed — this avoids re-summing every key on each
|
|
241
|
+
* convolve() call (including cache hits).
|
|
242
|
+
*/
|
|
243
|
+
fingerprint(): string;
|
|
244
|
+
convolve(other: PMF, eps?: number, raw?: boolean): PMF;
|
|
245
|
+
combineRaw(other: PMF, eps?: number): PMF;
|
|
246
|
+
private static reduceConvolveLeft;
|
|
247
|
+
/**
|
|
248
|
+
* Convolves multiple PMFs using linear convolution with automatic caching.
|
|
249
|
+
* Uses a left-to-right accumulation approach for maximum cache reuse.
|
|
250
|
+
* Each convolve() call automatically uses the convolution cache for performance.
|
|
251
|
+
*
|
|
252
|
+
* This linear approach provides better cache hits than pairwise because:
|
|
253
|
+
* - Intermediate results are more predictable and stable
|
|
254
|
+
* - Similar PMF lists share common prefixes (A+B, (A+B)+C, etc.)
|
|
255
|
+
* - Order-independent cache keys work better with consistent build patterns
|
|
256
|
+
*/
|
|
257
|
+
static convolveMany(pmfList: PMF[], eps?: number): PMF;
|
|
258
|
+
/**
|
|
259
|
+
* Returns a plain, JSON-serializable representation of this PMF.
|
|
260
|
+
*
|
|
261
|
+
* Follows the standard `toJSON` contract, so `JSON.stringify(pmf)` produces
|
|
262
|
+
* the expected output (no double-encoding). Use {@link PMF.fromJSON} to
|
|
263
|
+
* reconstruct, or {@link PMF.toJSONString} if you need the string directly.
|
|
264
|
+
*/
|
|
265
|
+
toJSON(): {
|
|
266
|
+
bins: Array<[number, Bin]>;
|
|
267
|
+
normalized: boolean;
|
|
268
|
+
identifier: string;
|
|
269
|
+
};
|
|
270
|
+
/** Serializes this PMF to a JSON string (equivalent to `JSON.stringify(pmf)`). */
|
|
271
|
+
toJSONString(): string;
|
|
272
|
+
static fromJSON(jsonData: {
|
|
273
|
+
bins: Array<[number, Bin]>;
|
|
274
|
+
normalized?: boolean;
|
|
275
|
+
identifier?: string;
|
|
276
|
+
}): PMF;
|
|
277
|
+
/**
|
|
278
|
+
* Relative pruning with optional top-K floor.
|
|
279
|
+
* Keeps bins with p >= epsRel * peak, always keeps min and max damage,
|
|
280
|
+
* optionally guarantees at least `minBins` survivors by adding top-K.
|
|
281
|
+
* Returns a new, non-normalized PMF.
|
|
282
|
+
*/
|
|
283
|
+
prune(epsRel: number, minBins?: number): PMF;
|
|
284
|
+
/** Probability mass at exactly x. */
|
|
285
|
+
pAt(x: number): number;
|
|
286
|
+
/**
|
|
287
|
+
* P(any damage) — the mass on all non-zero outcomes, i.e. `1 - P(0)`.
|
|
288
|
+
* Assumes a miss is encoded as the damage-0 bin (the convention used across
|
|
289
|
+
* attack/save PMFs). The dual of {@link missProbability}.
|
|
290
|
+
*/
|
|
291
|
+
hitProbability(): number;
|
|
292
|
+
/** P(no damage) — the mass at damage 0. The dual of {@link hitProbability}. */
|
|
293
|
+
missProbability(): number;
|
|
294
|
+
/**
|
|
295
|
+
* Coarsen the distribution into at most `maxBuckets` contiguous, equal-width
|
|
296
|
+
* damage buckets, aggregating probability mass (and `count`/`attr`
|
|
297
|
+
* provenance) into each bucket's start value. Returns this PMF unchanged when
|
|
298
|
+
* its integer support already fits within `maxBuckets`.
|
|
299
|
+
*
|
|
300
|
+
* This is a lossy display/downsampling transform (bucket start replaces the
|
|
301
|
+
* exact damage value) — use it for charting wide distributions, not for DPR
|
|
302
|
+
* math.
|
|
303
|
+
*/
|
|
304
|
+
rebin(maxBuckets: number): PMF;
|
|
305
|
+
/** Dense integer support from min..max (inclusive).
|
|
306
|
+
* Useful for showing empty bars in charts.
|
|
307
|
+
*/
|
|
308
|
+
denseSupport(): number[];
|
|
309
|
+
/** CDF at x: P(X ≤ x). */
|
|
310
|
+
cdfAt(x: number): number;
|
|
311
|
+
/** Quantile / inverse CDF for p in [0,1]. Returns smallest x with CDF ≥ p. */
|
|
312
|
+
quantile(p: number): number;
|
|
313
|
+
/** Get outcome probability at specific damage value. */
|
|
314
|
+
outcomeAt(damage: number, outcome: string): number;
|
|
315
|
+
/** Get all outcome types present in this PMF. */
|
|
316
|
+
outcomes(): string[];
|
|
317
|
+
/** Get total probability of an outcome across all damage values. */
|
|
318
|
+
outcomeProbability(outcome: string): number;
|
|
319
|
+
/** Get damage attribution for an outcome at specific damage value. */
|
|
320
|
+
outcomeAttributionAt(damage: number, outcome: string): number;
|
|
321
|
+
/** Get all outcome data at specific damage value. */
|
|
322
|
+
binAt(damage: number): {
|
|
323
|
+
p: number;
|
|
324
|
+
count: Record<string, number>;
|
|
325
|
+
attr?: Record<string, number>;
|
|
326
|
+
} | null;
|
|
327
|
+
/** Check if outcome exists in this PMF. */
|
|
328
|
+
hasOutcome(outcome: string): boolean;
|
|
329
|
+
/**
|
|
330
|
+
* Split each damage value's probability mass across outcome labels, returning
|
|
331
|
+
* per-label maps of `damage value → probability mass attributable to that
|
|
332
|
+
* label`. Summing over labels at a given value recovers that value's `p`.
|
|
333
|
+
*
|
|
334
|
+
* Damage-bearing bins are split by `attr` weight (the share of damage each
|
|
335
|
+
* outcome contributed); the clean-miss bin at 0 is split by `count` weight
|
|
336
|
+
* (there is no damage to attribute). Attribution is computed on demand via
|
|
337
|
+
* {@link withAttribution} when absent, so builder-generated PMFs work too.
|
|
338
|
+
*
|
|
339
|
+
* This is the provenance core of the stacked damage-attribution chart — the
|
|
340
|
+
* caller only maps these series into its rendering format (colors, binning,
|
|
341
|
+
* axis labels).
|
|
342
|
+
*/
|
|
343
|
+
attributionByValue(): Map<string, Map<number, number>>;
|
|
344
|
+
tailProbGE(t: number): number;
|
|
345
|
+
tailProbGT(t: number): number;
|
|
346
|
+
/**
|
|
347
|
+
* Returns a new PMF containing only bins where the specified outcome has non-zero probability.
|
|
348
|
+
* This creates a marginal distribution for the given outcome type, with probabilities
|
|
349
|
+
* scaled to represent the unconditional mass attributable to that outcome.
|
|
350
|
+
*/
|
|
351
|
+
filterOutcome(outcome: string): PMF;
|
|
352
|
+
/**
|
|
353
|
+
* Calculates probabilities for first-success outcomes across n independent attempts.
|
|
354
|
+
*
|
|
355
|
+
* @param pSuccess - Total probability of any success on a single attempt.
|
|
356
|
+
* @param pSpecial - Probability of a specific subset of successes (e.g., critical success).
|
|
357
|
+
* @param n - Number of independent attempts.
|
|
358
|
+
*
|
|
359
|
+
* Returns:
|
|
360
|
+
* - pSpecificSuccess: Probability that the first success was of the "special" type
|
|
361
|
+
* - pGeneralSuccess: Probability that the first success was of the non-special type
|
|
362
|
+
* - pNone: Probability that no successes occurred
|
|
363
|
+
* - pAny: Probability that at least one success occurred
|
|
364
|
+
*/
|
|
365
|
+
static firstSuccessWeights(pSuccess: number, pSpecial: number, n: number): {
|
|
366
|
+
pSpecificSuccess: number;
|
|
367
|
+
pGeneralSuccess: number;
|
|
368
|
+
pNone: number;
|
|
369
|
+
pAny: number;
|
|
370
|
+
};
|
|
371
|
+
mapValues(f: (v: number) => number, eps?: number, opts?: {
|
|
372
|
+
rounding?: Rounding;
|
|
373
|
+
preserveCounts?: boolean;
|
|
374
|
+
}): PMF;
|
|
375
|
+
static fromMap(m: Map<number, number>, eps?: number, { requireIntegerValues }?: {
|
|
376
|
+
requireIntegerValues?: boolean;
|
|
377
|
+
}): PMF;
|
|
378
|
+
query(): DiceQuery;
|
|
379
|
+
}
|
|
380
|
+
//# sourceMappingURL=pmf.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pmf.d.ts","sourceRoot":"","sources":["../../src/pmf/pmf.ts"],"names":[],"mappings":"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"}
|