Files
2024-03-12 17:28:38 +04:00

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]);
}
}