probTableRng = probTable => {
const probsSum = _.sumBy(probTable, ([val, prob]) => prob || 0);
const restProbItems = probTable.filter(([val, prob]) => prob == null).length;
if (probsSum < 1 && restProbItems === 0) {
throw Error('all probs should sum to 1, or at least one be left without prob')
}
const defaultProb = restProbItems === 0 ? 0 : Math.max(0, 1.0 - probsSum) / restProbItems;
return () => {
const rnd = random();
let cursor = 0;
for (let [val, prob] of probTable) {
cursor += (prob != null ? prob : defaultProb);
if (rnd < cursor) return val;
}
}
}