Spaces:
Running
Running
File size: 5,069 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 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
'use strict';
const PRNG = require('../../../dist/sim/prng').PRNG;
const assert = require('../../assert');
const testSeed = 'sodium,00000001000000020000000300000004';
describe(`PRNG`, () => {
it("should always generate the same results off the same seed", () => {
const results = [];
const testAgainst = new PRNG(testSeed);
for (let i = 0; i < 100; i++) {
results.push(testAgainst.random());
}
for (let i = 0; i < 10; i++) {
const cur = new PRNG(testSeed);
for (let j = 0; j < results.length; j++) {
const n = cur.random();
assert(results[j] === n, `generation ${j} for seed ${testSeed} did not match (expected: ${results[j]}, got ${n})`);
}
}
});
describe(`randomChance(numerator=0, denominator=1)`, () => {
it(`should always return false`, () => {
const prng = new PRNG(testSeed);
for (let i = 0; i < 100; ++i) {
assert.equal(prng.randomChance(0, 1), false);
}
});
});
describe(`randomChance(numerator=1, denominator=1)`, () => {
it(`should always return true`, () => {
const prng = new PRNG(testSeed);
for (let i = 0; i < 100; ++i) {
assert.equal(prng.randomChance(1, 1), true);
}
});
});
describe(`randomChance(numerator=256, denominator=256)`, () => {
it(`should always return true`, () => {
const prng = new PRNG(testSeed);
for (let i = 0; i < 100; ++i) {
assert.equal(prng.randomChance(256, 256), true);
}
});
});
describe(`randomChance(numerator=1, denominator=2)`, () => {
it(`should return true 45-55% of the time`, () => {
const prng = new PRNG(testSeed);
let trueCount = 0;
for (let i = 0; i < 100; ++i) {
if (prng.randomChance(1, 2)) {
trueCount += 1;
}
}
assert.bounded(trueCount, [45, 55]);
});
it(`should be identical to (random(2) == 0)`, () => {
// This invariant is important for battle logs.
const coinPRNG = new PRNG(testSeed);
const numberPRNG = new PRNG(testSeed);
for (let i = 0; i < 10; ++i) {
assert.equal(numberPRNG.random(2) === 0, coinPRNG.randomChance(1, 2));
}
});
});
describe(`randomChance(numerator=217, denominator=256)`, () => {
it(`should return true 80%-90% of the time`, () => {
const prng = new PRNG(testSeed);
let trueCount = 0;
for (let i = 0; i < 100; ++i) {
if (prng.randomChance(217, 256)) {
trueCount += 1;
}
}
assert.bounded(trueCount, [80, 90]);
});
it(`should be identical to (random(256) < 217)`, () => {
// This invariant is important for battle logs.
const coinPRNG = new PRNG(testSeed);
const numberPRNG = new PRNG(testSeed);
for (let i = 0; i < 10; ++i) {
assert.equal(numberPRNG.random(256) < 217, coinPRNG.randomChance(217, 256));
}
});
});
describe(`sample`, () => {
it(`should throw for a zero-item array`, () => {
const prng = new PRNG(testSeed);
const items = [];
assert.throws(() => prng.sample(items), RangeError);
});
it(`should eventually throw for a very sparse array`, () => {
const prng = new PRNG(testSeed);
const items = [];
items[30] = 'hello!';
assert.throws(() => {
for (let i = 0; i < 100; ++i) {
prng.sample(items);
}
});
});
it(`should eventually throw for a somewhat sparse array`, () => {
const prng = new PRNG(testSeed);
const items = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K'];
delete items[9];
assert.throws(() => {
for (let i = 0; i < 100; ++i) {
prng.sample(items);
}
});
});
it(`should return the only item in a single-item array`, () => {
const item = {};
const prng = new PRNG(testSeed);
for (let i = 0; i < 10; ++i) {
const sample = prng.sample([item]);
assert.equal(sample, item);
}
});
it(`should return items with equal probability for a five-item array`, () => {
const items = ['a', 'b', 'c', 'd', 'e'];
const occurences = { a: 0, b: 0, c: 0, d: 0, e: 0 };
const prng = new PRNG(testSeed);
for (let i = 0; i < 1000; ++i) {
const sample = prng.sample(items);
occurences[sample] += 1;
}
assert.bounded(occurences.a, [170, 230]);
assert.bounded(occurences.b, [170, 230]);
assert.bounded(occurences.c, [170, 230]);
assert.bounded(occurences.d, [170, 230]);
assert.bounded(occurences.e, [170, 230]);
});
it(`should return items with weighted probability for a three-item array with duplicates`, () => {
const items = ['x', 'x', 'y'];
const occurences = { x: 0, y: 0 };
const prng = new PRNG(testSeed);
for (let i = 0; i < 100; ++i) {
const sample = prng.sample(items);
occurences[sample] += 1;
}
assert.bounded(occurences.x, [63, 71]);
assert.bounded(occurences.y, [29, 37]);
});
it(`should be identical to array[random(array.length)]`, () => {
// This invariant is important for battle logs.
const items = [{}, {}, {}, {}, {}, {}, {}, {}];
const samplePRNG = new PRNG(testSeed);
const randomIntegerPRNG = new PRNG(testSeed);
for (let i = 0; i < 10; ++i) {
assert.equal(items[randomIntegerPRNG.random(items.length)], samplePRNG.sample(items));
}
});
});
});
|