isaacscript-common
Version:
Helper functions and features for IsaacScript mods.
57 lines (56 loc) • 2.69 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.getRandomFromWeightedArray = getRandomFromWeightedArray;
exports.getRandomIndexFromWeightedArray = getRandomIndexFromWeightedArray;
const array_1 = require("./array");
const random_1 = require("./random");
const utils_1 = require("./utils");
/**
* Get a random value from a `WeightedArray`. (A `WeightedArray` is an array of tuples, where the
* first element in the tuple is a value, and the second element in the tuple is a float
* corresponding to the value's weight.)
*
* If you want to get an unseeded element, you must explicitly pass `undefined` to the `seedOrRNG`
* parameter.
*
* @param weightedArray The array to pick from.
* @param seedOrRNG The `Seed` or `RNG` object to use. If an `RNG` object is provided, the
* `RNG.Next` method will be called. If `undefined` is provided, it will default to
* a random seed.
*/
function getRandomFromWeightedArray(weightedArray, seedOrRNG) {
const randomIndex = getRandomIndexFromWeightedArray(weightedArray, seedOrRNG);
const randomElement = weightedArray[randomIndex];
(0, utils_1.assertDefined)(randomElement, `Failed to get an element from a weighted array using a random index of: ${randomIndex}`);
return randomElement[0];
}
/**
* Get a random index from a `WeightedArray`. (A `WeightedArray` is an array of tuples, where the
* first element in the tuple is a value, and the second element in the tuple is a float
* corresponding to the value's weight.)
*
* If you want to get an unseeded index, you must explicitly pass `undefined` to the `seedOrRNG`
* parameter.
*
* @param weightedArray The array to pick from.
* @param seedOrRNG The `Seed` or `RNG` object to use. If an `RNG` object is provided, the
* `RNG.Next` method will be called. If `undefined` is provided, it will default to
* a random seed.
*/
function getRandomIndexFromWeightedArray(weightedArray, seedOrRNG) {
if (weightedArray.length === 0) {
error("Failed to get a random index from a weighted array since the provided array was empty.");
}
const weights = weightedArray.map((tuple) => tuple[1]);
const totalWeight = (0, array_1.sumArray)(weights);
const randomWeight = (0, random_1.getRandomFloat)(0, totalWeight, seedOrRNG);
let weightAccumulator = 0;
for (const [i, tuple] of weightedArray.entries()) {
const [_element, weight] = tuple;
weightAccumulator += weight;
if (weightAccumulator >= randomWeight) {
return i;
}
}
error("Failed to get a random index from a weighted array.");
}