import { Creature } from './creature' import { Encounter } from './combat' import { LogEntry } from './interface' import { ReleaseAction, TransferAction } from './combat/actions' export interface AI { name: string; decide (actor: Creature, encounter: Encounter): LogEntry; } export class NoAI implements AI { name = "No AI" decide (actor: Creature, encounter: Encounter): LogEntry { throw new Error("This AI cannot be used.") } } /** * The RandomAI is **COMPLETELY** random. Good luck. */ export class RandomAI implements AI { name = "Random AI" decide (actor: Creature, encounter: Encounter): LogEntry { const actions = encounter.combatants.flatMap(enemy => actor.validActions(enemy).map(action => ({ target: enemy, action: action }))) const chosen = actions[Math.floor(Math.random() * actions.length)] return chosen.action.execute(actor, chosen.target) } } /** * The VoreAI tries to perform moves from its containers */ export class VoreAI extends RandomAI { name = "Vore AI" decide (actor: Creature, encounter: Encounter): LogEntry { const actions = encounter.combatants.flatMap(enemy => actor.validActions(enemy).map(action => ({ target: enemy, action: action }))) const voreActions = actions.filter(action => actor.otherContainers.concat(actor.containers).some(container => container.actions.includes(action.action) || action instanceof TransferAction)) const aggressiveActions = voreActions.filter(action => !(action.action instanceof ReleaseAction)) const chosen = aggressiveActions[Math.floor(Math.random() * aggressiveActions.length)] if (chosen === undefined) { return super.decide(actor, encounter) } return chosen.action.execute(actor, chosen.target) } }