Files
Dune/game/reinforcements.ts
T
Quintine 1cf90f1328
Verify and publish checkpoint container / container (push) Successful in 11m11s
Allow chosen Reinforcements reserve costs
2026-10-29 04:41:26 +11:00

43 lines
2.0 KiB
TypeScript

import type { Card } from './cards';
import { ecazTreacheryDefinition } from './ecaz-cards';
export const REINFORCEMENTS_CARD = 'ecaz-reinforcements' as const;
export class ReinforcementsError extends Error {
constructor(message: string) {
super(message);
this.name = 'ReinforcementsError';
}
}
/** A matching id alone does not establish the physical variant card's identity. */
export function isReinforcements(card: Card | undefined): boolean {
return !!card && card.id === REINFORCEMENTS_CARD &&
Object.keys(card).sort().join(',') === 'effect,id,kind,name' &&
ecazTreacheryDefinition(card)?.card.effect === 'reinforcements';
}
/** Legal elite counts for the three-counter fee, in ordinary-first order. */
export function reinforcementsEliteOptions(normalReserves: number, eliteReserves: number): number[] {
if (![normalReserves, eliteReserves].every(n => typeof n === 'number' && Number.isSafeInteger(n) && n >= 0))
throw new ReinforcementsError('Reinforcements needs valid nonnegative reserve counts.');
const minimum = Math.max(0, 3 - normalReserves);
const maximum = Math.min(3, eliteReserves);
return minimum > maximum ? [] : Array.from({ length: maximum - minimum + 1 }, (_, i) => minimum + i);
}
/** Spend exactly three own reserve counters; omitted choice retains the original ordinary-first rule. */
export function quoteReinforcements(
normalReserves: number,
eliteReserves: number,
selectedElite?: number,
): { normal: number; elite: number; bonus: 2 } {
const options = reinforcementsEliteOptions(normalReserves, eliteReserves);
if (!options.length)
throw new ReinforcementsError('Reinforcements needs at least three own forces in reserves.');
const elite = selectedElite === undefined ? options[0] : selectedElite;
if (!Number.isSafeInteger(elite) || !options.includes(elite))
throw new ReinforcementsError('Choose an available mix of three ordinary and elite reserve forces.');
return { normal: 3 - elite, elite, bonus: 2 };
}