1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859 |
- /**
- * Warning: Shufflers will alter the given array
- */
- class Shuffler<T> {
- private array : Array<T>;
- private position = 0;
- /**
- * Maybe use seeded random some day
- */
- private rng : () => number;
- public constructor (array : Array<T>, rng? : () => number) {
- this.rng = rng == undefined ? Math.random : rng;
- this.array = array;
- }
- public restart () {
- this.position = 0;
- }
- /**
- * Gets a random element from the Shuffler Array
- * Can be called repeatedly
- * When there are no more elements left, returns undefined
- * @returns {T}
- */
- public getOne () : T {
- // get a random element from this.position to (array.length - 1)
- // store it locally
- // switch it with array[this.position]
- // return it
- if (this.position >= this.array.length) {
- return undefined;
- }
- let randomIndex = Math.floor(this.rng() * (this.array.length - this.position)) + this.position;
- let localCopy = this.array[this.position];
- this.array[this.position] = this.array[randomIndex];
- this.array[randomIndex] = localCopy;
- return this.array[this.position++];
- }
- /**
- * There should be no reason to use this with the "getOne" code above.
- * @returns {T[]}
- */
- public getShuffled () : Array<T> {
- let array = this.array.slice(0);
- var m = array.length, t, i;
- while (m) {
- i = Math.floor(this.rng() * m--);
- t = array[m];
- array[m] = array[i];
- array[i] = t;
- }
- return array;
- }
- }
|