File size: 2,500 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
'use strict';

const assert = require('assert').strict;
const TeamGenerator = require('../../dist/data/cg-teams').default;

describe('[Gen 9] Computer-Generated Teams', () => {
	it.skip('should give all species 4 or fewer moves', () => {
		const generator = new TeamGenerator();
		const pool = generator.dex.species
			.all()
			.filter(s => s.exists && !(s.isNonstandard || s.isNonstandard === 'Unobtainable') && !s.nfe);
		for (const species of pool) {
			const set = generator.makeSet(species, { hazardSetters: {} });
			assert(set.moves.length <= 4, `Species ${species.name} has more than 4 moves (set=${JSON.stringify(set)})`);
			assert(new Set(set.moves).size === set.moves.length, `Species ${species.name} has duplicate moves (set=${JSON.stringify(set)})`);
		}
	});

	// Skipped since it includes randomness; useful for debugging though
	it.skip('should have an accurate weighted picker', () => {
		const generator = new TeamGenerator();
		const numTrials = 100000;
		let error = 0;
		let trials = 0;

		for (const choices of [
			[{ choice: 'a', weight: 1 }, { choice: 'b', weight: 2 }],
			[{ choice: 'a', weight: 1 }, { choice: 'b', weight: 1 }],
			[{ choice: 'a', weight: 30 }, { choice: 'b', weight: 2000 }, { choice: 'c', weight: 7 }],
			// a big test case with lots of different weight values
			[
				{ choice: 'a', weight: 1345 }, { choice: 'b', weight: 2013 }, { choice: 'c', weight: 3411 }, { choice: 'd', weight: 940 },
				{ choice: 'e', weight: 505 }, { choice: 'f', weight: 10148 }, { choice: 'g', weight: 7342 }, { choice: 'h', weight: 8403 },
				{ choice: 'i', weight: 9859 }, { choice: 'j', weight: 1042 }, { choice: 'k', weight: 1132 }, { choice: 'l', weight: 1200 },
			],
		]) {
			const results = {};
			for (let i = 0; i < numTrials; i++) {
				const res = generator.weightedRandomPick(choices.map(x => x.choice), c => choices.find(x => x.choice === c)?.weight || 0);
				// console.log(`"${res}"`);
				if (!results[res]) results[res] = 0;
				results[res]++;
			}

			let totalWeight = 0;
			for (const choice of choices) {
				totalWeight += choice.weight;
			}

			for (const [choice, count] of Object.entries(results)) {
				const c = choices.find(x => x.choice === choice);
				const expected = (c.weight / totalWeight) * numTrials;
				error += Math.abs(count - expected) / expected;
				trials++;
			}
		}

		const percentError = (error / trials) * 100;
		assert(percentError < 3, `Weighted picker error is too high: ${percentError.toFixed(1)}%`);
	});
});