Support AI opponents in two-faction games
This commit is contained in:
1 parent
aa6f77372f
commit
b00d720e40
13 files changed
+395
-28
No files matched your search
@@ -25,6 +25,7 @@ function render(game: GameView, pendingEntry = false) {
|
||||
return renderToStaticMarkup(createElement(TwoPlayerControls, {
|
||||
game, disabled: pendingEntry, pendingEntry, entryRoom: game.code, entryProblem: '',
|
||||
retryDisabled: false, onModeChange: noop, onSwitch: noop, onAdd: noop, onRetry: noop,
|
||||
onAddBot: noop, onAddControlledBot: noop,
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -51,3 +52,53 @@ void test('an unresolved request stays visible with an explicit retry', () => {
|
||||
assert.match(html, /never retried automatically/);
|
||||
assert.match(html, /<select[^>]*disabled/);
|
||||
});
|
||||
|
||||
void test('host may add a computer opponent when the second controller slot is empty', () => {
|
||||
const game = {
|
||||
...base,
|
||||
players: [base.players[0]],
|
||||
twoPlayerControllers: { version: 1 as const, controllers: [{ id: 'a', seats: ['a'] }] },
|
||||
controlledFactionSeats: [{ id: 'a', name: 'Ali', faction: 'atreides' as const }],
|
||||
};
|
||||
const html = render(game);
|
||||
assert.match(html, /Add an AI player/);
|
||||
assert.match(html, /The AI plays each faction independently/);
|
||||
for (const difficulty of ['Easy', 'Medium', 'Hard', 'Brutal'])
|
||||
assert.match(html, new RegExp(`value="${difficulty}"`));
|
||||
assert.match(html, /value="harkonnen"/);
|
||||
assert.doesNotMatch(html, /<option[^>]*value="atreides"/);
|
||||
});
|
||||
|
||||
void test('host adds the second AI faction only for an incomplete AI controller', () => {
|
||||
const human = base.players[0];
|
||||
const ai = { ...base.players[1], bot: 'Hard' as const };
|
||||
const game = {
|
||||
...base,
|
||||
players: [human, ai],
|
||||
twoPlayerControllers: { version: 1 as const, controllers: [
|
||||
{ id: 'a', seats: ['a'] }, { id: 'b', seats: ['b'] },
|
||||
] },
|
||||
controlledFactionSeats: [{ id: 'a', name: 'Ali', faction: 'atreides' as const }],
|
||||
};
|
||||
const html = render(game);
|
||||
assert.match(html, /Player 2 \(AI\): Harkonnen/);
|
||||
assert.match(html, /Add the AI player’s second faction/);
|
||||
assert.match(html, /Add AI second faction/);
|
||||
assert.doesNotMatch(html, /<option[^>]*value="harkonnen"/);
|
||||
const nonHost = render({ ...game, me: 'b' });
|
||||
assert.doesNotMatch(nonHost, /Add AI second faction/);
|
||||
const complete = render({ ...game, twoPlayerControllers: { version: 1, controllers: [
|
||||
{ id: 'a', seats: ['a'] }, { id: 'b', seats: ['b', 'c'] },
|
||||
] } });
|
||||
assert.doesNotMatch(complete, /Add AI second faction/);
|
||||
});
|
||||
|
||||
void test('a human opponent does not expose controls to add an AI faction to their seat', () => {
|
||||
const game = {
|
||||
...base,
|
||||
twoPlayerControllers: { version: 1 as const, controllers: [
|
||||
{ id: 'a', seats: ['a', 'c'] }, { id: 'b', seats: ['b'] },
|
||||
] },
|
||||
};
|
||||
assert.doesNotMatch(render(game), /Add AI second faction|Add an AI player/);
|
||||
});
|
||||
Reference in new issue
Block a user