내부 밸런스 비교 CLI와 조건별 대조 실험을 추가한다
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
import { test } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { readFile } from 'node:fs/promises';
|
||||
import { processBattleSimJob, parseUnitSetDefinition } from '../../packages/logic/dist/index.js';
|
||||
import { makePayload, observe } from './design.mjs';
|
||||
|
||||
const units = parseUnitSetDefinition(
|
||||
JSON.parse(await readFile(new URL('../../resources/unitset/unitset_che.json', import.meta.url), 'utf8'))
|
||||
);
|
||||
const cell = { unit: 1100, opponent: 1200, build: 'martial', role: 'attack', mode: 'field' };
|
||||
function run(payload, role = 'attack') {
|
||||
let observation;
|
||||
processBattleSimJob(payload, {
|
||||
onBattleResolved: (outcome) => {
|
||||
observation = observe(outcome, payload, role);
|
||||
},
|
||||
});
|
||||
assert.ok(observation);
|
||||
assert.ok(Object.values(observation).every((value) => value === null || Number.isFinite(value)));
|
||||
return observation;
|
||||
}
|
||||
test('actual engine is deterministic and leaves the input fixture immutable', () => {
|
||||
const payload = makePayload(units, cell, 'balance-test');
|
||||
const saved = structuredClone(payload);
|
||||
assert.deepEqual(run(payload), run(payload));
|
||||
assert.deepEqual(payload, saved);
|
||||
});
|
||||
test('neutral nation control is exactly equal, not just statistically similar', () => {
|
||||
const paired = { ...cell, nationTrait: 'che_중립' };
|
||||
assert.deepEqual(run(makePayload(units, paired, 's')), run(makePayload(units, paired, 's', false)));
|
||||
});
|
||||
test('same-unit mirror results reverse exchange and retain zero wall damage', () => {
|
||||
const mirror = { ...cell, opponent: 1100 };
|
||||
const attack = run(makePayload(units, mirror, 's'));
|
||||
const defend = run(makePayload(units, { ...mirror, role: 'defend' }, 's'), 'defend');
|
||||
assert.ok(Math.abs(attack.exchange + defend.exchange) < 1e-12);
|
||||
assert.equal(attack.wallDamage, 0);
|
||||
});
|
||||
test('real siege item is equipped and changes wall damage in the production action stack', () => {
|
||||
const siege = { ...cell, unit: 1501, build: 'command', mode: 'siege', generalPatch: { item: 'che_공성_묵자' } };
|
||||
const control = run(makePayload(units, { ...siege, wall: 5000 }, 'balance-test', false));
|
||||
const treatment = run(makePayload(units, { ...siege, wall: 5000 }, 'balance-test'));
|
||||
assert.equal(treatment.exchange, null);
|
||||
assert.ok(treatment.wallDamage > control.wallDamage);
|
||||
});
|
||||
Reference in New Issue
Block a user