Spaces:
Running
Running
File size: 2,869 Bytes
5c2ed06 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
/**
* Battle Simulator multi random runner.
* Pokemon Showdown - http://pokemonshowdown.com/
*
* @license MIT
*/
import { PRNG, type PRNGSeed } from '../prng';
import { Runner, type RunnerOptions } from './runner';
export interface MultiRandomRunnerOptions extends Partial<RunnerOptions> {
totalGames: number;
prng?: PRNG | PRNGSeed | null;
format?: string;
cycle?: boolean;
all?: boolean;
async?: boolean;
}
export class MultiRandomRunner {
static readonly FORMATS = [
'gen8randombattle', 'gen8randomdoublesbattle', 'gen8battlefactory',
'gen7randombattle', 'gen7battlefactory',
'gen6randombattle', 'gen6battlefactory',
'gen5randombattle',
'gen4randombattle',
'gen3randombattle',
'gen2randombattle',
'gen1randombattle',
];
private readonly options: Partial<RunnerOptions>;
private readonly totalGames: number;
private readonly prng: PRNG;
private readonly format: string | undefined;
private readonly cycle: boolean;
private readonly all: boolean;
private readonly isAsync: boolean;
private formatIndex: number;
private numGames: number;
constructor(options: MultiRandomRunnerOptions) {
this.options = { ...options };
this.totalGames = options.totalGames;
this.prng = PRNG.get(options.prng);
this.options.prng = this.prng;
this.format = options.format;
this.cycle = !!options.cycle;
this.all = !!options.all;
this.isAsync = !!options.async;
this.formatIndex = 0;
this.numGames = 0;
}
async run() {
let games = [];
let format: string | false;
let lastFormat: string | false = false;
let failures = 0;
while ((format = this.getNextFormat())) {
if (this.all && lastFormat && format !== lastFormat) {
if (this.isAsync) await Promise.all(games);
games = [];
}
const seed = this.prng.getSeed();
const game = new Runner({ format, ...this.options }).run().catch(err => {
failures++;
console.error(
`Run \`node tools/simulate multi 1 --format=${format} --seed=${seed}\` ` +
`to debug (optionally with \`--output\` and/or \`--input\` for more info):\n`,
err
);
});
if (!this.isAsync) await game;
games.push(game);
lastFormat = format;
}
if (this.isAsync) await Promise.all(games);
return failures;
}
private getNextFormat() {
const FORMATS = MultiRandomRunner.FORMATS;
if (this.formatIndex > FORMATS.length) return false;
if (this.numGames++ < this.totalGames) {
if (this.format) {
return this.format;
} else if (this.all) {
return FORMATS[this.formatIndex];
} else if (this.cycle) {
const format = FORMATS[this.formatIndex];
this.formatIndex = (this.formatIndex + 1) % FORMATS.length;
return format;
} else {
return this.prng.sample(FORMATS);
}
} else if (this.all) {
this.numGames = 1;
this.formatIndex++;
return FORMATS[this.formatIndex];
}
return false;
}
}
|