Files
Dune/tests/truth-turn-karama-forecast.test.ts
T

53 lines
3.3 KiB
TypeScript

import assert from 'node:assert/strict';
import test from 'node:test';
import { viewGame } from '../game/engine';
import { windowCardOpportunity } from '../game/window-card-play';
import { createTruthBidFixture, declareTruthBid, actTruthBid, truthBidInventory } from './fixture-truth-bid';
import { askTruthTurnKarama, settleTruthTurnKarama, truthTurnKaramaGroup, truthTurnKaramaPlay,
createTruthTurnKaramaFixture, bindTruthTurnKarama } from './fixture-truth-turn-karama';
void test('an unseen auction Hajr cannot fund a future card promise before its actual Karama acquisition', () => {
const f = createTruthBidFixture({ targetKarama: true, firstLotEffect: 'hajr', window: 'active' });
assert.equal(f.game.auction?.cards[0].effect, 'hajr');
assert.equal(viewGame(f.game, f.target).auction?.card, null);
const source = windowCardOpportunity(f.game, 'karamaAuction')!;
const mixed = truthTurnKaramaGroup('and', truthTurnKaramaPlay(source.source),
{ kind: 'action', action: { kind: 'cardPlay', effect: 'hajr' } });
let game = declareTruthBid(f).game;
game = askTruthTurnKarama(game, f.asker, f.target, mixed);
assert.deepEqual(viewGame(game, f.target).truthTurnActionAnswers, ['no']);
game = actTruthBid(game, f.target, { type: 'truthAnswer', answer: 'no' });
game = settleTruthTurnKarama(actTruthBid(game, f.target, { type: 'card', card: f.karama!, mode: 'purchase' }));
assert.ok(game.players.find(player => player.id === f.target)!.hand.some(card => card.effect === 'hajr'));
assert.deepEqual(truthBidInventory(game), f.originalCards);
// The actual acquisition makes the printed card owned knowledge. A second
// original Truth can now ask about the known remaining Movement play.
game = actTruthBid(game, f.asker, { type: 'card', card: f.truths[1] });
while (game.truthtrance?.stage === 'priority') {
const actor = game.players.find(player => !game.truthtrance!.passed.includes(player.id))!;
game = actTruthBid(game, actor.id, { type: 'truthPass' });
}
game = askTruthTurnKarama(game, f.asker, f.target,
{ kind: 'action', action: { kind: 'cardPlay', effect: 'hajr' } });
// The earlier No still forbids fulfilling the AND by that Hajr. It is the
// original binding, rather than lack of owned card knowledge, that applies.
assert.deepEqual(viewGame(game, f.target).truthTurnActionAnswers, ['no']);
let owned = settleTruthTurnKarama(actTruthBid(f.game, f.target, { type: 'card', card: f.karama!, mode: 'purchase' }));
owned = declareTruthBid(f, owned).game;
owned = askTruthTurnKarama(owned, f.asker, f.target,
{ kind: 'action', action: { kind: 'cardPlay', effect: 'hajr' } });
assert.ok(viewGame(owned, f.target).truthTurnActionAnswers?.includes('yes'),
'Actual ownership permits the native future play when no earlier answer forbids it');
});
void test('the last native pass cannot close an own unfulfilled printed Karama promise', () => {
const f = createTruthTurnKaramaFixture();
const game = bindTruthTurnKarama(f, 'yes', truthTurnKaramaPlay(f.source)).game;
assert.equal(game.auction?.active, f.target);
const before = structuredClone(game);
assert.throws(() => actTruthBid(game, f.target, { type: 'passBid' }), /Karama lot|Truthtrance/);
assert.deepEqual(game, before);
const played = settleTruthTurnKarama(actTruthBid(game, f.target, f.purchase));
assert.equal(played.turnActionPromises![0].fulfilled, true);
});