Resolve the high-threshold revival deployment question provisionally
This commit is contained in:
1 parent
504681db82
commit
048c8e60ff
12 files changed
+107
-64
No files matched your search
@@ -253,7 +253,7 @@ void test('Southern Ghola retires its physical card before choice and restores t
|
||||
}
|
||||
});
|
||||
|
||||
void test('low populations do not invent a deployment; first reaching high rejects ordinary and Ghola returns before payment or custody changes', () => {
|
||||
void test('low populations do not invent a deployment; a return that first reaches high stages its own redeployment choice', () => {
|
||||
for (const ghola of [false, true]) {
|
||||
let g = homeworldRevivalFixture();
|
||||
positionRevivalForces(g, 'f', { native: 1, tanks: 5, eliteTanks: 2 });
|
||||
@@ -267,12 +267,22 @@ void test('low populations do not invent a deployment; first reaching high rejec
|
||||
assert.equal(viewGame(low, 'f').homeworldRevivalDeployment, null);
|
||||
assert.equal(p(low, 'f').reserves, 2);
|
||||
stable(low);
|
||||
reject(g, 'f', { ...action, amount: 2 }, /timing ruling/);
|
||||
// The crossing return now qualifies under the provisional post-return
|
||||
// population policy and may redeploy instead of only returning to reserves.
|
||||
const crossing = applyAction(reload(g), 'f', { ...action, amount: 2 });
|
||||
assert.notEqual(crossing.homeworldRevivalReturn ?? null, null);
|
||||
assert.equal(viewGame(crossing, 'f').homeworldRevivalDeployment?.player, 'f');
|
||||
const placed = applyAction(reload(crossing), 'f', choice(crossing, 'f'));
|
||||
assert.equal(placed.homeworldRevivalReturn!.stage, 'complete');
|
||||
stable(placed);
|
||||
}
|
||||
let t = homeworldRevivalFixture({ tleilaxu: true });
|
||||
positionRevivalForces(t, 't', { native: 8, tanks: 5 });
|
||||
t = enterHomeworldRevival(t);
|
||||
reject(t, 't', { type: 'revive', amount: 1, elite: 0 }, /timing ruling/);
|
||||
const crossing = applyAction(reload(t), 't', { type: 'revive', amount: 1, elite: 0 });
|
||||
assert.notEqual(crossing.homeworldRevivalReturn ?? null, null);
|
||||
assert.equal(viewGame(crossing, 't').homeworldRevivalDeployment?.player, 't');
|
||||
stable(applyAction(reload(crossing), 't', choice(crossing, 't')));
|
||||
const card = holdRevivalCard(t, 't', 'ghola');
|
||||
const done = applyAction(t, 't', { type: 'card', card, amount: 2, elite: 0 });
|
||||
assert.equal(
|
||||
@@ -348,35 +358,25 @@ void test('real deployment projections expose destinations only to their owner a
|
||||
}
|
||||
});
|
||||
|
||||
void test('every bot profile avoids actual low-to-high ordinary and Ghola star returns while the shared block permits a leader return', () => {
|
||||
void test('every bot profile uses legal returns across the low-to-high crossing and the shared block permits a leader return', () => {
|
||||
for (const advanced of [false, true]) {
|
||||
let g = homeworldRevivalFixture({ advanced });
|
||||
positionRevivalForces(g, 'f', { native: 2, tanks: 3, eliteTanks: 3 });
|
||||
g = enterHomeworldRevival(g);
|
||||
const ghola = holdRevivalCard(g, 'f', 'ghola');
|
||||
const ownView = viewGame(g, 'f');
|
||||
assert.match(
|
||||
homeworldRevivalActionBlock(ownView, {
|
||||
type: 'revive',
|
||||
amount: 1,
|
||||
elite: 1,
|
||||
})!,
|
||||
/timing ruling/,
|
||||
);
|
||||
if (!advanced)
|
||||
assert.match(
|
||||
homeworldRevivalActionBlock(ownView, { type: 'card', card: ghola })!,
|
||||
/timing ruling/,
|
||||
// A return that itself reaches the high side is now legal under the
|
||||
// provisional post-return population policy.
|
||||
for (const action of [
|
||||
{ type: 'revive', amount: 1, elite: 1 },
|
||||
{ type: 'card', card: ghola, amount: 1, elite: 1 },
|
||||
{ type: 'card', card: ghola, amount: 1 },
|
||||
] as Action[])
|
||||
assert.equal(
|
||||
homeworldRevivalActionBlock(ownView, action),
|
||||
null,
|
||||
JSON.stringify(action),
|
||||
);
|
||||
assert.match(
|
||||
homeworldRevivalActionBlock(ownView, {
|
||||
type: 'card',
|
||||
card: ghola,
|
||||
amount: 1,
|
||||
})!,
|
||||
/timing ruling/,
|
||||
);
|
||||
reject(g, 'f', { type: 'card', card: ghola, amount: 1 }, /timing ruling/);
|
||||
for (const profile of ['Easy', 'Medium', 'Hard', 'Brutal'] as const) {
|
||||
const view = viewGame(reload(g), 'f');
|
||||
view.players.find((player) => player.id === 'f')!.bot = profile;
|
||||
@@ -385,13 +385,6 @@ void test('every bot profile avoids actual low-to-high ordinary and Ghola star r
|
||||
actions.length,
|
||||
`${profile} must retain a legal way to advance.`,
|
||||
);
|
||||
assert.ok(
|
||||
actions.every(
|
||||
(action) =>
|
||||
action.type !== 'revive' &&
|
||||
!(action.type === 'card' && action.card === ghola),
|
||||
),
|
||||
);
|
||||
for (const action of actions) {
|
||||
assert.equal(homeworldRevivalActionBlock(view, action), null);
|
||||
const next = applyAction(reload(g), 'f', action);
|
||||
|
||||
Reference in new issue
Block a user