Preserve Hajr after another seat accepts a paid deal
This commit is contained in:
1 parent
6da6ff7f83
commit
3edebecc89
7 files changed
+115
-5
No files matched your search
@@ -0,0 +1,69 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import { test } from 'node:test';
|
||||
import { applyAction, viewGame, type Game } from '../game/engine';
|
||||
import {
|
||||
completeHajrReplay, createHajrReplayFixture, hajrReplayPlayer,
|
||||
} from './fixture-hajr-replay';
|
||||
|
||||
/** This reaches the native Advanced immediate-after-movement Hajr window via
|
||||
* setup, auction, shipment, actual Hajr play, Box recovery and movement. The
|
||||
* genuine fixture has spent its spice on those actions; only the payer's spice
|
||||
* is explicitly staged so this independent deal payment can be exercised. */
|
||||
function windowGame() {
|
||||
const fixture = createHajrReplayFixture({ advanced: true });
|
||||
const game = completeHajrReplay(fixture).beforeSecondHajr;
|
||||
const payer = game.players.find(player => player.id === fixture.owner)!;
|
||||
const recipient = game.players.find(player => player.id !== payer.id && !player.bot &&
|
||||
player.id !== payer.ally && player.ally !== payer.id);
|
||||
assert.ok(recipient);
|
||||
assert.equal(payer.spice, 0, 'The original purchases, shipment and Box consumed the fixture spice.');
|
||||
payer.spice = 4; // Controlled funding only; the native movement/window is not staged.
|
||||
assert.ok(payer.hajrWindow);
|
||||
assert.equal(available(game, payer.id), true);
|
||||
return { fixture, game, payer: payer.id, recipient: recipient.id };
|
||||
}
|
||||
|
||||
function available(game: Game, id: string) {
|
||||
return viewGame(game, id).players.find(player => player.id === id)!.hajrAvailable;
|
||||
}
|
||||
|
||||
function offer(game: Game, from: string, to: string, payer: string, recipient: string): Game {
|
||||
return applyAction(game, from, {
|
||||
type: 'dealOffer', target: to, terms: 'An immediate one-spice bribe.',
|
||||
payment: { kind: 'immediateBribe', payer, recipient, amount: 1 },
|
||||
});
|
||||
}
|
||||
|
||||
void test('another seat accepting a prior-consented payment preserves the payer’s native Hajr opportunity', () => {
|
||||
const { fixture, game: initial, payer, recipient } = windowGame();
|
||||
const window = structuredClone(hajrReplayPlayer(initial).hajrWindow);
|
||||
const beforeSpice = hajrReplayPlayer(initial).spice;
|
||||
const beforeBribes = initial.players.find(player => player.id === recipient)!.bribes;
|
||||
const offered = offer(initial, payer, recipient, payer, recipient);
|
||||
assert.deepEqual(hajrReplayPlayer(offered).hajrWindow, window);
|
||||
const deal = offered.deals!.at(-1)!;
|
||||
const paid = applyAction(offered, recipient, { type: 'dealRespond', deal: deal.id, accept: true });
|
||||
assert.equal(paid.deals!.at(-1)!.status, 'active');
|
||||
assert.equal(hajrReplayPlayer(paid).spice, beforeSpice - 1);
|
||||
assert.equal(paid.players.find(player => player.id === recipient)!.bribes, beforeBribes + 1);
|
||||
assert.deepEqual(hajrReplayPlayer(paid).hajrWindow, window);
|
||||
assert.equal(available(paid, payer), true);
|
||||
const played = applyAction(paid, payer, { type: 'card', card: fixture.hajr });
|
||||
assert.equal(hajrReplayPlayer(played).hajrPlays, 2);
|
||||
assert.equal(hajrReplayPlayer(played).spice, beforeSpice - 1);
|
||||
assert.equal(played.players.find(player => player.id === recipient)!.bribes, beforeBribes + 1);
|
||||
});
|
||||
|
||||
void test('the payer’s own voluntary bribe or final acceptance closes the immediate Hajr window', () => {
|
||||
const { game: initial, payer, recipient } = windowGame();
|
||||
const direct = applyAction(initial, payer, { type: 'bribe', target: recipient, amount: 1 });
|
||||
assert.equal(hajrReplayPlayer(direct).hajrWindow, undefined);
|
||||
assert.equal(available(direct, payer), false);
|
||||
|
||||
const offered = offer(initial, recipient, payer, payer, recipient);
|
||||
assert.equal(available(offered, payer), true);
|
||||
const accepted = applyAction(offered, payer, { type: 'dealRespond', deal: offered.deals!.at(-1)!.id, accept: true });
|
||||
assert.equal(hajrReplayPlayer(accepted).hajrWindow, undefined);
|
||||
assert.equal(available(accepted, payer), false);
|
||||
assert.equal(hajrReplayPlayer(accepted).spice, 3);
|
||||
});
|
||||
Reference in new issue
Block a user