UNPKG

isaacscript-common

Version:

Helper functions and features for IsaacScript mods.

57 lines (56 loc) 2.69 kB
"use strict"; 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."); }