2023-12-06 00:41:04 +00:00
|
|
|
import { mapR } from "./reducers";
|
2023-12-06 00:21:48 +00:00
|
|
|
import { doIf, tap } from "./combinators";
|
|
|
|
import { isLive, setProp, dealDamageToRandom, isReadyToAttack } from "./helpers";
|
2023-12-05 23:27:52 +00:00
|
|
|
|
|
|
|
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);
|
|
|
|
|
2023-12-06 00:21:48 +00:00
|
|
|
type Attack = (_prevTanks: ITank[], tank: ITank, tIndex: number, tanks: ITank[]) => ITank[];
|
2023-12-05 23:27:52 +00:00
|
|
|
const attack: Attack = (_acc, tank, _iTank, tanks) => {
|
2023-12-06 00:21:48 +00:00
|
|
|
tap(
|
|
|
|
doIf(
|
|
|
|
isReadyToAttack,
|
|
|
|
dealDamageToRandom(tanks)
|
|
|
|
)
|
|
|
|
)(tank);
|
2023-12-06 00:41:04 +00:00
|
|
|
return mapR(setProp("attackDelay", isReadyToAttack(tank) ? Math.floor(tank.health / 10) : tank.attackDelay - 1))(tanks);
|
2023-12-05 23:27:52 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
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));
|