feat: add label random and animations to web interface
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
const assert = require('node:assert/strict');
|
||||
const test = require('node:test');
|
||||
const { createTargetActivator } = require('../../data/target_interaction.js');
|
||||
const { createTargetActivator, detectFeedback, createReactionPicker } = require('../../data/target_interaction.js');
|
||||
|
||||
test('a single tap selects a target without firing', () => {
|
||||
const selected = [];
|
||||
@@ -47,3 +47,42 @@ test('out-of-turn or already-targeted cells cannot select or fire', () => {
|
||||
assert.equal(selected, 0);
|
||||
assert.equal(shots, 0);
|
||||
});
|
||||
|
||||
function gameState(version, boards, overrides = {}) {
|
||||
return { version, gameId: 7, phase: 'in_progress', turn: 'player1', winner: null, boards, ...overrides };
|
||||
}
|
||||
|
||||
test('feedback distinguishes a hit on the opponent from damage to the player', () => {
|
||||
const water = '0'.repeat(100);
|
||||
const opponentHit = `${water.slice(0, 12)}3${water.slice(13)}`;
|
||||
assert.equal(detectFeedback(gameState(1, [water, water]), gameState(2, [water, opponentHit]), 'player1').type, 'hit');
|
||||
assert.equal(detectFeedback(gameState(1, [water, water]), gameState(2, [opponentHit, water]), 'player1').type, 'damage');
|
||||
});
|
||||
|
||||
test('sinking and victory feedback take priority over ordinary cell changes', () => {
|
||||
const water = '0'.repeat(100);
|
||||
const sunk = `44${water.slice(2)}`;
|
||||
assert.equal(detectFeedback(gameState(1, [water, water]), gameState(2, [water, sunk]), 'player1').type, 'sunk');
|
||||
const finished = gameState(3, [water, sunk], { phase: 'finished', winner: 0 });
|
||||
assert.equal(detectFeedback(gameState(2, [water, water]), finished, 'player1').type, 'victory');
|
||||
assert.equal(detectFeedback(gameState(2, [water, water]), finished, 'player2').type, 'defeat');
|
||||
});
|
||||
|
||||
test('duplicate snapshots do not repeat rewards', () => {
|
||||
const water = '0'.repeat(100);
|
||||
assert.equal(detectFeedback(gameState(2, [water, water]), gameState(2, [water, water]), 'player1'), undefined);
|
||||
});
|
||||
|
||||
test('reaction picker avoids an immediate repeat for the same event', () => {
|
||||
const picker = createReactionPicker({ hit: ['one', 'two', 'three'] }, () => 0);
|
||||
assert.equal(picker('hit'), 'one');
|
||||
assert.equal(picker('hit'), 'two');
|
||||
assert.equal(picker('hit'), 'one');
|
||||
});
|
||||
|
||||
test('reaction picker handles single and missing catalogs', () => {
|
||||
const picker = createReactionPicker({ miss: ['splash'] }, () => 0.9);
|
||||
assert.equal(picker('miss'), 'splash');
|
||||
assert.equal(picker('miss'), 'splash');
|
||||
assert.equal(picker('unknown'), undefined);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user