125 lines
3.0 KiB
JavaScript
125 lines
3.0 KiB
JavaScript
const { log } = require("console");
|
|
const RollCheck = require("./RollCheck");
|
|
const StatRoll = require("./StatRoll");
|
|
const { stat } = require("fs");
|
|
const ResultStatistics = require("./ResultStatistics");
|
|
|
|
|
|
module.exports = class Checker {
|
|
/**
|
|
* @type {RollCheck[]}
|
|
*/
|
|
checks = [];
|
|
|
|
/**
|
|
* @type {int[]}
|
|
*/
|
|
amounts;
|
|
|
|
/**
|
|
* @type {int}
|
|
*/
|
|
attemts;
|
|
|
|
/**
|
|
* @type {boolean}
|
|
*/
|
|
#isPrepared = false;
|
|
|
|
/**
|
|
* @type {ResultStatistics}
|
|
*/
|
|
statistic_all;
|
|
|
|
/**
|
|
* @type {ResultStatistics}
|
|
*/
|
|
statistic_passed;
|
|
|
|
variants = {};
|
|
|
|
full_mask;
|
|
|
|
/**
|
|
* @param {string} name
|
|
* @param {(roll: StatRoll) => boolean} fn
|
|
*/
|
|
addCheck(name, fn) {
|
|
if (this.#isPrepared) {
|
|
console.log("Cannot add check while prepared");
|
|
}
|
|
|
|
this.checks.push(new RollCheck(name, fn));
|
|
}
|
|
|
|
prepare() {
|
|
this.amounts = Array.from({length: Math.pow(2, this.checks.length)}, _ => 0);
|
|
this.#isPrepared = true;
|
|
this.attemts = 0;
|
|
|
|
this.statistic_all = new ResultStatistics();
|
|
this.statistic_passed = new ResultStatistics();
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param {StatRoll} statRoll
|
|
*/
|
|
test(statRoll) {
|
|
let mask = 0;
|
|
|
|
for (let i = 0; i < this.checks.length; i++) {
|
|
const check = this.checks[i];
|
|
const checkResult = check.test(statRoll);
|
|
|
|
mask += checkResult ? Math.pow(2, i) : 0;
|
|
}
|
|
|
|
this.amounts[mask] += 1;
|
|
this.attemts += 1;
|
|
|
|
this.statistic_all.add(statRoll);
|
|
|
|
if (mask + 1 === this.amounts.length) {
|
|
this.statistic_passed.add(statRoll);
|
|
}
|
|
}
|
|
|
|
printResults() {
|
|
this.statistic_all.print(this.attemts);
|
|
|
|
const resultPerCheck = [];
|
|
for (let i = 0; i < this.checks.length; i++) {
|
|
const check = this.checks[i];
|
|
const amount = this.amounts.filter((_, mask) => (mask >> i) % 2 > 0).reduce((a, s) => s + a);
|
|
|
|
resultPerCheck.push({
|
|
check: check.name,
|
|
successes: amount,
|
|
successes_percent: 100 * amount / this.attemts,
|
|
fails: this.attemts - amount,
|
|
fails_percent: 100 * (this.attemts - amount) / this.attemts,
|
|
})
|
|
}
|
|
console.table(resultPerCheck);
|
|
|
|
|
|
const result = [];
|
|
|
|
for (let mask = 0; mask < this.amounts.length; mask++) {
|
|
const amount = this.amounts[mask];
|
|
|
|
result.push({
|
|
mask: mask.toString(2),
|
|
successes: this.checks.filter((_, i) => (mask >> i) % 2 > 0).map(f => f.name).join(', '),
|
|
fails: this.checks.filter((_, i) => (mask >> i) % 2 === 0).map(f => f.name).join(', '),
|
|
amount: amount,
|
|
percent: 100 * amount / this.attemts,
|
|
});
|
|
}
|
|
|
|
console.table(result);
|
|
|
|
this.statistic_passed.print(this.amounts[this.amounts.length - 1]);
|
|
}
|
|
} |