dice parser

This commit is contained in:
Emmaline Autumn 2024-08-05 03:54:38 -06:00
parent f8fa3ec924
commit e6d8583220

89
lib/dice.ts Normal file
View File

@ -0,0 +1,89 @@
export class Dice {
private count!: number;
private sides!: number;
constructor(dice: string) {
this.parseDice(dice);
}
private parseDice(dice: string) {
const [c, s] = dice.split(/[dD]/);
this.count = Number(c);
this.sides = Number(s);
}
public roll() {
let total = 0;
for (let i = 0; i < this.count; i++) {
total += this.rollSingle();
}
return total;
}
private rollSingle() {
return Math.ceil(Math.random() * this.sides);
}
public rollAvg() {
return this.roll() / this.count;
}
public rollTimes(times: number) {
let total = 0;
for (let i = 0; i < times; i++) {
total += this.roll();
}
return total;
}
public rollTimesAvg(times: number) {
return this.rollTimes(times) / times;
}
public getNormalizedRollDistribution(): Record<number, number> {
const distribution: Record<number, number> = this.computeDistribution();
// Normalize the distribution
const totalOutcomes = Math.pow(this.sides, this.count);
for (const sum in distribution) {
if (distribution.hasOwnProperty(sum)) {
distribution[sum] /= totalOutcomes;
}
}
return distribution;
}
public getRollDistribution(): Record<number, number> {
return this.computeDistribution();
}
private computeDistribution(): Record<number, number> {
const distribution: Record<number, number> = {};
// Helper function to compute the sum distribution for given number of dice
const computeSumDistribution = (
dice: number,
sides: number,
currentSum: number,
currentDice: number
): void => {
if (currentDice === dice) {
distribution[currentSum] = (distribution[currentSum] || 0) + 1;
return;
}
for (let i = 1; i <= sides; i++) {
computeSumDistribution(dice, sides, currentSum + i, currentDice + 1);
}
};
// Compute distribution
computeSumDistribution(this.count, this.sides, 0, 0);
return distribution;
}
// STATIC
static isDice(d: string) {
return /\d+[dD]\d+/.test(d);
}
}