Connect canonical Moritani winning discs and queued Guild arrivals

This commit is contained in:
Quintine committed 2026-10-15 17:22:34 +11:00
1 parent a5a6db7868
commit 1cd7db7d0b
26 files changed
+1318 -148

No files matched your search

@@ -0,0 +1,87 @@
import assert from 'node:assert/strict';
import test from 'node:test';
import { viewGame, type Action } from '../game/engine';
import { leaders } from '../game/cards';
import {
FOREIGN_GHOLA_DISC, createMoritaniForeignGholaWinnerFixture,
rejectForeignGholaWinnerAction, revealMoritaniForeignGholaWitness,
} from './fixture-moritani-foreign-ghola-winner';
import { mixedE3MoritaniPlayer } from './fixture-mixed-e3-moritani-nexus';
/**
* The consumer-visible regression for one actual physical winning disc whose
* printed faction differs from the victorious player: a Guild native disc dies
* in original combat, Tleilaxu legally revives it as a foreign ghola, and that
* surviving disc then wins a real battle against Moritani. Before the played-
* disc registry admitted ordinary canonical identities independently of the
* winner’s faction, no private opportunity was produced at all.
*/
void test('a real Tleilaxu foreign ghola victory opens Moritani’s private loss choice against the opposing native Tleilaxu Traitor', () => {
const f = createMoritaniForeignGholaWinnerFixture();
assert.equal(mixedE3MoritaniPlayer(f.afterSetup, f.moritani).traitors.includes(f.target), true);
// Authentic acquisition: the disc really died and the return is a real action.
assert.equal(f.guildBattle.winner, f.tleilaxu);
assert.equal(mixedE3MoritaniPlayer(f.guildBattle.after, f.guild)
.leaders.find((l) => l.id === FOREIGN_GHOLA_DISC)!.dead, true);
assert.equal(mixedE3MoritaniPlayer(f.revival.after, f.tleilaxu).spice,
mixedE3MoritaniPlayer(f.revival.before, f.tleilaxu).spice - 3);
const borrowed = mixedE3MoritaniPlayer(f.window.game, f.guild).leaders.find(l => l.id === FOREIGN_GHOLA_DISC)!;
assert.equal(borrowed.dead, false);
assert.equal(borrowed.faction, 'guild');
assert.equal(borrowed.gholaBy, f.tleilaxu);
// The real window: the winning disc belongs to no Tleilaxu disc, yet the
// logical faction and target pool stay the victorious player’s printed one.
assert.equal(f.window.opposingLeader, FOREIGN_GHOLA_DISC);
assert.equal(f.window.faction, 'tleilaxu');
assert.notEqual(f.window.territory, f.guildBattle.territory);
assert.equal(f.window.opponent, f.tleilaxu);
assert.equal(f.window.blocked, null);
assert.equal(f.window.game.moritaniAssassinate!.normalTraitorCall, false);
assert.ok(f.window.cards.some((choice) => choice.card === f.target));
assert.equal(f.window.cards.every((choice) =>
leaders('tleilaxu').some((l) => l.id === choice.card)), true,
'Only the opposing player’s native Tleilaxu identities are targets.');
assert.equal(f.window.cards.some((choice) => choice.card === FOREIGN_GHOLA_DISC), false,
'The borrowed foreign disc never becomes a target identity.');
assert.equal(f.window.cards.find((choice) => choice.card === f.target)!.bounty, f.bounty);
// Original continuation: printed bounty, one physical death, Mentat replacement.
const outcome = revealMoritaniForeignGholaWitness(f);
assert.notEqual(outcome.replacement, f.target);
assert.equal(outcome.mentat.traitorReserve!.includes(outcome.replacement), false,
'The drawn replacement left the reserve for Moritani’s private hand.');
assert.equal(mixedE3MoritaniPlayer(outcome.mentat, f.moritani)
.traitors.includes(outcome.replacement), true);
assert.deepEqual(outcome.mentat.moritaniAssassinate!.opportunities.map((r) => r.stage),
['replaced']);
const ghola = mixedE3MoritaniPlayer(outcome.mentat, f.guild)
.leaders.find((l) => l.id === FOREIGN_GHOLA_DISC)!;
assert.equal(ghola.gholaBy, f.tleilaxu, 'The surviving foreign ghola stays in Tleilaxu custody.');
assert.equal(ghola.dead, false);
assert.equal(mixedE3MoritaniPlayer(outcome.mentat, f.tleilaxu)
.leaders.find((l) => l.id === f.target)!.dead, true, 'The revealed native Tleilaxu disc died.');
});
void test('the foreign-ghola window stays private and rejects any borrowed or foreign identity', () => {
const f = createMoritaniForeignGholaWinnerFixture();
const rival = viewGame(f.window.game, f.tleilaxu).moritaniAssassinate!;
assert.equal(rival.pending?.cards.length, 0);
assert.equal(rival.pending?.blocked, null);
const owner = viewGame(f.window.game, f.moritani).moritaniAssassinate!;
assert.equal(owner.history.length, 0, 'Nothing is public until the reveal actually commits.');
const foreign: Action = { type: 'decision', event: f.window.event, card: 'guild-1' };
rejectForeignGholaWinnerAction(f.window.game, f.moritani, foreign);
rejectForeignGholaWinnerAction(f.window.game, f.moritani,
{ type: 'decision', event: 'stale-foreign-ghola', card: f.target });
rejectForeignGholaWinnerAction(f.window.game, f.tleilaxu,
{ type: 'decision', event: f.window.event, card: f.target });
rejectForeignGholaWinnerAction(f.window.game, f.moritani,
{ type: 'decision', event: f.window.event, card: f.window.opposingLeader });
assert.equal(mixedE3MoritaniPlayer(f.window.game, f.tleilaxu)
.leaders.find((l) => l.id === f.target)!.dead, false,
'A rejected submission never kills the held target.');
});