Files
dnd_stat_roll_distribution/ResultStatistics.js
T
2024-03-12 17:28:38 +04:00

94 lines
2.6 KiB
JavaScript

const StatRoll = require("./StatRoll");
const { table } = require('table');
module.exports = class ResultStatistics {
dices = {};
stats = {};
counts = {};
sums = {};
constructor() {
this.dices = {};
this.counts[0] = {};
for (let i = 1; i <= 6; i++) {
this.dices[i] = 0;
this.counts[i] = {};
}
this.stats = {};
for (let j = 3; j <= 18; j++) {
this.stats[j] = 0;
for (let i = 0; i <= 6; i++) {
this.counts[i][j] = 0;
}
}
this.sums = {};
}
/**
* @param {StatRoll} statRoll
*/
add(statRoll) {
for (let i = 0; i < statRoll.rolls.length; i++) {
const stat = statRoll.rolls[i];
// this.stats[stat.result] += 1;
for (const dice of stat.dices) {
this.dices[dice] += 1;
}
}
for (let j = 3; j <= 18; j++) {
let count = statRoll.rolls.filter(r => r.result === j).length;
this.counts[count][j] += 1;
this.stats[j] += count ? 1 : 0;
}
this.sums[statRoll.sum] = (this.sums[statRoll.sum] ?? 0) + 1;
}
print(norm = 1) {
const rows = [];
rows.push([ '', ...Object.keys(this.stats) ]);
rows.push([ 'Probability', ...Object.values(this.stats).map(v => perc(v, norm)) ]);
rows.push([ 'Missing', ...Object.values(this.counts[0]).map(v => perc(v, norm)) ]);
for (let i = 1; i <= 6; i++) {
const counts = this.counts[i];
rows.push([ i, ...Object.values(this.counts[i]).map(v => perc(v, norm)) ]);
}
console.log(table(rows, {
drawHorizontalLine: (i, rc) => [0, 1, 3, rc].indexOf(i) >= 0,
}));
const sums = {};
const spl = 5;
const from = Math.floor(Object.keys(this.sums).reduce((a, m) => Math.min(a, m)) / spl);
const to = Math.floor(Object.keys(this.sums).reduce((a, m) => Math.max(a, m)) / spl);
for (let i = from; i <= to; i++) {
const min = spl * i, max = spl * (i + 1) - 1;
const f = Object.entries(this.sums).filter(([sum, _]) => (sum >= min) && (sum <= max));
sums[`${min}-${max}`] = perc(f.length ? f.map(([_, count]) => count).reduce((count, sum) => sum + count) : 0, norm);
}
console.log(table([ Object.keys(sums), Object.values(sums) ]))
}
}
function perc(a, N) {
return (a == 0) ? '' : `${(100 * a / N).toLocaleString('ru-RU', { maximumFractionDigits: 2, minimumFractionDigits: 2 })}%`;
}