Files
Dune/tests/fixture-semuta-shrine.ts
T

62 lines
3.3 KiB
TypeScript

import assert from 'node:assert/strict';
import {
applyAction, createGame, initializeSemutaGameForAudit, joinGame, newPlayer,
type Action, type Game,
} from '../game/engine';
import { SEMUTA_DRUG_ID } from '../game/semuta-drug';
import { nextSemutaGuildIncomeNativeStep } from './fixture-semuta-guild-income';
import { moveSemutaEmperorCard, semutaEmperorCardId } from './fixture-semuta-emperor-share';
export const shrinePlayer = (game: Game, id: string) => game.players.find(p => p.id === id)!;
export function semutaShrineLobby(advanced = true) {
let game = createGame('SEMUTASHRINE', newPlayer('r', 'Richese', 'richese'), advanced, ['choam']);
joinGame(game, newPlayer('e', 'Emperor', 'emperor'));
joinGame(game, newPlayer('g', 'Guild', 'guild'));
game.discoveryEnabled = true;
for (const player of game.players) game = applyAction(game, player.id, { type: 'ready' });
return game;
}
/** Original ready lobby/setup and first Movement; then CONTROLLED physical
* Shrine placement/occupation and conserved hand acquisition. Not an original
* Discovery draw/entry journey or full-game acceptance. */
export function createControlledSemutaShrine(advanced = true) {
let game = initializeSemutaGameForAudit(semutaShrineLobby(advanced));
for (const position of [0, 1]) {
const index = game.spiceDeck.findIndex((card, i) => i >= position && 'territory' in card && !card.discovery);
assert.ok(index >= position);
game.spiceDeck.splice(position, 0, game.spiceDeck.splice(index, 1)[0]);
}
for (let n = 0; n < 600; n++) {
if (game.phase === 5 && game.active === 'g' && !game.phaseOpening && !game.response && !game.decision) break;
const step = nextSemutaGuildIncomeNativeStep(game);
game = applyAction(game, step.actor, step.action);
}
assert.equal(game.phase, 5);
assert.ok(!game.response && !game.decision && !game.phaseOpening);
for (const player of game.players) game.deck.push(...player.hand.splice(0));
const shrine = game.discoveries!.tokens.find(token => token.face === 'shrine')!;
Object.assign(shrine, { status: 'placed', territory: 'gara_kulon', sector: 8, revealedTurn: game.turn });
shrinePlayer(game, 'e').reserves--;
shrinePlayer(game, 'e').forces['shrine:0'] = 1;
const truth = semutaEmperorCardId(game, card => card.effect === 'truthtrance');
const karama = semutaEmperorCardId(game, card => card.effect === 'karama');
moveSemutaEmperorCard(game, truth, 'e');
moveSemutaEmperorCard(game, karama, 'e');
moveSemutaEmperorCard(game, SEMUTA_DRUG_ID, 'r');
return { game, truth, karama, holder: 'r', owner: 'e',
provenance: 'CONTROLLED Shrine placement/occupation and conserved hand acquisition after genuine ready/setup/first Movement.' };
}
export function startShrineTruth(game: Game, karama: string): Game {
game = applyAction(game, 'e', { type: 'card', card: karama, shrineTruthtrance: [karama] });
while (game.truthtrance?.stage === 'priority') {
const actor = game.players.find(p => !game.truthtrance!.passed.includes(p.id))!;
game = applyAction(game, actor.id, { type: 'truthPass' });
}
const ask: Action = { type: 'truthAsk', question: { kind: 'fact', target: 'r',
fact: { kind: 'hand', name: 'Semuta Drug' } } };
game = applyAction(game, 'e', ask);
return applyAction(game, 'r', { type: 'truthAnswer', answer: 'yes' });
}