A hand forced by amnesia or paralysis still casts what it completes

The default cast was chosen only when a gesture was clicked, so a hand
bound to repeat its last gesture finished its spell and let it pass.
Defaults are now chosen at the start of every turn.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Eric WagonerandClaude Fable 5.1 committed 2026-09-22 16:07:21 -04:00
1 parent 0036eaf625
commit 527820ee95
2 files changed
+66 -2

No files matched your search

+51
View File
@@ -0,0 +1,51 @@
import { describe, expect, it } from 'vitest';
import { Duel } from './duel.svelte';
import { resolveTurn } from './resolve';
import { createGame, type GameState, type TurnInput } from './state';
import type { Gesture } from './spells';
const noop = (): TurnInput => ({ left: '-', right: '-', casts: [] });
/** A is one gesture from a lightning bolt and has just been struck by amnesia. */
function amnesiaBeforeLightning(): GameState {
let s = createGame({ A: 'You', B: 'Foe' }, 1);
const left = 'DFFD';
const foe = '-DPP';
for (let i = 0; i < 4; i++) {
s = resolveTurn(s, {
A: { ...noop(), left: left[i] as Gesture },
B: { ...noop(), left: foe[i] as Gesture, casts: i === 3 ? [{ hand: 'left', spellId: 'amnesia' }] : [] }
});
}
expect(s.wizards.A.constraints.amnesia).toBe(true);
return s;
}
describe('the duel store', () => {
it('casts the spell a forced repeat completes, without a click', () => {
const duel = new Duel(amnesiaBeforeLightning());
expect(duel.forced.left).toBe('D');
expect(duel.completions.main.left.map((c) => c.spell.id)).toContain('lightning_bolt');
expect(duel.sets.main.left.spellId).toBe('lightning_bolt');
expect(duel.ready).toBe(true);
duel.reveal();
expect(duel.foe.hp).toBe(10);
});
it('chooses a default cast at the start of the next turn as well', () => {
let s = createGame({ A: 'You', B: 'Foe' }, 1);
// A's left hand made D-F-F-D; B's amnesia lands as A makes the fourth gesture.
const left = 'DFFD';
const foe = '-DPP';
for (let i = 0; i < 3; i++) {
s = resolveTurn(s, { A: { ...noop(), left: left[i] as Gesture }, B: { ...noop(), left: foe[i] as Gesture } });
}
const duel = new Duel(s);
duel.choose('main', 'left', 'D');
duel.choose('main', 'right', '-');
// The bot is replaced by a scripted foe for this test: resolve directly, then hand the store the result.
const next = resolveTurn(s, { A: { ...noop(), left: 'D' }, B: { ...noop(), left: 'P', casts: [{ hand: 'left', spellId: 'amnesia' }] } });
const fresh = new Duel(next);
expect(fresh.sets.main.left.spellId).toBe('lightning_bolt');
});
});