Files
Dune/game/nexus-advisor-options.ts
T

75 lines
2.4 KiB
TypeScript

import type { Action, GameView } from './engine';
import { fighterCount } from './advisors';
export function nexusAdvisorCanAct(game: GameView): boolean {
const owner = game.players.find((player) => player.id === game.me);
return !!(
game.status === 'playing' &&
game.advanced &&
game.phase === 5 &&
game.active === game.me &&
owner?.faction === 'beneGesserit' &&
!owner.ally &&
game.nexusCards?.card === 'beneGesserit' &&
!game.automaticContinuationPending &&
!game.truthtrance &&
!game.response &&
!game.decision &&
!game.phaseOpening &&
!game.nexusCards.waiting.length &&
!game.nexusTraitors?.pending &&
!game.nexusAdvisors?.pending &&
game.nexusAdvisors?.offer &&
!game.nexusAdvisors.offer.blocked
);
}
/** Whole-territory legality and quantities come from the private server quote. */
export function nexusAdvisorAction(
game: GameView,
event: string,
territories: readonly string[],
): Action | null {
if (!nexusAdvisorCanAct(game)) return null;
const offer = game.nexusAdvisors!.offer!;
if (
!event ||
offer.event !== event ||
!territories.length ||
new Set(territories).size !== territories.length ||
!territories.every((territory) =>
offer.territories.some(
(choice) =>
choice.territory === territory &&
!choice.blocked &&
Number.isSafeInteger(choice.count) &&
choice.count > 0,
),
)
)
return null;
return { type: 'nexusAdvisors', event, territories: [...territories] };
}
/** Prefer publicly favorable battles, using no hidden cards or No-Field values.
* This is the shared legal policy, not a calibrated battle-strength estimate. */
export function nexusAdvisorBotActions(game: GameView): Action[] {
if (!nexusAdvisorCanAct(game)) return [];
const owner = game.players.find((player) => player.id === game.me)!;
const offer = game.nexusAdvisors!.offer!;
const territories = offer.territories
.filter((choice) => {
if (choice.blocked) return false;
const enemies = game.players
.filter((player) => player.id !== owner.id && player.id !== owner.ally)
.reduce(
(count, player) => count + fighterCount(player, choice.territory),
0,
);
return enemies > 0 && enemies < choice.count;
})
.map((choice) => choice.territory);
const action = nexusAdvisorAction(game, offer.event, territories);
return action ? [action] : [];
}