64 lines
3.4 KiB
TypeScript
64 lines
3.4 KiB
TypeScript
import assert from 'node:assert/strict';
|
|
import test from 'node:test';
|
|
import { viewGame, type Action } from '../game/engine';
|
|
import type { TruthQuestion } from '../game/truthtrance';
|
|
import {
|
|
createTruthtranceRichesePromisesFixture as fixture,
|
|
actTruthtranceRichesePromises as act,
|
|
askTruthtranceRichesePromises as ask,
|
|
advanceTruthtranceRichesePromises as advance,
|
|
truthtranceRichesePromisesClean as clean,
|
|
truthtranceRichesePromisesPlayer as player,
|
|
truthtranceRichesePromisesInventory as inventory,
|
|
} from './fixture-truthtrance-richese-promises';
|
|
|
|
void test('a No-Field shipment guide preserves an earlier physical ground-movement Yes', () => {
|
|
const f = fixture({kind:'movement'}), source = structuredClone(f.game);
|
|
// Controlled conserved supplement: acquire the other original physical
|
|
// Truthtrance from the unopened deck, leaving every card in one location.
|
|
const at = source.deck.findIndex(card => card.effect === 'truthtrance');
|
|
assert.ok(at >= 0);
|
|
const extra = source.deck.splice(at, 1)[0];
|
|
player(source, f.asker).hand.push(extra);
|
|
assert.deepEqual(inventory(source), f.originalInventory);
|
|
|
|
let game = ask(source, f);
|
|
assert.ok(viewGame(game, f.target).truthMovementAnswers?.includes('yes'));
|
|
game = advance(act(game, f.target, {type:'truthAnswer', answer:'yes'}), clean);
|
|
game = act(game, f.asker, {type:'card', card:extra.id});
|
|
game = advance(game, state => state.truthtrance?.stage === 'ask');
|
|
const markerQuestion = {kind:'shipment', target:f.target,
|
|
claim:{kind:'noField', territory:'arrakeen', sector:10}} as unknown as TruthQuestion;
|
|
game = act(game, f.asker, {type:'truthAsk', question:markerQuestion});
|
|
assert.ok(viewGame(game, f.target).truthShipmentAnswers?.includes('yes'));
|
|
game = advance(act(game, f.target, {type:'truthAnswer', answer:'yes'}), clean);
|
|
game = advance(game, state => state.phase === 5 && state.active === f.target && clean(state));
|
|
assert.equal(game.movementPromises?.[0].answer, true);
|
|
assert.equal(game.shipmentPromises?.[0].answer, true);
|
|
assert.equal(game.movementPromises?.[0].released, undefined);
|
|
|
|
const first = viewGame(game, f.target).shipmentCompletion?.actions[0];
|
|
assert.equal(first?.type, 'ship');
|
|
assert.equal(typeof first.noField, 'string');
|
|
const selected = player(game).noField!.tokens.find(token => token.id === first.noField);
|
|
assert.ok(selected && selected.value >= 1, 'A zero marker cannot supply the promised physical movement');
|
|
const otherView = viewGame(game, f.asker);
|
|
assert.equal(otherView.shipmentCompletion, null);
|
|
assert.equal(otherView.richeseNoField?.private, null);
|
|
assert.equal(JSON.stringify(otherView).includes(first.noField as string), false);
|
|
|
|
game = advance(act(game, f.target, first), clean);
|
|
assert.equal(game.shipmentPromises![0].fulfilled, true);
|
|
// Follow the same private legal guidance to reveal the marker and move its
|
|
// actual physical forces; neither promise is satisfied by the marker alone.
|
|
for (let step = 0; !game.movementPromises![0].fulfilled && step < 4; step++) {
|
|
const next: Action | undefined = viewGame(game, f.target).movementPromisePolicy?.[0];
|
|
assert.ok(next, 'An owned completion must remain available after the shipment');
|
|
game = advance(act(game, f.target, next), clean);
|
|
}
|
|
assert.equal(game.movementPromises![0].fulfilled, true);
|
|
assert.equal(game.movementPromises![0].released, undefined);
|
|
assert.ok(player(game).forces['carthag:11'] >= 1);
|
|
assert.deepEqual(inventory(game), f.originalInventory);
|
|
});
|