'Functional version' broke, cba to fix :)
This commit is contained in:
parent
545f8b4366
commit
74c40576cf
49
Tank.ts
49
Tank.ts
@ -1,49 +0,0 @@
|
|||||||
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 CritMultiplier = (health: number) => number;
|
|
||||||
const critMultiplier: CritMultiplier = (health) =>
|
|
||||||
Math.floor(Math.random() * 10) >= 10 - health / 10 ? 1 : 2;
|
|
||||||
|
|
||||||
type SetStats = (tank: ITank) => ITank;
|
|
||||||
const setStats: SetStats = (tank) => ({
|
|
||||||
...tank,
|
|
||||||
attackDelay: tank.attackDelay === 0 ? Math.floor(tank.health / 10) : tank.attackDelay - 1,
|
|
||||||
} 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[Math.floor(Math.random() * tanks.length)];
|
|
||||||
const attackDamage = critMultiplier(tank.health) * tank.health / 100;
|
|
||||||
target.health -= attackDamage;
|
|
||||||
};
|
|
||||||
|
|
||||||
return tanks.map(setStats);
|
|
||||||
};
|
|
||||||
|
|
||||||
type IsLive = (tank: ITank) => boolean;
|
|
||||||
const isLive: IsLive = (tank) => tank.health >= 0;
|
|
||||||
|
|
||||||
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));
|
|
2
index.ts
2
index.ts
@ -9,7 +9,7 @@
|
|||||||
* KAPOW!!!
|
* KAPOW!!!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { buildTank, battleItOut } from "./Tank";
|
import { buildTank, battleItOut } from "./lib/Tank";
|
||||||
|
|
||||||
const tankPrototypes = [
|
const tankPrototypes = [
|
||||||
"Rust",
|
"Rust",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
|
import { mapR } from "./reducers";
|
||||||
import { doIf, tap } from "./combinators";
|
import { doIf, tap } from "./combinators";
|
||||||
import { isLive, setProp, dealDamageToRandom, isReadyToAttack } from "./helpers";
|
import { isLive, setProp, dealDamageToRandom, isReadyToAttack } from "./helpers";
|
||||||
import { mapR, pipe } from "./reducers";
|
|
||||||
|
|
||||||
export interface ITank {
|
export interface ITank {
|
||||||
name: string;
|
name: string;
|
||||||
@ -23,7 +23,7 @@ const attack: Attack = (_acc, tank, _iTank, tanks) => {
|
|||||||
dealDamageToRandom(tanks)
|
dealDamageToRandom(tanks)
|
||||||
)
|
)
|
||||||
)(tank);
|
)(tank);
|
||||||
return mapR(setProp("attackDelay", tank))(tanks);
|
return mapR(setProp("attackDelay", isReadyToAttack(tank) ? Math.floor(tank.health / 10) : tank.attackDelay - 1))(tanks);
|
||||||
};
|
};
|
||||||
|
|
||||||
type Attacks = (tanks: ITank[]) => ITank[];
|
type Attacks = (tanks: ITank[]) => ITank[];
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
// @ts-nocheck
|
||||||
|
|
||||||
export const tap = (fn) => (input) => {
|
export const tap = (fn) => (input) => {
|
||||||
fn(input);
|
fn(input);
|
||||||
return input;
|
return input;
|
||||||
|
@ -9,6 +9,7 @@ type PickRandom = <T>(arr: T[]) => T;
|
|||||||
export const pickRandom: PickRandom = (arr) =>
|
export const pickRandom: PickRandom = (arr) =>
|
||||||
arr[Math.floor(Math.random() * arr.length)];
|
arr[Math.floor(Math.random() * arr.length)];
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
export const setProp = (prop, val) => (obj) => obj[prop] = val;
|
export const setProp = (prop, val) => (obj) => obj[prop] = val;
|
||||||
|
|
||||||
type IsLive = (tank: ITank) => boolean;
|
type IsLive = (tank: ITank) => boolean;
|
||||||
@ -21,6 +22,7 @@ export const isReadyToAttack = (tank: ITank) => tank.attackDelay === 0;
|
|||||||
|
|
||||||
type DealDamageToRandom = (tanks: ITank[]) => (tank: ITank) => void;
|
type DealDamageToRandom = (tanks: ITank[]) => (tank: ITank) => void;
|
||||||
export const dealDamageToRandom: DealDamageToRandom = (tanks) => (tank) => {
|
export const dealDamageToRandom: DealDamageToRandom = (tanks) => (tank) => {
|
||||||
|
console.log("hp");
|
||||||
const target = pipe(filterR(isOther(tank.name)), pickRandom)(tanks);
|
const target = pipe(filterR(isOther(tank.name)), pickRandom)(tanks);
|
||||||
const attackDamage = critMultiplier(tank.health) * tank.health / 100;
|
const attackDamage = critMultiplier(tank.health) * tank.health / 100;
|
||||||
setProp("health", target.health - attackDamage)(target);
|
setProp("health", target.health - attackDamage)(target);
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
|
// @ts-nocheck
|
||||||
|
|
||||||
export const pipe = (...fns) => (input) =>
|
export const pipe = (...fns) => (input) =>
|
||||||
fns.reduce((acc, fn) => fn(acc), input);
|
fns.reduce((acc, fn) => fn(acc), input);
|
||||||
|
|
||||||
export const redFn = (acc, x) => [...acc, x];
|
|
||||||
|
|
||||||
export const mapR = (fn) => (input) =>
|
export const mapR = (fn) => (input) =>
|
||||||
input.reduce((acc, x) => [...acc, fn(x)], []);
|
input.reduce((acc, x) => [...acc, fn(x)], []);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user