import assert from 'node:assert/strict'; import { applyAction, handLimit, type Action, type Game } from '../game/engine'; import { SEMUTA_DRUG_ID } from '../game/semuta-drug'; import { createSemutaRevivalBenefitsForcesFixture, finishSemutaRevivalBenefitsForces, semutaRevivalBenefitsForcesInventory as inventory, semutaRevivalBenefitsForcesPlayer as player, } from './fixture-semuta-revival-benefits-forces'; export { inventory, player, finishSemutaRevivalBenefitsForces as finishRevival }; export const act = (game: Game, actor: string, action: Action) => applyAction(game, actor, action); /** Original public Basic source has a real paid cache Semuta, real shipment, * Storm casualties and CHOAM's actual three-force pending revival. This * supplement moves only original physical Semuta, Kull and a distinct Karama * among zones; no force, purse, quota, phase, response or request is installed. */ export function createKullRevivalSemutaFixture() { const source = createSemutaRevivalBenefitsForcesFixture({ kind: 'choamRevival', advanced: false }); const game = structuredClone(source.game); assert.ok(game.semutaPreview && game.kullPreview, 'Use the public Basic Kull and Semuta profile.'); const reactor = source.holder, holder = source.seller, actor = source.spender, counterOwner = source.atreides; const originalCards = inventory(game); const zones = [game.deck, game.discard, ...(game.richeseCache ? [game.richeseCache] : []), ...(game.richeseRemoved ? [game.richeseRemoved] : []), ...game.players.map(row => row.hand)]; const move = (id: string, destination: string) => { const zone = zones.find(cards => cards.some(card => card.id === id)); assert.ok(zone, `The original ${id} must occupy one physical zone.`); const [card] = zone.splice(zone.findIndex(candidate => candidate.id === id), 1); const receiver = player(game, destination); assert.ok(receiver.hand.length < handLimit(receiver), `The staged recipient ${destination} must have room.`); receiver.hand.push(card); }; move(SEMUTA_DRUG_ID, holder); move('ix-kull-wahad', reactor); const counter = zones.flat().find(card => card.effect === 'karama' && card.id !== source.cost && !card.id.startsWith('richese-')); assert.ok(counter, 'A second actual physical Karama must exist.'); move(counter.id, counterOwner); assert.ok(player(game, reactor).hand.some(card => card.id === 'ix-kull-wahad')); assert.ok(player(game, holder).hand.some(card => card.id === SEMUTA_DRUG_ID)); assert.ok(player(game, actor).hand.some(card => card.id === source.cost)); assert.ok(player(game, counterOwner).hand.some(card => card.id === counter.id)); assert.deepEqual(inventory(game), originalCards); assert.deepEqual(game.pendingRevival, source.pending); assert.deepEqual(game.response, source.originalResponse); return { game, source, originalCards, reactor, holder, actor, counterOwner, kull: 'ix-kull-wahad', karama: source.cost, counter: counter.id, semuta: SEMUTA_DRUG_ID }; }