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 and various algorithms

452 lines (451 loc) 11.7 kB
import prng from './prng'; /** * Utility abstract class for generating pseudo-random values * * @class PRNGController * @abstract */ export class PRNGController { seed; gui; constructor(seed) { this.seed = `${seed}`; prng.addController(this); } addGUI(gui, params = {}) { this.gui = gui.addBinding(this, 'value', { label: this.seed, ...params }); return this.gui; } dispose() { prng.removeController(this); this.gui?.dispose(); } } /** * Utility abstract class for managing multiple instances of individual controllers * * @class PRNGGroupController * @abstract */ export class PRNGGroupController { seed; controllers = []; gui; guiParams; constructor(seed) { this.seed = `${seed}`; } addGUI(gui, params = {}) { this.gui = gui.addFolder({ title: this.seed, expanded: false, ...params }); this.guiParams = params; return this.gui; } getValueAt(index) { let controller = this.controllers[index]; if (!controller) { controller = this.createController(index); if (this.gui) { controller.addGUI(this.gui, { label: `${this.gui.title}-${index}`, ...this.guiParams }); } this.controllers[index] = controller; } return controller.value; } dispose() { this.controllers.forEach((controller) => controller.dispose()); this.controllers = []; this.gui?.dispose(); } } // ********************* // Controllers // ********************* /** * Utility class for generating pseudo-random boolean value * * @exports * @class BooleanController * @extends PRNGController */ export class BooleanController extends PRNGController { value; probability; constructor(seed, probability = 0.5) { super(seed); this.probability = probability; this.value = this.getValue(); } getValue() { this.value = prng.randomBoolean(this.seed, this.probability); this.gui?.refresh(); return this.value; } } /** * Utility class for generating pseudo-random sign value (-1 or 1) * * @exports * @class SignController * @extends PRNGController */ export class SignController extends PRNGController { value; probability; constructor(seed, probability = 0.5) { super(seed); this.probability = probability; this.value = this.getValue(); } addGUI(gui, params = {}) { return super.addGUI(gui, { options: [-1, 1], ...params }); } getValue() { this.value = prng.randomSign(this.seed, this.probability); this.gui?.refresh(); return this.value; } } /** * Utility class for generating pseudo-random floating-point number within a specified range * * @exports * @class FloatController * @extends PRNGController */ export class FloatController extends PRNGController { value; min; max; constructor(seed, min = 0, max = 1) { super(seed); this.min = min; this.max = max; this.value = this.getValue(); } addGUI(gui, { min, max, step = 0.01, ...params } = {}) { return super.addGUI(gui, { min, max, step, ...params }); } getValue() { this.value = prng.randomFloat(this.seed, this.min, this.max); this.gui?.refresh(); return this.value; } } /** * Utility class for generating pseudo-random integer number within a specified range * * @exports * @class IntController * @extends PRNGController */ export class IntController extends PRNGController { value; min; max; constructor(seed, min, max) { super(seed); this.min = min; this.max = max; this.value = prng.randomInt(this.seed, min, max); } addGUI(gui, { min, max, step = 1, ...params } = {}) { return super.addGUI(gui, { min, max, step, ...params }); } getValue() { this.value = prng.randomInt(this.seed, this.min, this.max); this.gui?.refresh(); return this.value; } } /** * Utility class for generating pseudo-random hexadecimal color * * @exports * @class HexColorController * @extends PRNGController */ export class HexColorController extends PRNGController { value; constructor(seed) { super(seed); this.value = this.getValue(); } addGUI(gui, { view = 'color', ...params } = {}) { return super.addGUI(gui, { view, ...params }); } getValue() { this.value = prng.randomHexColor(this.seed); this.gui?.refresh(); return this.value; } } /** * Utility class for picking a pseudo-random item from a given array * * @exports * @class ItemController * @extends PRNGController */ export class ItemController extends PRNGController { value; items; constructor(seed, items) { super(seed); this.items = items; this.value = this.getValue(); } addGUI(gui, params = {}) { return super.addGUI(gui, { options: this.items, ...params }); } getValue() { this.value = prng.randomItem(this.seed, this.items); this.gui?.refresh(); return this.value; } } /** * Utility class for picking a pseudo-random property value from a given object * * @exports * @class ObjectPropertyController * @extends PRNGController */ export class ObjectPropertyController extends PRNGController { value; object; constructor(seed, object) { super(seed); this.object = object; this.value = this.getValue(); } addGUI(gui, params = {}) { return super.addGUI(gui, { options: this.object, ...params }); } getValue() { this.value = prng.randomObjectProperty(this.seed, this.object); this.gui?.refresh(); return this.value; } } /** * Utility class for selecting a pseudo-random index from an array of weighted items * * @exports * @class WeightsController * @extends PRNGController */ export class WeightsController extends PRNGController { value; items; weights; constructor(seed, items) { super(seed); this.items = items; this.weights = this.items.map((item) => item.weight); this.value = this.getValue(); } addGUI(gui, params = {}) { return super.addGUI(gui, { options: this.items.map((item) => item.value), ...params }); } getValue() { const index = prng.randomIndex(this.seed, this.weights); this.value = this.items[index].value; this.gui?.refresh(); return this.value; } } /** * Utility class for generating a pseudo-random number fitting a Gaussian (normal) distribution * * @exports * @class GaussianController * @extends PRNGController */ export class GaussianController extends PRNGController { value; mean; spread; constructor(seed, mean = 0, spread = 1) { super(seed); this.mean = mean; this.spread = spread; this.value = this.getValue(); } addGUI(gui, { min = this.mean - this.spread, max = this.mean + this.spread, step, ...params } = {}) { return super.addGUI(gui, { min, max, step, ...params }); } getValue() { this.value = prng.randomGaussian(this.seed, this.mean, this.spread); this.gui?.refresh(); return this.value; } } // ********************* // Group Controllers // ********************* /** * Utility class for managing multiple `BooleanController` * * @exports * @class BooleanGroupController * @extends PRNGGroupController */ export class BooleanGroupController extends PRNGGroupController { probability; controllers = []; constructor(seed, probability) { super(seed); this.probability = probability; } createController(index) { return new BooleanController(`${this.seed}-${index}`, this.probability); } } /** * Utility class for managing multiple `SignController` * * @exports * @class SignGroupController * @extends PRNGGroupController */ export class SignGroupController extends PRNGGroupController { probability; controllers = []; constructor(seed, probability) { super(seed); this.probability = probability; } createController(index) { return new SignController(`${this.seed}-${index}`, this.probability); } } /** * Utility class for managing multiple `FloatController` * * @exports * @class FloatGroupController * @extends PRNGGroupController */ export class FloatGroupController extends PRNGGroupController { min; max; controllers = []; constructor(seed, min, max) { 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 `IntController` * * @exports * @class IntGroupController * @extends PRNGGroupController */ export class IntGroupController extends PRNGGroupController { min; max; controllers = []; 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 `HexColorController` * * @exports * @class HexColorGroupController * @extends PRNGGroupController */ export class HexColorGroupController extends PRNGGroupController { controllers = []; // constructor(seed: string | number) { // super(seed); // } createController(index) { return new HexColorController(`${this.seed}-${index}`); } } /** * Utility class for managing multiple `ItemController` * * @exports * @class ItemGroupController * @extends PRNGGroupController */ export class ItemGroupController extends PRNGGroupController { items; controllers = []; constructor(seed, items) { super(seed); this.items = items; } createController(index) { return new ItemController(`${this.seed}-${index}`, this.items); } } /** * Utility class for managing multiple `ObjectPropertyController` * * @exports * @class ObjectPropertyGroupController * @extends PRNGGroupController */ export class ObjectPropertyGroupController extends PRNGGroupController { object; controllers = []; constructor(seed, object) { super(seed); this.object = object; } createController(index) { return new ObjectPropertyController(`${this.seed}-${index}`, this.object); } } /** * Utility class for managing multiple `WeightsController` * * @exports * @class WeightsGroupController * @extends PRNGGroupController */ export class WeightsGroupController extends PRNGGroupController { items; controllers = []; constructor(seed, items) { super(seed); this.items = items; } createController(index) { return new WeightsController(`${this.seed}-${index}`, this.items); } } /** * Utility class for managing multiple `GaussianController` * * @exports * @class GaussianGroupController * @extends PRNGGroupController */ export class GaussianGroupController extends PRNGGroupController { controllers = []; mean; spread; 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); } }