Files
ssessesse-ki-battle/tests/rules.test.ts
T

36 lines
1.8 KiB
TypeScript

import { test } from 'node:test';
import assert from 'node:assert/strict';
import { isLegalAction, resolveTurn } from '../src/shared/rules.js';
const actions = ['charge', 'blast', 'guard', 'beam', 'dodge'] as const;
const winners = [
[null, 1, null, 1, null],
[0, null, null, 1, null],
[null, null, null, 1, null],
[0, 0, 0, null, null],
[null, null, null, null, null],
];
for (let a = 0; a < 5; a++) for (let b = 0; b < 5; b++) {
test(`${actions[a]} / ${actions[b]} follows the agreed outcome table`, () => {
const result = resolveTurn([3, 3], [actions[a], actions[b]]) as { winnerIndex: number | null };
assert.equal(result.winnerIndex, winners[a][b]);
});
}
test('first turn allows only charge and guard; unknown actions are rejected', () => {
assert.equal(isLegalAction('charge', 0), true);
assert.equal(isLegalAction('guard', 0), true);
for (const action of ['blast', 'beam', 'dodge', 'fake']) assert.equal(isLegalAction(action, 0), false);
});
test('energy is spent on evasion and clashing attacks, and a hit cancels charging', () => {
assert.deepEqual(resolveTurn([3, 1], ['beam', 'dodge']), { energy: [0, 0], winnerIndex: null, hitIndex: null });
assert.deepEqual(resolveTurn([1, 0], ['blast', 'charge']), { energy: [0, 0], winnerIndex: 0, hitIndex: 1 });
assert.deepEqual(resolveTurn([1, 1], ['blast', 'blast']), { energy: [0, 0], winnerIndex: null, hitIndex: null });
assert.deepEqual(resolveTurn([0, 0], ['charge', 'charge']), { energy: [1, 1], winnerIndex: null, hitIndex: null });
assert.deepEqual(resolveTurn([0, 1], ['guard', 'dodge']), { energy: [0, 0], winnerIndex: null, hitIndex: null });
});
test('illegal actions cannot spend energy or mutate the input', () => {
const energy: [number, number] = [0, 0];
assert.throws(() => resolveTurn(energy, ['blast', 'charge']));
assert.deepEqual(energy, [0, 0]);
});