66 lines
3.8 KiB
TypeScript
66 lines
3.8 KiB
TypeScript
import assert from 'node:assert/strict';
|
|
import test from 'node:test';
|
|
import { applyAction, createGame, newPlayer, type Game } from '../game/engine';
|
|
import { baseDeck } from '../game/cards';
|
|
import { acquireDuke, createDukeVidal, DUKE_VIDAL_ID } from '../game/duke-vidal';
|
|
import { richeseCards } from '../game/richese-cards';
|
|
import { moritaniTerrorAssassinationPool } from '../game/moritani-terror-assassination';
|
|
import { createMoritaniDukeCaptureFixture, revealMoritaniTerrorVictim } from './fixture-moritani-duke-capture';
|
|
|
|
function mark(game: Game, marker: 'uncertain' | 'legacy') {
|
|
if (marker === 'uncertain') game.dukeCaptureUncertain = true;
|
|
else delete game.dukeCaptureUncertain;
|
|
}
|
|
|
|
/** Staged ordinary pre-battle source based on the Residual Poison review
|
|
* fixture. One real card and the one shared Duke are placed in their physical
|
|
* zones; native leader deaths are controlled so the random pool is singleton. */
|
|
function residual(victim: 'duke' | 'native'): Game {
|
|
let game = createGame('DUKERESIDUAL', newPlayer('r', 'Richese', 'richese'), false, ['choam']);
|
|
game.players.push(newPlayer('g', 'Guild', 'guild'), newPlayer('e', 'Emperor', 'emperor'));
|
|
Object.assign(game, {status:'playing',phase:6,turn:2,active:'r',order:['r','g','e'],storm:18,
|
|
deck:baseDeck(),richeseCache:richeseCards()});
|
|
for (const player of game.players) { player.hand = []; player.spice = 10; player.forces = {}; player.reserves = 20; }
|
|
for (const player of game.players.slice(0, 2)) { player.forces = {'arrakeen:10':2}; player.reserves = 18; }
|
|
const cache = game.richeseCache!, index = cache.findIndex(card => card.effect === 'residualPoison');
|
|
assert.ok(index >= 0); game.players[0].hand.push(cache.splice(index, 1)[0]);
|
|
const guild = game.players[1];
|
|
for (const leader of guild.leaders) { leader.dead = true; leader.deaths = 1; }
|
|
if (victim === 'native') { guild.leaders[0].dead = false; guild.leaders[0].deaths = 0; }
|
|
game.dukeVidal = acquireDuke(createDukeVidal(), 'g', 2, 'moritani');
|
|
if (victim === 'native') game.dukeVidal.leader.usedAt = 'carthag';
|
|
game = applyAction(game, 'r', {type:'chooseBattle', target:'g', territory:'arrakeen'});
|
|
return game;
|
|
}
|
|
|
|
for (const state of ['uncertain', 'legacy'] as const) {
|
|
void test(`public Moritani Terror Duke death resolves ${state} uncertainty`, () => {
|
|
const f = createMoritaniDukeCaptureFixture({terror:true});
|
|
mark(f.game, state);
|
|
const {after} = revealMoritaniTerrorVictim(f, DUKE_VIDAL_ID);
|
|
assert.equal(after.dukeVidal!.leader.dead, true);
|
|
assert.equal(after.dukeCaptureUncertain, false);
|
|
assert.ok(after.log.some(entry => entry.text.includes('Duke Prad Vidal was assassinated')));
|
|
});
|
|
|
|
void test(`Moritani Terror killing another leader preserves ${state} uncertainty`, () => {
|
|
const f = createMoritaniDukeCaptureFixture({terror:true});
|
|
mark(f.game, state);
|
|
const pool = moritaniTerrorAssassinationPool(f.game, f.captor);
|
|
const other = pool.find(leader => leader.id !== DUKE_VIDAL_ID); assert.ok(other);
|
|
const {after} = revealMoritaniTerrorVictim(f, other.id);
|
|
assert.equal(after.dukeCaptureUncertain, state === 'uncertain' ? true : undefined);
|
|
assert.equal(after.dukeVidal!.leader.dead, false);
|
|
});
|
|
|
|
for (const victim of ['duke', 'native'] as const) {
|
|
void test(`public Residual Poison ${victim} death ${victim === 'duke' ? 'resolves' : 'preserves'} ${state} uncertainty`, () => {
|
|
const game = residual(victim); mark(game, state);
|
|
const after = applyAction(game, 'r', {type:'card',card:'richese-residual-poison',target:'g',event:game.battle!.event});
|
|
assert.equal(after.dukeCaptureUncertain, victim === 'duke' ? false : state === 'uncertain' ? true : undefined);
|
|
assert.equal(after.dukeVidal!.leader.dead, victim === 'duke');
|
|
assert.equal(after.log.some(entry => entry.text.includes('Duke Prad Vidal was randomly selected')), victim === 'duke');
|
|
});
|
|
}
|
|
}
|