Preserve Emperor gift opportunity before bot Extortion
Verify and publish checkpoint container / container (push) Successful in 10m54s
Verify and publish checkpoint container / container (push) Successful in 10m54s
This commit is contained in:
1 parent
a6be17fc5d
commit
7c1f4b4e09
13 files changed
+370
-13
No files matched your search
@@ -0,0 +1,89 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import test from 'node:test';
|
||||
import { viewGame } from '../game/engine';
|
||||
import { botActions, runBots } from '../game/bots';
|
||||
import { DIFFICULTIES } from '../game/bot-profiles';
|
||||
import { createExtortionBotPriority, extortionAct, extortionEvent, extortionPayment, extortionSeat,
|
||||
finishExtortionGiftResponse } from './emperor-extortion-bot-priority-fixture';
|
||||
|
||||
for (const advanced of [false, true]) for (const autopilot of [false, true]) void test(
|
||||
`${advanced ? 'Advanced' : 'Basic'} human Emperor gets Extortion gift priority before ${autopilot ? 'autopilot' : 'bot'} ally`, () => {
|
||||
const {game: initial} = createExtortionBotPriority(advanced, {autopilot});
|
||||
let game = initial;
|
||||
const event = extortionEvent(game);
|
||||
assert.deepEqual(viewGame(game, 'e').emperorExtortionPriority, {event, recipient:'a', canContinue:true});
|
||||
for (const id of ['a','h','m'])
|
||||
assert.deepEqual(viewGame(game, id).emperorExtortionPriority, {event, recipient:'a', canContinue:false});
|
||||
const e = extortionSeat(game, 'e').spice, a = extortionSeat(game, 'a').spice;
|
||||
for (const difficulty of DIFFICULTIES) {
|
||||
const view = viewGame(game, 'a');
|
||||
const actor = view.players.find(player => player.id === 'a')!;
|
||||
if (autopilot) actor.autopilot = difficulty; else actor.bot = difficulty;
|
||||
assert.ok(!botActions(view).some(action => action.type === 'decision' && action.event === event), difficulty);
|
||||
}
|
||||
const waiting = runBots(game, 5);
|
||||
assert.equal(waiting.decision?.kind, 'moritaniExtortion');
|
||||
assert.equal(extortionEvent(waiting), event);
|
||||
assert.equal(extortionSeat(waiting, 'e').spice, e);
|
||||
assert.equal(extortionSeat(waiting, 'a').spice, a);
|
||||
const original = structuredClone(game);
|
||||
assert.throws(() => extortionAct(game, 'a', extortionPayment(game, false)));
|
||||
assert.throws(() => extortionAct(game, 'a', {type:'emperorExtortionContinue', event}));
|
||||
assert.throws(() => extortionAct(game, 'e', {type:'emperorExtortionContinue', event:'stale'}));
|
||||
assert.deepEqual(game, original);
|
||||
game = extortionAct(game, 'e', {type:'emperorExtortionContinue', event});
|
||||
assert.ok(!viewGame(game, 'e').emperorExtortionPriority);
|
||||
assert.deepEqual(game.emperorExtortionGiftRelease, {event, emperor:'e', recipient:'a'});
|
||||
const action = botActions(viewGame(game, 'a')).find(row => row.type === 'decision' && row.event === event);
|
||||
assert.ok(action); assert.equal(action.pay, false);
|
||||
game = runBots(game, 1);
|
||||
assert.ok(game.decision?.kind !== 'moritaniExtortion' || game.decision.event !== event);
|
||||
});
|
||||
|
||||
for (const advanced of [false, true]) for (const canceled of [false, true]) void test(
|
||||
`${advanced ? 'Advanced' : 'Basic'} ${canceled ? 'canceled' : 'successful'} Emperor gift preserves priority until Continue`, () => {
|
||||
const fixture = createExtortionBotPriority(advanced);
|
||||
let game = fixture.game;
|
||||
const event = extortionEvent(game), emperor = extortionSeat(game, 'e').spice;
|
||||
game = extortionAct(game, 'e', {type:'emperorGift', amount:1});
|
||||
assert.equal(game.response?.kind, 'emperorGift');
|
||||
game = canceled ? extortionAct(game, 'h', {type:'card', card:fixture.karama, mode:'cancel'}) :
|
||||
finishExtortionGiftResponse(game);
|
||||
assert.equal(game.response, null);
|
||||
assert.equal(game.decision?.kind, 'moritaniExtortion');
|
||||
assert.equal(extortionEvent(game), event);
|
||||
assert.deepEqual(viewGame(game, 'e').emperorExtortionPriority, {event, recipient:'a', canContinue:true});
|
||||
assert.equal(extortionSeat(game, 'a').spice, canceled ? 2 : 3);
|
||||
assert.equal(extortionSeat(game, 'e').spice, emperor - (canceled ? 0 : 1));
|
||||
const before = runBots(game, 5);
|
||||
assert.equal(extortionEvent(before), event);
|
||||
game = extortionAct(game, 'e', {type:'emperorExtortionContinue', event});
|
||||
const action = botActions(viewGame(game, 'a')).find(row => row.type === 'decision' && row.event === event);
|
||||
// The current minimal bot policy declines even when it can afford to pay.
|
||||
assert.ok(action); assert.equal(action.pay, false);
|
||||
game = runBots(game, 1);
|
||||
assert.ok(game.decision?.kind !== 'moritaniExtortion' || game.decision.event !== event);
|
||||
assert.equal(game.moritaniTerror!.tokens.find(row => row.id === fixture.token)?.status, 'extortion');
|
||||
});
|
||||
|
||||
for (const advanced of [false, true]) void test(
|
||||
`${advanced ? 'Advanced' : 'Basic'} no-spice Emperor still has neutral Continue priority`, () => {
|
||||
const {game} = createExtortionBotPriority(advanced, {emperorSpice:0});
|
||||
const event = extortionEvent(game);
|
||||
assert.deepEqual(viewGame(game, 'e').emperorExtortionPriority, {event, recipient:'a', canContinue:true});
|
||||
assert.deepEqual(viewGame(game, 'a').emperorExtortionPriority, {event, recipient:'a', canContinue:false});
|
||||
assert.ok(!botActions(viewGame(game, 'a')).some(action => action.type === 'decision'));
|
||||
const continued = extortionAct(game, 'e', {type:'emperorExtortionContinue', event});
|
||||
assert.ok(botActions(viewGame(continued, 'a')).some(action => action.type === 'decision' && action.pay === false));
|
||||
});
|
||||
|
||||
for (const advanced of [false, true]) void test(
|
||||
`${advanced ? 'Advanced' : 'Basic'} unaffiliated bot pays or declines without Emperor priority`, () => {
|
||||
const {game} = createExtortionBotPriority(advanced, {unallied:true});
|
||||
const event = extortionEvent(game);
|
||||
assert.ok(!viewGame(game, 'e').emperorExtortionPriority);
|
||||
const action = botActions(viewGame(game, 'a')).find(row => row.type === 'decision' && row.event === event);
|
||||
assert.ok(action); assert.equal(action.pay, false);
|
||||
const next = runBots(game, 1);
|
||||
assert.ok(next.decision?.kind !== 'moritaniExtortion' || next.decision.event !== event);
|
||||
});
|
||||
Reference in new issue
Block a user