@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
52 lines (38 loc) • 1.3 kB
JavaScript
import { assert } from "../../assert.js";
import { binarySearchHighIndex } from "./binarySearchHighIndex.js";
import { number_compare_ascending } from "../../primitives/numbers/number_compare_ascending.js";
/**
*
* @type {number[]}
*/
const scratch_weights = [];
/**
* @template T
* @param {T[]} array
* @param {function} random
* @param {function(T):number} weight
* @param {*} [weightContext]
* @param {number} [length]
* @returns {T|undefined}
*/
export function weightedRandomFromArray(array, random, weight, weightContext, length = array.length) {
assert.isArray(array, 'array');
assert.isFunction(random, 'random');
assert.isFunction(weight, 'weight');
if (length === 0) {
return undefined;
}
let weight_total = 0;
for (let i = 0; i < length; i++) {
const el = array[i];
const w = weight.call(weightContext, el);
if (w > 0) {
// ignore negative weights, clamp them to 0
weight_total += w;
}
scratch_weights[i] = weight_total;
}
const target_weight = random() * weight_total;
const index = binarySearchHighIndex(scratch_weights, target_weight, number_compare_ascending, 0, length - 1);
return array[index];
}