diff --git a/lib/Tank.ts b/lib/Tank.ts new file mode 100644 index 0000000..5cf0635 --- /dev/null +++ b/lib/Tank.ts @@ -0,0 +1,38 @@ +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)); diff --git a/lib/helpers.ts b/lib/helpers.ts new file mode 100644 index 0000000..e6cb4ed --- /dev/null +++ b/lib/helpers.ts @@ -0,0 +1,17 @@ +import { ITank } from "./Tank"; + +type CritMultiplier = (health: number) => number; +export const critMultiplier: CritMultiplier = (health) => + Math.floor(Math.random() * 10) >= 10 - health / 10 ? 1 : 2; + +type SetStats = (tank: ITank) => ITank; +export const setStats: SetStats = (tank) => ({ + ...tank, + attackDelay: tank.attackDelay === 0 ? Math.floor(tank.health / 10) : tank.attackDelay - 1, +} as ITank); + +type IsLive = (tank: ITank) => boolean; +export const isLive: IsLive = (tank) => tank.health >= 0; + +type IsOther = (name: string) => (tank: ITank) => boolean; +export const isOther: IsOther = (name) => (tank) => tank.name !== name;