UNPKG

gamekit-utils

Version:

Minimal, fast and useful utilities for randomness, array manipulation and math — built for games, UI logic and generative design.

125 lines (116 loc) 3.35 kB
/** * Returns a random element from an array. * Throws an error if the array is empty. * * @example * random([1, 2, 3]); // → 2 */ const random = (arr) => { if (!Array.isArray(arr)) { throw new TypeError("Expected an array"); } if (arr.length === 0) { throw new RangeError("Cannot select a random element from an empty array"); } const index = Math.floor(Math.random() * arr.length); return arr[index]; }; /** * Returns a new array with the same elements in random order (Fisher–Yates). * * Note: Only the array structure is copied. Objects inside are not cloned. * * @example * shuffle([1, 2, 3]); // → [2, 3, 1] */ const shuffle = (arr) => { const result = [...arr]; // shallow copy for (let i = result.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [result[i], result[j]] = [result[j], result[i]]; } return result; }; /** * Picks `n` unique random elements from the array. * * @throws if n > arr.length */ function pickN(arr, n) { if (!Array.isArray(arr)) { throw new TypeError("Expected an array"); } if (n > arr.length) { throw new RangeError("Cannot pick more elements than array contains"); } return shuffle(arr).slice(0, n); } /** * Returns true with the given percentage chance (0–100). * * @example * chance(25) // ~25% chance to return true */ function chance(percent) { if (typeof percent !== "number" || isNaN(percent)) { throw new TypeError("Chance percent must be a valid number"); } if (percent < 0 || percent > 100) { throw new RangeError("Chance percent must be between 0 and 100"); } return Math.random() < percent / 100; } /** * Clamps a number between min and max bounds. * * @example * clamp(5, 1, 10) // → 5 * clamp(-2, 0, 10) // → 0 * clamp(12, 0, 10) // → 10 */ function clamp(val, min, max) { if (min > max) { throw new RangeError("clamp: min cannot be greater than max"); } return Math.min(Math.max(val, min), max); } /** * Linearly interpolate between two values. * @param a The start value. * @param b The end value. * @param t The interpolation factor, clamped between 0 and 1. * @returns The interpolated value. */ function lerp(a, b, t) { return a + (b - a) * t; } /** * Normalizes a value t from the range [a, b] to [0, 1]. * * @param a The start of the range. * @param b The end of the range. * @param t The value to normalize. * @returns The normalized value in [0, 1]. * * @example * normalize(10, 20, 15) // → 0.5 * normalize(0, 100, 25) // → 0.25 */ function normalize(a, b, t) { if (a === b) throw new RangeError('normalize: a and b cannot be equal'); return (t - a) / (b - a); } /** * Creates a 2D array. * @param rows The number of rows. * @param cols The number of columns. * @param value The initial value or a function to generate values. * @returns A 2D array filled with the specified value. */ function create2D(rows, cols, value) { const isFn = typeof value === "function"; return Array.from({ length: rows }, (_, r) => Array.from({ length: cols }, (_, c) => isFn ? value(r, c) : value)); } export { chance, clamp, create2D, lerp, normalize, pickN, random, shuffle }; //# sourceMappingURL=index.js.map