45 lines
1.2 KiB
TypeScript
45 lines
1.2 KiB
TypeScript
// https://stackoverflow.com/a/424445 thanks my dude
|
|
|
|
export type State = number;
|
|
|
|
const M = 0x80000000;
|
|
const A = 1103515245;
|
|
const C = 12345;
|
|
|
|
export class Rand {
|
|
state: number;
|
|
|
|
constructor(state?: State) {
|
|
this.state = typeof state == 'number' && !isNaN(state) ?
|
|
state : Math.floor(Math.random() * (M - 1));
|
|
}
|
|
|
|
#next(): number { return this.state = (A * this.state + C) % M; }
|
|
|
|
#float(x?: number, y?: number): number {
|
|
const [lo, hi] =
|
|
x === undefined ? [0, 1] :
|
|
y === undefined ? [0, x] :
|
|
[Math.min(x, y), Math.max(x, y)];
|
|
|
|
return lo + this.#next() / (M - 1) * (hi - lo);
|
|
}
|
|
|
|
int(): number; // whole int32 range
|
|
int(x: number): number; // [0, x)
|
|
int(x: number, y: number): number; // [x, y)
|
|
int(x?: number, y?: number): number {
|
|
return x === undefined ? this.#next() : Math.floor(this.#float(x, y));
|
|
}
|
|
|
|
float(): number; // [0, 1)
|
|
float(x: number): number; // [0, x)
|
|
float(x: number, y: number): number; // [x, y)
|
|
float(x?: number, y?: number): number { return this.#float(x, y); }
|
|
|
|
choice<A>(array: A[]): A {
|
|
return array[this.int(0, array.length)]!;
|
|
}
|
|
|
|
boolean(): boolean { return this.float() > 0.5; }
|
|
}
|