hasard
Version:
Random variables and random nested objects manipulation in javascript
68 lines (55 loc) • 1.38 kB
JavaScript
const AbstractHasard = require('./abstract');
const getRanges = function (array) {
const res = [];
let current = 0;
array.forEach(v => {
res.push([current, current + v]);
current += v;
});
return res;
};
class ValueHasard extends AbstractHasard {
check(key, value) {
if (key === 'weights' && Array.isArray(value)) {
const sum = value.reduce((a, b) => a + b, 0);
const tolerance = 1e-6;
if (Math.abs(sum - 1) > tolerance) {
throw (new Error(`sum of weights must be 1 (is ${sum})`));
}
}
}
getOpts(opts) {
let choices;
if (Array.isArray(opts)) {
choices = opts;
} else if (AbstractHasard.isHasard(opts)) {
choices = opts;
} else {
choices = opts.choices;
}
const {weights} = opts;
return {
choices,
weights
};
}
generate(ctx) {
let choice;
if (ctx.weights) {
if (!Array.isArray(ctx.choices)) {
throw (new TypeError('choices must be defined in h.value'));
}
const ranges = getRanges(ctx.weights);
const v = this.prng();
const {index} = ranges.map((value, index) => ({value, index})).filter(({value}) => (value[0] <= v && v < value[1]))[0];
choice = ctx.choices[index];
} else {
choice = ctx.choices[Math.floor(this.prng() * ctx.choices.length)];
}
if (this.constructor.isHasard(choice)) {
return choice.runOnce();
}
return choice;
}
}
module.exports = ValueHasard;