Support mixed Discovery decks with Leader Skills
Verify and publish checkpoint container / container (push) Canceled after 0s
Verify and publish checkpoint container / container (push) Canceled after 0s
This commit is contained in:
1 parent
7c1f4b4e09
commit
77eb2392eb
15 files changed
+420
-11
No files matched your search
@@ -0,0 +1,92 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import test from 'node:test';
|
||||
import { bureaucratPaymentModeSupported } from '../game/bureaucrat-payment';
|
||||
import { discoveryModeSupported, selectedDiscoveryLeaderSkillsProfile } from '../game/discovery-module-profile';
|
||||
import { selectedDiscoveryWithoutCardsProfile, type FactionModuleProfile } from '../game/faction-module-profile';
|
||||
import { advancedMoritaniLeaderSkillsProfile, basicMoritaniLeaderSkillsProfile,
|
||||
nativeDiscoveryLeaderSkillsProfile, nativeEcazLeaderSkillsProfile,
|
||||
ordinaryLeaderSkillModeSupported, strongholdLeaderSkillsProfile } from '../game/leader-skill-profile';
|
||||
|
||||
const base: FactionModuleProfile = {
|
||||
advanced: false,
|
||||
expansions: ['ix', 'choam', 'ecaz'],
|
||||
players: [{faction:'atreides'}, {faction:'guild'}, {faction:'emperor'}],
|
||||
discoveryEnabled: true,
|
||||
leaderSkills: {},
|
||||
};
|
||||
|
||||
void test('selected Discovery and Skills use the shared registered roster without requiring native seats', () => {
|
||||
const rows: FactionModuleProfile[] = [
|
||||
base,
|
||||
{...base, advanced:true},
|
||||
{...base, expansions:['ecaz'], players:[{faction:'atreides'}, {faction:'guild'}]},
|
||||
{...base, expansions:['ix', 'ecaz'], players:[{faction:'ixians'}, {faction:'guild'}]},
|
||||
{...base, players:[{faction:'ixians'}, {faction:'ecaz'}, {faction:'moritani'}]},
|
||||
{...base, players:[{faction:'ixians'}, {faction:'ecaz'}, {faction:'guild'}],
|
||||
discoveries:{}, discoveryStash:{}, greatMaker:{}, ecazOccupyPreview:true},
|
||||
{...base, advanced:true, players:[{faction:'moritani'}, {faction:'atreides'}, {faction:'guild'}],
|
||||
moritaniAssassinatePreview:true},
|
||||
{...base, advanced:true, homeworlds:{}, techTokens:{}, strongholdCards:{}},
|
||||
{...base, advanced:true, players:[{faction:'harkonnen'}, {faction:'ixians'}]},
|
||||
];
|
||||
for (const row of rows) {
|
||||
const label = JSON.stringify(row);
|
||||
assert.equal(selectedDiscoveryWithoutCardsProfile(row), true, label);
|
||||
assert.equal(selectedDiscoveryLeaderSkillsProfile(row), true, label);
|
||||
assert.equal(discoveryModeSupported(row), true, label);
|
||||
assert.equal(nativeDiscoveryLeaderSkillsProfile(row), true, label);
|
||||
assert.equal(ordinaryLeaderSkillModeSupported(row), true, label);
|
||||
assert.equal(bureaucratPaymentModeSupported(row), true, label);
|
||||
}
|
||||
// The pre-deal lobby has not allocated the physical Skills deck yet.
|
||||
const lobby: FactionModuleProfile = {...base, leaderSkills:undefined};
|
||||
assert.equal(selectedDiscoveryLeaderSkillsProfile(lobby), true);
|
||||
assert.equal(strongholdLeaderSkillsProfile({...base, advanced:true, strongholdCards:{}}), true);
|
||||
});
|
||||
|
||||
void test('selected Discovery Skills preserve native Ecaz and Moritani participation', () => {
|
||||
const pair = {...base, players:[{faction:'ecaz'}, {faction:'moritani'}, {faction:'guild'}]};
|
||||
assert.equal(nativeEcazLeaderSkillsProfile(pair), true);
|
||||
assert.equal(basicMoritaniLeaderSkillsProfile(pair), true);
|
||||
assert.equal(advancedMoritaniLeaderSkillsProfile(pair), false);
|
||||
const advanced = {...pair, advanced:true, moritaniAssassinatePreview:true};
|
||||
assert.equal(nativeEcazLeaderSkillsProfile(advanced), true);
|
||||
assert.equal(advancedMoritaniLeaderSkillsProfile(advanced), true);
|
||||
});
|
||||
|
||||
void test('selected Discovery Skills reject illegal seats, decks, overlays and phase-module prerequisites', () => {
|
||||
const rejected: FactionModuleProfile[] = [
|
||||
{...base, discoveryEnabled:false},
|
||||
{...base, expansions:[]},
|
||||
{...base, expansions:['ix', 'ix']},
|
||||
{...base, expansions:['ix', 'unknown']},
|
||||
{...base, players:[{faction:'atreides'}]},
|
||||
{...base, players:[{faction:'atreides'}, {faction:'atreides'}]},
|
||||
{...base, players:[{faction:'atreides'}, {faction:'unknown'}]},
|
||||
{...base, expansions:['ix'], players:[{faction:'choam'}, {faction:'atreides'}]},
|
||||
{...base, players:[{faction:'atreides'}, {faction:'guild'}], techTokens:{}},
|
||||
{...base, strongholdCards:{}},
|
||||
{...base, nexusCards:{}},
|
||||
{...base, ecazTreachery:true},
|
||||
{...base, semutaPreview:true},
|
||||
{...base, kullPreview:true},
|
||||
{...base, nexusKullPreview:true},
|
||||
{...base, guildBetrayalPreview:true},
|
||||
{...base, nexusIxianBetrayalPreview:true},
|
||||
{...base, moritaniAssassinatePreview:true},
|
||||
];
|
||||
for (const row of rejected) {
|
||||
const label = JSON.stringify(row);
|
||||
assert.equal(selectedDiscoveryWithoutCardsProfile(row), false, label);
|
||||
assert.equal(selectedDiscoveryLeaderSkillsProfile(row), false, label);
|
||||
}
|
||||
});
|
||||
|
||||
void test('Advanced trained Harkonnen with actual E3 native remains excluded', () => {
|
||||
for (const faction of ['ecaz', 'moritani']) {
|
||||
const players = [{faction:'harkonnen'}, {faction}];
|
||||
assert.equal(selectedDiscoveryLeaderSkillsProfile({...base, players}), true, faction);
|
||||
assert.equal(selectedDiscoveryLeaderSkillsProfile({...base, players, advanced:true}), false, faction);
|
||||
assert.equal(discoveryModeSupported({...base, players, advanced:true}), false, faction);
|
||||
}
|
||||
});
|
||||
Reference in new issue
Block a user