UNPKG

toosoon-prng-controllers

Version:

This project provides PRNG functions with a set of controllers for generating pseudo-random values using a seed-based approach

604 lines (603 loc) 16 kB
import prng from './prng'; /** * Utility abstract class for generating a pseudo-random values * * @class PRNGController * @abstract * @template {unknown} [T=unknown] */ export class PRNGController { /** * Seed string used for pseudo-random generations */ seed; /** * @param {Seed} seed Seed string used for pseudo-random generations */ constructor(seed) { this.seed = `${seed}`; prng.addController(this); } /** * Dispose this controller */ dispose() { prng.removeController(this); } } /** * Utility abstract class for managing multiple instances of controllers * * @class PRNGGroupController * @abstract * @template {unknown} [T=unknown] * @template {PRNGController<T>} [C=PRNGController<T>] */ export class PRNGGroupController { /** * Seed string used for pseudo-random generations */ seed; /** * Controllers managed by this group */ controllers = []; /** * @param {Seed} seed Seed string used for pseudo-random generations */ constructor(seed) { this.seed = `${seed}`; } /** * Generate a pseudo-random value * * @param {number} index Index of the controller to use * @returns {T} Generated pseudo-random value */ getValueAt(index) { let controller = this.controllers[index]; if (!controller) { controller = this.createController(index); this.controllers[index] = controller; } return controller.value; } /** * Dispose this group controllers */ dispose() { this.controllers.forEach((controller) => controller.dispose()); this.controllers = []; } } // ********************* // Controllers // ********************* /** * Utility class for generating pseudo-random boolean values * * @exports * @class BooleanController * @extends PRNGController */ export class BooleanController extends PRNGController { /** * Pseudo-random boolean value generated by this controller */ value; /** * Probability to get `true` */ probability; /** * @param {Seed} seed Seed string used for pseudo-random generations * @param {number} [probability=0.5] Probability to get `true` */ constructor(seed, probability = 0.5) { super(seed); this.probability = probability; this.value = this.getValue(); } getValue() { this.value = prng.randomBoolean(this.seed, this.probability); return this.value; } } /** * Utility class for generating pseudo-random sign values (-1 or 1) * * @exports * @class SignController * @extends PRNGController */ export class SignController extends PRNGController { /** * Pseudo-random sign value generated by this controller */ value; /** * Probability to get `1` */ probability; /** * @param {Seed} seed Seed string used for pseudo-random generations * @param {number} [probability=0.5] Probability to get `1` */ constructor(seed, probability = 0.5) { super(seed); this.probability = probability; this.value = this.getValue(); } getValue() { this.value = prng.randomSign(this.seed, this.probability); return this.value; } } /** * Utility class for generating pseudo-random floating-point numbers within a specified range * * @exports * @class FloatController * @extends PRNGController */ export class FloatController extends PRNGController { /** * Pseudo-random floating-point number value generated by this controller */ value; /** * Minimum boundary */ min; /** * Maximum boundary */ max; /** * @param {Seed} seed Seed string used for pseudo-random generations * @param {number} [min=0] Minimum boundary * @param {number} [max=1] Maximum boundary */ constructor(seed, min = 0, max = 1) { super(seed); this.min = min; this.max = max; this.value = this.getValue(); } getValue() { this.value = prng.randomFloat(this.seed, this.min, this.max); return this.value; } } /** * Utility class for generating pseudo-random integer numbers within a specified range * * @exports * @class IntController * @extends PRNGController */ export class IntController extends PRNGController { /** * Pseudo-random integer number value generated by this controller */ value; /** * Minimum boundary */ min; /** * Maximum boundary */ max; /** * @param {Seed} seed Seed string used for pseudo-random generations * @param {number} min Minimum boundary * @param {number} max Maximum boundary */ constructor(seed, min, max) { super(seed); this.min = min; this.max = max; this.value = this.getValue(); } getValue() { this.value = prng.randomInt(this.seed, this.min, this.max); return this.value; } } /** * Utility class for generating pseudo-random hexadecimal colors * * @exports * @class HexColorController * @extends PRNGController */ export class HexColorController extends PRNGController { /** * Pseudo-random hexadecimal color value generated by this controller */ value; /** * @param {Seed} seed Seed string used for pseudo-random generations */ constructor(seed) { super(seed); this.value = this.getValue(); } getValue() { this.value = prng.randomHexColor(this.seed); return this.value; } } /** * Utility class for pseudo-randomly picking an item from an array * * @exports * @class ItemController * @extends PRNGController<T> * @template {unknown} [T=unknown] */ export class ItemController extends PRNGController { /** * Item pseudo-randomly picked from the items array */ value; /** * Array of items to pseudo-randomly pick from */ items; /** * @param {Seed} seed Seed string used for pseudo-random generations * @param {T[]} items Array of items to pseudo-randomly pick from */ constructor(seed, items) { super(seed); this.items = items; this.value = this.getValue(); } getValue() { this.value = prng.randomItem(this.seed, this.items); return this.value; } } /** * Utility class for pseudo-randomly picking a property value from an object * * @exports * @class ObjectPropertyController * @extends PRNGController<T|undefined> * @template {unknown} [T=unknown] */ export class ObjectPropertyController extends PRNGController { /** * Property value pseudo-randomly picked from the object */ value; /** * Object to pseudo-randomly pick the property value from */ object; /** * @param {Seed} seed Seed string used for pseudo-random generations * @param {object} object Object to pseudo-randomly pick the property value from */ constructor(seed, object) { super(seed); this.object = object; this.value = this.getValue(); } getValue() { this.value = prng.randomObjectProperty(this.seed, this.object); return this.value; } } /** * Utility class for pseudo-randomly picking an item from an array of weighted items * * @exports * @class WeightsController * @extends PRNGController */ export class WeightsController extends PRNGController { /** * Item pseudo-randomly picked from the weighted items array */ value; /** * Array of weighted items to pseudo-randomly pick from */ items; /** * @param {Seed} seed Seed string used for pseudo-random generations * @param {WeightedItems<T>} items Array of weighted items to pseudo-randomly pick from */ constructor(seed, items) { super(seed); this.items = items; this.value = this.getValue(); } getValue() { const index = prng.randomIndex(this.seed, this.weights); this.value = this.items[index].value; return this.value; } /** * Array of weights */ get weights() { return this.items.map((item) => item.weight); } } /** * Utility class for generating pseudo-random numbers fitting a Gaussian (normal) distribution * * @exports * @class GaussianController * @extends PRNGController */ export class GaussianController extends PRNGController { /** * Pseudo-random number value generated by this controller */ value; /** * Mean (central) value of the distribution */ mean; /** * Spread (standard deviation) of the distribution */ spread; /** * @param {Seed} seed Seed string used for pseudo-random generations * @param {number} [mean=0] Mean (central) value of the distribution * @param {number} [spread=1] Spread (standard deviation) of the distribution */ constructor(seed, mean = 0, spread = 1) { super(seed); this.mean = mean; this.spread = spread; this.value = this.getValue(); } getValue() { this.value = prng.randomGaussian(this.seed, this.mean, this.spread); return this.value; } } // ********************* // Group Controllers // ********************* /** * Utility class for managing multiple {@link BooleanController} * * @exports * @class BooleanGroupController * @extends PRNGGroupController<boolean, BooleanController> */ export class BooleanGroupController extends PRNGGroupController { /** * Probability to get `true` */ probability; /** * @param {Seed} seed Seed string used for pseudo-random generations * @param {number} [probability=0.5] Probability to get `true` */ constructor(seed, probability = 0.5) { super(seed); this.probability = probability; } createController(index) { return new BooleanController(`${this.seed}${index}`, this.probability); } } /** * Utility class for managing multiple {@link SignController} * * @exports * @class SignGroupController * @extends PRNGGroupController<number, SignController> */ export class SignGroupController extends PRNGGroupController { /** * Probability to get `1` */ probability; /** * @param {Seed} seed Seed string used for pseudo-random generations * @param {number} [probability=0.5] Probability to get `1` */ constructor(seed, probability = 0.5) { super(seed); this.probability = probability; } createController(index) { return new SignController(`${this.seed}${index}`, this.probability); } } /** * Utility class for managing multiple {@link FloatController} * * @exports * @class FloatGroupController * @extends PRNGGroupController<number, FloatController> */ export class FloatGroupController extends PRNGGroupController { /** * Minimum boundary */ min; /** * Maximum boundary */ max; /** * @param {Seed} seed Seed string used for pseudo-random generations * @param {number} [min=0] Minimum boundary * @param {number} [max=1] Maximum boundary */ constructor(seed, min = 0, max = 1) { super(seed); this.min = min; this.max = max; } createController(index) { return new FloatController(`${this.seed}${index}`, this.min, this.max); } } /** * Utility class for managing multiple {@link IntController} * * @exports * @class IntGroupController * @extends PRNGGroupController<number, IntController> */ export class IntGroupController extends PRNGGroupController { /** * Minimum boundary */ min; /** * Maximum boundary */ max; /** * @param {Seed} seed Seed string used for pseudo-random generations * @param {number} min Minimum boundary * @param {number} max Maximum boundary */ constructor(seed, min, max) { super(seed); this.min = min; this.max = max; } createController(index) { return new IntController(`${this.seed}${index}`, this.min, this.max); } } /** * Utility class for managing multiple {@link HexColorController} * * @exports * @class HexColorGroupController * @extends PRNGGroupController<string, HexColorController> */ export class HexColorGroupController extends PRNGGroupController { // constructor(seed: Seed) { // super(seed); // } createController(index) { return new HexColorController(`${this.seed}${index}`); } } /** * Utility class for managing multiple {@link ItemController} * * @exports * @class ItemGroupController * @extends PRNGGroupController<T, ItemController<T>> * @template {unknown} [T=unknown] */ export class ItemGroupController extends PRNGGroupController { /** * Array of items to pseudo-randomly pick from */ items; /** * @param {Seed} seed Seed string used for pseudo-random generations * @param {T[]} items Array of items to pseudo-randomly pick from */ constructor(seed, items) { super(seed); this.items = items; } createController(index) { return new ItemController(`${this.seed}${index}`, this.items); } } /** * Utility class for managing multiple {@link ObjectPropertyController} * * @exports * @class ObjectPropertyGroupController * @extends PRNGGroupController<T|undefined, ObjectPropertyController<T>> * @template {unknown} [T=unknown] */ export class ObjectPropertyGroupController extends PRNGGroupController { /** * Object to pseudo-randomly pick the property value from */ object; /** * @param {Seed} seed Seed string used for pseudo-random generations * @param {object} object Object to pseudo-randomly pick the property value from */ constructor(seed, object) { super(seed); this.object = object; } createController(index) { return new ObjectPropertyController(`${this.seed}${index}`, this.object); } } /** * Utility class for managing multiple {@link WeightsController} * * @exports * @class WeightsGroupController * @extends PRNGGroupController<T, WeightsController<T>> * @template {unknown} [T=unknown] */ export class WeightsGroupController extends PRNGGroupController { /** * Array of weighted items to pseudo-randomly pick from */ items; /** * @param {Seed} seed Seed string used for pseudo-random generations * @param {WeightedItems<T>} items Array of weighted items to pseudo-randomly pick from */ constructor(seed, items) { super(seed); this.items = items; } createController(index) { return new WeightsController(`${this.seed}${index}`, this.items); } /** * Array of weights */ get weights() { return this.items.map((item) => item.weight); } } /** * Utility class for managing multiple {@link GaussianController} * * @exports * @class GaussianGroupController * @extends PRNGGroupController<number, GaussianController> */ export class GaussianGroupController extends PRNGGroupController { /** * Mean (central) value of the distribution */ mean; /** * Spread (standard deviation) of the distribution */ spread; /** * @param {Seed} seed Seed string used for pseudo-random generations * @param {number} [mean=0] Mean (central) value of the distribution * @param {number} [spread=1] Spread (standard deviation) of the distribution */ constructor(seed, mean = 0, spread = 1) { super(seed); this.mean = mean; this.spread = spread; } createController(index) { return new GaussianController(`${this.seed}${index}`, this.mean, this.spread); } }