import { mapR } from "./reducers"; import { doIf, tap } from "./combinators"; import { isLive, setProp, dealDamageToRandom, isReadyToAttack } 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 = (_prevTanks: ITank[], tank: ITank, tIndex: number, tanks: ITank[]) => ITank[]; const attack: Attack = (_acc, tank, _iTank, tanks) => { tap( doIf( isReadyToAttack, dealDamageToRandom(tanks) ) )(tank); return mapR(setProp("attackDelay", isReadyToAttack(tank) ? Math.floor(tank.health / 10) : tank.attackDelay - 1))(tanks); }; 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));