import assert from 'node:assert/strict'; import test from 'node:test'; import { alliancePromiseModeSupported } from '../game/alliance-promises'; import { revivalPromiseModeSupported } from '../game/revival-promises'; import { leaderRevivalPromiseModeSupported } from '../game/leader-revival-promises'; import { revivalExpressionPromiseModeSupported } from '../game/revival-expression-promises'; import { createGame, joinGame, newPlayer, viewGame } from '../game/engine'; import { act, advance, clean, createKullRicheseSemutaFixture } from './fixture-kull-richese-semuta'; const profile = { advanced: false, expansions: ['choam', 'ix'], kullPreview: true, semutaPreview: true, players: [{faction:'choam'}, {faction:'richese'}, {faction:'emperor'}, {faction:'harkonnen'}], }; void test('Basic Richese admits each Revival family with and without printed Kull', () => { for (const quote of [revivalPromiseModeSupported, leaderRevivalPromiseModeSupported, revivalExpressionPromiseModeSupported]) { assert.equal(quote(profile), true); assert.equal(quote({...profile, kullPreview:false}), true); assert.equal(quote({...profile, expansions:['ix','choam']}), true); assert.equal(quote({...profile, expansions:['choam','ix','ecaz'], players:[...profile.players,{faction:'ecaz'},{faction:'moritani'}]}), true); for (const unsupported of [ {...profile, advanced:true}, {...profile, expansions:['choam']}, {...profile, expansions:['choam','ix','ix']}, {...profile, players:profile.players.filter(player=>player.faction!=='choam')}, {...profile, players:profile.players.filter(player=>player.faction!=='richese')}, {...profile, players:[...profile.players,{faction:'ecaz'}]}, {...profile, players:[...profile.players,{faction:'richese'}]}, ]) assert.equal(quote(unsupported),false); for (const key of ['homeworlds','nexusCards','leaderSkills','techTokens','strongholdCards', 'discoveryEnabled','nexusKullPreview','richeseBetrayalPreview','guildBetrayalPreview', 'nexusIxianReplacementPreview','nexusIxianBetrayalPreview','nexusHarkonnenBetrayalPreview', 'moritaniAssassinatePreview'] as const) assert.equal(quote({...profile,[key]:true}),false,key); } assert.equal(alliancePromiseModeSupported(profile),true); assert.equal(alliancePromiseModeSupported({...profile,kullPreview:false}),true); }); function assertRevivalTargets(game: ReturnType) { const view = viewGame(game,'emperor'); assert.ok(view.truthRevivalTargets.includes('harkonnen')); assert.ok(view.truthLeaderRevivalTargets.includes('harkonnen')); assert.ok(view.truthRevivalExpressionTargets.includes('harkonnen')); assert.ok(view.truthMixedRevivalTargets.includes('harkonnen')); assert.deepEqual(view.truthAllianceTargets,[]); } void test('a real Basic Kull and Richese start projects all Revival question families', () => { const {acquired} = createKullRicheseSemutaFixture(); assert.ok(acquired.kullPreview && acquired.semutaPreview); assert.equal(acquired.phase,3); assertRevivalTargets(acquired); }); void test('a real Basic Richese start with Kull switched off projects the same Revival questions', () => { let game = createGame('SEMUTAREVIVALSCOPE',newPlayer('choam','CHOAM','choam'),false,['choam','ix']); for (const id of ['richese','emperor','harkonnen'] as const) joinGame(game,newPlayer(id,id,id)); game = act(game,'choam',{type:'moduleOption',module:'kullPreview',enabled:false}); for (const seat of game.players) game = act(game,seat.id,{type:'ready'}); game = act(game,'choam',{type:'start'}); game = advance(game,state=>state.status==='playing' && clean(state)); assert.ok(!game.kullPreview); assert.equal(game.semutaPreview,true); assertRevivalTargets(game); });