100 lines
5.2 KiB
TypeScript
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);
|
|
});
|