Implement Bene Gesserit Nexus advisor conversion with durable responses
This commit is contained in:
1 parent
40912498b1
commit
b05125de9a
23 files changed
+2298
-16
No files matched your search
@@ -0,0 +1,91 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { applyAction, viewGame } from '../game/engine';
|
||||
import { DIFFICULTIES } from '../game/bot-profiles';
|
||||
import { botActions } from '../game/bots';
|
||||
import { nexusAdvisorBotActions } from '../game/nexus-advisor-options';
|
||||
import {
|
||||
nexusAdvisorFixture,
|
||||
nexusAdvisorInventory,
|
||||
beginNexusAdvisorFlip,
|
||||
allowNexusAdvisorFlip,
|
||||
holdAdvisorKarama,
|
||||
} from './fixture-nexus-advisors';
|
||||
|
||||
void test('all profiles announce favorable whole advisor groups and settle one conserved real conversion', () => {
|
||||
const initial = nexusAdvisorFixture();
|
||||
for (const difficulty of DIFFICULTIES) {
|
||||
const v = viewGame(initial, 'p');
|
||||
v.players[0].bot = difficulty;
|
||||
const before = structuredClone(v);
|
||||
const actions = botActions(v);
|
||||
assert.equal(actions.length, 1);
|
||||
assert.equal(actions[0].type, 'nexusAdvisors');
|
||||
assert.deepEqual([...(actions[0].territories as string[])].sort(), [
|
||||
'arrakeen',
|
||||
'pasty_mesa',
|
||||
]);
|
||||
assert.deepEqual(v, before);
|
||||
const g = allowNexusAdvisorFlip(applyAction(initial, 'p', actions[0]));
|
||||
assert.equal(g.players[0].advisors?.arrakeen, undefined);
|
||||
assert.equal(g.players[0].advisors?.pasty_mesa, undefined);
|
||||
assert.ok(g.players[0].advisors?.carthag);
|
||||
assert.deepEqual(g.players[0].forces, initial.players[0].forces);
|
||||
assert.equal(g.players[0].spice, initial.players[0].spice);
|
||||
assert.equal(g.players[0].moved, initial.players[0].moved);
|
||||
assert.equal(g.players[0].shipped, initial.players[0].shipped);
|
||||
nexusAdvisorInventory(g);
|
||||
}
|
||||
});
|
||||
|
||||
void test('advisor policy respects blocked groups and uses only public fighter presence', () => {
|
||||
const v = viewGame(nexusAdvisorFixture(), 'p');
|
||||
v.players[0].bot = 'Brutal';
|
||||
const offer = v.nexusAdvisors!.offer!;
|
||||
offer.territories.find((t) => t.territory === 'arrakeen')!.blocked =
|
||||
'Fresh advisor conversion awaits its ruling.';
|
||||
for (const player of v.players)
|
||||
for (const key of ['hand', 'traitors', 'faceDancers', 'spice'])
|
||||
Object.defineProperty(player, key, {
|
||||
get() {
|
||||
throw new Error(`Private ${key} read`);
|
||||
},
|
||||
});
|
||||
assert.deepEqual(nexusAdvisorBotActions(v)[0]?.territories, ['pasty_mesa']);
|
||||
v.players[1].forces['pasty_mesa:5'] = 10;
|
||||
assert.deepEqual(nexusAdvisorBotActions(v), []);
|
||||
v.players[1].forces = {};
|
||||
assert.deepEqual(nexusAdvisorBotActions(v), []);
|
||||
Object.defineProperty(v.players[1], 'noField', {
|
||||
value: {
|
||||
deployed: {
|
||||
location: { territory: 'pasty_mesa', sector: 5 },
|
||||
get value() {
|
||||
throw new Error('Read No-Field denomination');
|
||||
},
|
||||
get tokenId() {
|
||||
throw new Error('Read No-Field identity');
|
||||
},
|
||||
},
|
||||
get tokens() {
|
||||
throw new Error('Read private No-Field inventory');
|
||||
},
|
||||
},
|
||||
});
|
||||
assert.deepEqual(nexusAdvisorBotActions(v)[0]?.territories, ['pasty_mesa']);
|
||||
});
|
||||
|
||||
void test('response bots use the ordinary whole-use Karama controls when their fighters are threatened', () => {
|
||||
const initial = nexusAdvisorFixture();
|
||||
const card = holdAdvisorKarama(initial);
|
||||
const g = beginNexusAdvisorFlip(initial, ['arrakeen', 'pasty_mesa']);
|
||||
for (const difficulty of DIFFICULTIES) {
|
||||
const v = viewGame(g, 'q');
|
||||
v.players.find((p) => p.id === 'q')!.bot = difficulty;
|
||||
const action = botActions(v)[0];
|
||||
assert.ok(action);
|
||||
if (difficulty === 'Easy' || difficulty === 'Medium')
|
||||
assert.deepEqual(action, { type: 'passResponse' });
|
||||
else assert.deepEqual(action, { type: 'card', card, mode: 'cancel' });
|
||||
}
|
||||
});
|
||||
Reference in new issue
Block a user