75 lines
4.1 KiB
TypeScript
75 lines
4.1 KiB
TypeScript
import assert from 'node:assert/strict';
|
|
import test from 'node:test';
|
|
import { viewGame, type Game } from '../game/engine';
|
|
import { actAdvancedCharityOrder as act, advancedCharityOrderInventory as inventory,
|
|
advancedCharityOrderPlayer as player, allowAdvancedCharityOpening as allow,
|
|
createAdvancedCharityOrderFixture, passAdvancedCharityResponses as pass } from './fixture-advanced-charity-order';
|
|
|
|
let cached: ReturnType<typeof createAdvancedCharityOrderFixture> | undefined;
|
|
const source = () => cached ??= createAdvancedCharityOrderFixture();
|
|
|
|
/** Genuine Advanced CHOAM/Bene Gesserit setup, phase opening and original
|
|
* ordered Charity. Exchange one conserved physical Truthtrance into CHOAM's
|
|
* hand for an existing card; no wallet, order, response or promise is staged. */
|
|
function beforeAnswer() {
|
|
const f = source(); let game = allow(structuredClone(f.game));
|
|
const asker = player(game,'choam'), target = 'beneGesserit';
|
|
const index = game.deck.findIndex(card => card.effect === 'truthtrance'); assert.ok(index >= 0);
|
|
assert.ok(asker.hand.length > 0);
|
|
[asker.hand[0],game.deck[index]] = [game.deck[index],asker.hand[0]];
|
|
const truth = asker.hand[0].id;
|
|
assert.ok(player(game,target).spice >= 2);
|
|
assert.ok(game.charityOrder?.remaining.includes(target));
|
|
assert.deepEqual(inventory(game),f.original);
|
|
game = act(game,'choam',{type:'card',card:truth});
|
|
while (game.truthtrance?.stage === 'priority') {
|
|
const actor = game.players.find(candidate => !game.truthtrance!.passed.includes(candidate.id)); assert.ok(actor);
|
|
game = act(game,actor.id,{type:'truthPass'});
|
|
}
|
|
assert.equal(game.truthtrance?.stage,'ask');
|
|
game = act(game,'choam',{type:'truthAsk',question:{kind:'charity',target,turn:game.turn}});
|
|
assert.ok(viewGame(game,target).truthCharityAnswers?.includes('yes'));
|
|
game = act(game,target,{type:'truthAnswer',answer:'yes'});
|
|
const promise = viewGame(game,target).truthCharityPromises.find(row => row.answer); assert.ok(promise);
|
|
return {f,game,target,truth,event:promise.event};
|
|
}
|
|
|
|
function reachBeneGesserit(sourceGame:Game):Game {
|
|
let game = sourceGame;
|
|
for (let count = 0; game.charityOrder?.remaining[0] !== 'beneGesserit' && count < 4; count++) {
|
|
const actor = game.charityOrder?.remaining[0]; assert.ok(actor);
|
|
game = act(game,actor,{type:'ready'});
|
|
}
|
|
assert.equal(game.charityOrder?.remaining[0],'beneGesserit');
|
|
return game;
|
|
}
|
|
|
|
for (const cancel of [false,true]) void test(
|
|
`Advanced wealthy Bene Gesserit promised Charity retains its native ${cancel ? 'cancellation' : 'payment'} response`, () => {
|
|
const f = beforeAnswer(); let game = reachBeneGesserit(f.game);
|
|
const bgSpice = player(game,f.target).spice, choamSpice = player(game,'choam').spice;
|
|
const order = structuredClone(game.charityOrder), guide = viewGame(game,f.target).truthCharityGuide;
|
|
assert.ok(guide); assert.equal(guide.action.type,'charity');
|
|
game = act(game,f.target,guide.action);
|
|
assert.equal(game.response?.kind,'bgCharity');
|
|
assert.equal(game.response?.owner,f.target);
|
|
assert.deepEqual(game.charityOrder,order);
|
|
assert.equal(player(game,f.target).charityTurn,game.turn);
|
|
assert.equal(viewGame(game,f.target).truthCharityPromises.find(row => row.event === f.event)?.fulfilled,true);
|
|
assert.equal(player(game,f.target).spice,bgSpice);
|
|
if (cancel) {
|
|
assert.ok(player(game,'atreides').hand.some(card => card.id === f.f.karama));
|
|
game = act(game,'atreides',{type:'card',card:f.f.karama,mode:'cancel'});
|
|
} else game = pass(game);
|
|
assert.equal(game.response ?? null,null);
|
|
assert.deepEqual(game.charityOrder,order);
|
|
assert.equal(player(game,f.target).spice,bgSpice + (cancel ? 0 : 2));
|
|
assert.equal(player(game,'choam').spice,choamSpice - (cancel ? 0 : 2));
|
|
assert.equal(viewGame(game,f.target).truthCharityPromises.find(row => row.event === f.event)?.fulfilled,true);
|
|
assert.equal(player(game,f.target).charityTurn,game.turn);
|
|
game = act(game,f.target,{type:'ready'});
|
|
assert.ok(game.phase !== 2 || !game.charityOrder?.remaining.includes(f.target));
|
|
assert.deepEqual(inventory(game),f.f.original);
|
|
},
|
|
);
|