Skip to content

Commit

Permalink
Fuck this
Browse files Browse the repository at this point in the history
  • Loading branch information
mia-pi-git committed Jan 8, 2025
1 parent 789cde0 commit c5ef777
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 34 deletions.
71 changes: 41 additions & 30 deletions sim/prng.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,26 +161,27 @@ export class PRNG {
}

// old, predictable PRNG. do not use this for anything but tests
export class TestPRNG extends PRNG {
_seed: PRNGSeed;
export class TestPRNG {
readonly initialSeed: PRNGSeed;
seed: PRNGSeed;
/** Creates a new source of randomness for the given seed. */
constructor(seed: PRNGSeed | null = null) {
super();
if (!seed) seed = PRNG.generateSeed();
this._seed = seed.slice() as PRNGSeed;
this.initialSeed = seed.slice() as PRNGSeed; // make a copy
this.seed = seed.slice() as PRNGSeed;
}

get startingSeed(): PRNGSeed {
return this.initialSeed;
}

clone(): PRNG {
return new PRNG(this.seed);
}

/**
* Retrieves the next random number in the sequence.
* This function has three different results, depending on arguments:
* - random() returns a real number in [0, 1), just like Math.random()
* - random(n) returns an integer in [0, n)
* - random(m, n) returns an integer in [m, n)
* m and n are converted to integers via Math.floor. If the result is NaN, they are ignored.
*/
next(from?: number, to?: number): number {
this._seed = this.nextFrame(this._seed); // Advance the RNG
let result = (this._seed[0] << 16 >>> 0) + this._seed[1]; // Use the upper 32 bits
this.seed = this.nextFrame(this.seed); // Advance the RNG
let result = (this.seed[0] << 16 >>> 0) + this.seed[1]; // Use the upper 32 bits
if (from) from = Math.floor(from);
if (to) to = Math.floor(to);
if (from === undefined) {
Expand All @@ -193,11 +194,32 @@ export class TestPRNG extends PRNG {
return result;
}

/**
* Calculates `a * b + c` (with 64-bit 2's complement integers)
*
* If you've done long multiplication, this is the same thing.
*/
randomChance(numerator: number, denominator: number): boolean {
return this.next(denominator) < numerator;
}

sample<T>(items: readonly T[]): T {
if (items.length === 0) {
throw new RangeError(`Cannot sample an empty array`);
}
const index = this.next(items.length);
const item = items[index];
if (item === undefined && !Object.prototype.hasOwnProperty.call(items, index)) {
throw new RangeError(`Cannot sample a sparse array`);
}
return item;
}

shuffle<T>(items: T[], start = 0, end: number = items.length) {
while (start < end - 1) {
const nextIndex = this.next(start, end);
if (start !== nextIndex) {
[items[start], items[nextIndex]] = [items[nextIndex], items[start]];
}
start++;
}
}

multiplyAdd(a: PRNGSeed, b: PRNGSeed, c: PRNGSeed) {
const out: PRNGSeed = [0, 0, 0, 0];
let carry = 0;
Expand All @@ -217,17 +239,6 @@ export class TestPRNG extends PRNG {
return out;
}

/**
* The RNG is a Linear Congruential Generator (LCG) in the form: `x_{n + 1} = (a x_n + c) % m`
*
* Where: `x_0` is the seed, `x_n` is the random number after n iterations,
*
* ````
* a = 0x5D588B656C078965
* c = 0x00269EC3
* m = 2^64
* ````
*/
nextFrame(seed: PRNGSeed, framesToAdvance = 1): PRNGSeed {
const a: PRNGSeed = [0x5D58, 0x8B65, 0x6C07, 0x8965];
const c: PRNGSeed = [0, 0, 0x26, 0x9EC3];
Expand Down
2 changes: 1 addition & 1 deletion sim/tools/exhaustive-runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import {ObjectReadWriteStream} from '../../lib/streams';
import {Dex, toID} from '../dex';
import {PRNG, PRNGSeed} from '../prng';
import {TestPRNG as PRNG, PRNGSeed} from '../prng';
import {RandomPlayerAI} from './random-player-ai';
import {AIOptions, Runner} from './runner';

Expand Down
2 changes: 1 addition & 1 deletion sim/tools/multi-random-runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* @license MIT
*/

import {PRNG, PRNGSeed} from '../prng';
import {TestPRNG as PRNG, PRNGSeed} from '../prng';
import {Runner, RunnerOptions} from './runner';

// @ts-ignore
Expand Down
2 changes: 1 addition & 1 deletion sim/tools/random-player-ai.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import {ObjectReadWriteStream} from '../../lib/streams';
import {BattlePlayer} from '../battle-stream';
import {PRNG, PRNGSeed} from '../prng';
import {TestPRNG as PRNG, PRNGSeed} from '../prng';

export class RandomPlayerAI extends BattlePlayer {
protected readonly move: number;
Expand Down
2 changes: 1 addition & 1 deletion sim/tools/runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {ObjectReadWriteStream} from '../../lib/streams';
import {Battle} from '../battle';
import * as BattleStreams from '../battle-stream';
import {State} from '../state';
import {PRNG, PRNGSeed} from '../prng';
import {TestPRNG as PRNG, PRNGSeed} from '../prng';
import {RandomPlayerAI} from './random-player-ai';

export interface AIOptions {
Expand Down

0 comments on commit c5ef777

Please sign in to comment.