Files
Dune/tests/great-maker-sneak-runtime.test.ts
T
Quintine 2ad7f127ec
Verify and publish checkpoint container / container (push) Canceled after 0s
Resolve Sneak arrivals during Great Maker rides
2026-10-29 19:59:10 +11:00

100 lines
5.2 KiB
TypeScript

import assert from 'node:assert/strict';
import test from 'node:test';
import { viewGame } from '../game/engine';
import { DIFFICULTIES } from '../game/bot-profiles';
import { botActions } from '../game/bots';
import { act, greatMakerSneakFixture, player } from './fixture-great-maker-sneak';
for (const withBG of [false,true]) void test(
`Advanced Great Maker Sneak resolves its own arrival ${withBG ? 'after BG' : 'without BG'} before completing the Maker`, () => {
const f = greatMakerSneakFixture(withBG, withBG);
let game = f.game;
assert.equal(viewGame(game,'moritani').terrorEntry?.sneakAttack?.blocked, null);
game = act(game,'moritani',{type:'decision',reveal:true});
assert.equal(game.pendingTerrorEntry?.stage,'sneakAttack');
for (const difficulty of DIFFICULTIES) {
const view = viewGame(game,'moritani');
view.players.find(row => row.id === 'moritani')!.bot = difficulty;
const choice = botActions(view)[0]; assert.ok(choice, difficulty);
assert.doesNotThrow(() => act(game,'moritani',choice), difficulty);
}
const reserves = player(game,'moritani').reserves;
const spice = player(game,'moritani').spice;
game = act(game,'moritani',{type:'decision',amount:1});
assert.equal(player(game,'moritani').reserves,reserves-1);
assert.equal(player(game,'moritani').forces[`${f.destination}:${f.sector}`],1);
assert.equal(player(game,'moritani').spice,spice);
assert.equal(player(game,'fremen').reserves,f.originalReserves-1);
if (withBG) {
assert.equal(game.greatMaker?.stage,'arrival');
assert.equal(game.decision?.kind,'advisor');
assert.equal(game.decision?.player,'beneGesserit');
game = act(game,'beneGesserit',{type:'decision',accept:false});
const child = game.pendingAmbassador; assert.ok(child);
assert.equal(child.token,f.ambassador);
assert.equal(child.entrant,'moritani');
assert.equal(game.greatMaker?.stage,'arrival');
game = act(game,'ecaz',{type:'decision',event:child.event,decline:true});
}
assert.equal(game.pendingSneakWorm ?? null,null);
assert.equal(game.pendingTerrorEntry ?? null,null);
assert.equal(game.pendingAmbassador ?? null,null);
assert.equal(game.greatMaker?.event,f.event);
assert.equal(game.greatMaker?.stage,'complete');
assert.equal(player(game,'fremen').reserves,f.originalReserves-1);
assert.equal(player(game,'moritani').reserves,reserves-1);
assert.equal(player(game,'moritani').forces[`${f.destination}:${f.sector}`],1);
});
void test('Advanced Great Maker Sneak choosing zero finishes without BG or a child entry', () => {
const f = greatMakerSneakFixture(true, true);
let game = act(f.game,'moritani',{type:'decision',reveal:true});
const reserves = player(game,'moritani').reserves;
game = act(game,'moritani',{type:'decision',amount:0});
assert.equal(player(game,'moritani').reserves,reserves);
assert.equal(game.pendingSneakWorm ?? null,null);
assert.equal(game.pendingTerrorEntry ?? null,null);
assert.equal(game.pendingAmbassador ?? null,null);
assert.notEqual(game.decision?.kind,'advisor');
assert.equal(game.greatMaker?.event,f.event);
assert.equal(game.greatMaker?.stage,'complete');
});
for (const first of ['terror','ambassador'] as const) void test(
`Advanced Great Maker ${first}-first overlap finishes both original owners before the Sneak child`, () => {
const f = greatMakerSneakFixture(false, true, 'emperor', first);
let game = f.game;
assert.equal(game.pendingArrivalOverlap?.first, first);
assert.equal(game.pendingArrivalOverlap?.resume, 'wormRide');
assert.equal(game.greatMaker?.stage, 'arrival');
if (first === 'ambassador') {
const original = game.pendingAmbassador; assert.ok(original);
assert.equal(original.entrant, 'fremen');
game = act(game,'ecaz',{type:'decision',event:original.event,decline:true});
}
assert.equal(game.pendingTerrorEntry?.token, f.sneak);
assert.equal(viewGame(game,'moritani').terrorEntry?.sneakAttack?.blocked, null);
game = act(game,'moritani',{type:'decision',reveal:true});
const reserves = player(game,'moritani').reserves;
game = act(game,'moritani',{type:'decision',amount:1});
assert.equal(game.greatMaker?.stage,'arrival');
if (first === 'terror') {
const original = game.pendingAmbassador; assert.ok(original);
assert.equal(original.entrant, 'fremen');
game = act(game,'ecaz',{type:'decision',event:original.event,decline:true});
}
const child = game.pendingAmbassador; assert.ok(child);
assert.equal(child.token, f.ambassador);
assert.equal(child.entrant, 'moritani');
assert.equal(game.greatMaker?.stage,'arrival');
game = act(game,'ecaz',{type:'decision',event:child.event,decline:true});
assert.equal(game.pendingSneakWorm ?? null,null);
assert.equal(game.pendingArrivalOverlap ?? null,null);
assert.equal(game.pendingAmbassador ?? null,null);
assert.equal(game.greatMaker?.event,f.event);
assert.equal(game.greatMaker?.stage,'complete');
assert.equal(player(game,'moritani').reserves,reserves-1);
assert.equal(player(game,'moritani').forces[`${f.destination}:${f.sector}`],1);
assert.equal(player(game,'fremen').reserves,f.originalReserves-1);
});