import type { DomainEvent } from "./events.js"; import type { DomainError, Encounter } from "./types.js"; interface RetreatTurnSuccess { readonly encounter: Encounter; readonly events: DomainEvent[]; } export function retreatTurn( encounter: Encounter, ): RetreatTurnSuccess | DomainError { if (encounter.combatants.length === 0) { return { kind: "domain-error", code: "invalid-encounter", message: "Cannot retreat turn on an encounter with no combatants", }; } if (encounter.roundNumber === 1 && encounter.activeIndex === 0) { return { kind: "domain-error", code: "no-previous-turn", message: "Cannot retreat before the start of the encounter", }; } const previousIndex = encounter.activeIndex; const wraps = previousIndex === 0; const newIndex = wraps ? encounter.combatants.length - 1 : previousIndex - 1; const newRoundNumber = wraps ? encounter.roundNumber - 1 : encounter.roundNumber; const events: DomainEvent[] = [ { type: "TurnRetreated", previousCombatantId: encounter.combatants[previousIndex].id, newCombatantId: encounter.combatants[newIndex].id, roundNumber: newRoundNumber, }, ]; if (wraps) { events.push({ type: "RoundRetreated", newRoundNumber, }); } return { encounter: { combatants: encounter.combatants, activeIndex: newIndex, roundNumber: newRoundNumber, }, events, }; }