import { setStats, isLive, isOther, critMultiplier } from "./helpers"; export interface ITank { name: string; health: number; attackDelay: number; } type BuildTank = (name: string) => ITank; export const buildTank: BuildTank = (name) => ({ name, health: 100, attackDelay: 0, } as ITank); type Attack = (_: ITank[], tank: ITank, tIndex: number, tanks: ITank[]) => ITank[]; const attack: Attack = (_acc, tank, _iTank, tanks) => { // [TODO]: Refactor this imperative block if (tank.attackDelay === 0) { const target = tanks.filter(isOther(tank.name))[Math.floor(Math.random() * tanks.length)]; const attackDamage = critMultiplier(tank.health) * tank.health / 100; target.health -= attackDamage; }; return tanks.map(setStats); }; type Attacks = (tanks: ITank[]) => ITank[]; const attacksRound: Attacks = (tanks) => tanks .reduce(attack, tanks) .filter(isLive); type Battle = (remainingTanks: ITank[]) => ITank; export const battleItOut: Battle = (remainingTanks: ITank[]) => remainingTanks.length === 1 ? remainingTanks[0] : battleItOut(attacksRound(remainingTanks));