diff --git a/src/Hacknet/formulas/HacknetNodes.ts b/src/Hacknet/formulas/HacknetNodes.ts index 21d45e5a1..9e46c6112 100644 --- a/src/Hacknet/formulas/HacknetNodes.ts +++ b/src/Hacknet/formulas/HacknetNodes.ts @@ -16,7 +16,7 @@ export function calculateLevelUpgradeCost(startingLevel: number, extraLevels = 1 return 0; } - if (startingLevel >= HacknetNodeConstants.MaxLevel) { + if (startingLevel + sanitizedLevels > HacknetNodeConstants.MaxLevel) { return Infinity; } @@ -37,7 +37,7 @@ export function calculateRamUpgradeCost(startingRam: number, extraLevels = 1, co return 0; } - if (startingRam >= HacknetNodeConstants.MaxRam) { + if (startingRam * Math.pow(2, sanitizedLevels) > HacknetNodeConstants.MaxRam) { return Infinity; } @@ -60,20 +60,20 @@ export function calculateRamUpgradeCost(startingRam: number, extraLevels = 1, co return totalCost; } -export function calculateCoreUpgradeCost(startingCore: number, extraLevels = 1, costMult = 1): number { +export function calculateCoreUpgradeCost(startingCores: number, extraLevels = 1, costMult = 1): number { const sanitizedCores = Math.round(extraLevels); if (isNaN(sanitizedCores) || sanitizedCores < 1) { return 0; } - if (startingCore >= HacknetNodeConstants.MaxCores) { + if (startingCores + sanitizedCores > HacknetNodeConstants.MaxCores) { return Infinity; } const coreBaseCost = HacknetNodeConstants.CoreBaseCost; const mult = HacknetNodeConstants.UpgradeCoreMult; let totalCost = 0; - let currentCores = startingCore; + let currentCores = startingCores; for (let i = 0; i < sanitizedCores; ++i) { totalCost += coreBaseCost * Math.pow(mult, currentCores - 1); ++currentCores; diff --git a/src/Hacknet/formulas/HacknetServers.ts b/src/Hacknet/formulas/HacknetServers.ts index 73ed68be0..8aa5adc6a 100644 --- a/src/Hacknet/formulas/HacknetServers.ts +++ b/src/Hacknet/formulas/HacknetServers.ts @@ -22,7 +22,7 @@ export function calculateLevelUpgradeCost(startingLevel: number, extraLevels = 1 return 0; } - if (startingLevel >= HacknetServerConstants.MaxLevel) { + if (startingLevel + sanitizedLevels > HacknetServerConstants.MaxLevel) { return Infinity; } @@ -43,7 +43,7 @@ export function calculateRamUpgradeCost(startingRam: number, extraLevels = 1, co return 0; } - if (startingRam >= HacknetServerConstants.MaxRam) { + if (startingRam * Math.pow(2, sanitizedLevels) > HacknetServerConstants.MaxRam) { return Infinity; } @@ -70,7 +70,7 @@ export function calculateCoreUpgradeCost(startingCores: number, extraLevels = 1, return 0; } - if (startingCores >= HacknetServerConstants.MaxCores) { + if (startingCores + sanitizedLevels > HacknetServerConstants.MaxCores) { return Infinity; } @@ -93,7 +93,7 @@ export function calculateCacheUpgradeCost(startingCache: number, extraLevels = 1 return 0; } - if (startingCache >= HacknetServerConstants.MaxCache) { + if (startingCache + sanitizedLevels > HacknetServerConstants.MaxCache) { return Infinity; } diff --git a/test/jest/Hacknet.test.ts b/test/jest/Hacknet.test.ts new file mode 100644 index 000000000..ef7d1cff2 --- /dev/null +++ b/test/jest/Hacknet.test.ts @@ -0,0 +1,147 @@ +import { HacknetNodeConstants, HacknetServerConstants } from "../../src/Hacknet/data/Constants"; +import { + calculateCoreUpgradeCost as calculateCoreUpgradeCostNode, + calculateLevelUpgradeCost as calculateLevelUpgradeCostNode, + calculateRamUpgradeCost as calculateRamUpgradeCostNode, +} from "../../src/Hacknet/formulas/HacknetNodes"; +import { + calculateCoreUpgradeCost as calculateCoreUpgradeCostServer, + calculateLevelUpgradeCost as calculateLevelUpgradeCostServer, + calculateRamUpgradeCost as calculateRamUpgradeCostServer, +} from "../../src/Hacknet/formulas/HacknetServers"; + +describe("HacknetNode calculations", () => { + describe("calculateLevelUpgradeCost applies limits", () => { + it("bails out for NaN", () => { + expect(calculateLevelUpgradeCostNode(1, NaN, 1)).toBe(0); + }); + it("fails for invalid extraLevels", () => { + expect(calculateLevelUpgradeCostNode(1, -1, 1)).toBe(0); + expect(calculateLevelUpgradeCostNode(1, 0, 1)).toBe(0); + expect(calculateLevelUpgradeCostNode(1, 1, 1)).toBeGreaterThan(0); + }); + it("correctly rounds values between 0.5 and 1", () => { + expect(calculateLevelUpgradeCostNode(1, 0.4, 1)).toBe(0); + expect(calculateLevelUpgradeCostNode(1, 0.5, 1)).toBeGreaterThan(0); + expect(calculateLevelUpgradeCostNode(1, 0.9999999999999999, 1)).toBeGreaterThan(0); + }); + it("limits maximum level correctly", () => { + expect(calculateLevelUpgradeCostNode(HacknetNodeConstants.MaxLevel, 1, 1)).toBe(Infinity); + expect(calculateLevelUpgradeCostNode(HacknetNodeConstants.MaxLevel + 1, 1, 1)).toBe(Infinity); + expect(calculateLevelUpgradeCostNode(HacknetNodeConstants.MaxLevel - 1, 1, 1)).toBeGreaterThan(0); + expect(calculateLevelUpgradeCostNode(HacknetNodeConstants.MaxLevel - 2, 5, 1)).toBe(Infinity); + }); + }); + + describe("calculateRamUpgradeCost applies limits", () => { + it("bails out for NaN", () => { + expect(calculateRamUpgradeCostNode(1, NaN, 1)).toBe(0); + }); + it("fails for invalid extraLevels", () => { + expect(calculateRamUpgradeCostNode(1, -1, 1)).toBe(0); + expect(calculateRamUpgradeCostNode(1, 0, 1)).toBe(0); + expect(calculateRamUpgradeCostNode(1, 1, 1)).toBeGreaterThan(0); + }); + it("correctly rounds values between 0.5 and 1", () => { + expect(calculateRamUpgradeCostNode(1, 0.4, 1)).toBe(0); + expect(calculateRamUpgradeCostNode(1, 0.5, 1)).toBeGreaterThan(0); + expect(calculateRamUpgradeCostNode(1, 0.9999999999999999, 1)).toBeGreaterThan(0); + }); + it("limits maximum level correctly", () => { + expect(calculateRamUpgradeCostNode(HacknetNodeConstants.MaxRam, 1, 1)).toBe(Infinity); + expect(calculateRamUpgradeCostNode(HacknetNodeConstants.MaxRam + 1, 1, 1)).toBe(Infinity); + expect(calculateRamUpgradeCostNode(HacknetNodeConstants.MaxRam - 1, 1, 1)).toBeGreaterThan(0); + expect(calculateRamUpgradeCostNode(HacknetNodeConstants.MaxRam - 2, 5, 1)).toBe(Infinity); + }); + }); + + describe("calculateCoreUpgradeCost applies limits", () => { + it("bails out for NaN", () => { + expect(calculateCoreUpgradeCostNode(1, NaN, 1)).toBe(0); + }); + it("fails for invalid extraLevels", () => { + expect(calculateCoreUpgradeCostNode(1, -1, 1)).toBe(0); + expect(calculateCoreUpgradeCostNode(1, 0, 1)).toBe(0); + expect(calculateCoreUpgradeCostNode(1, 1, 1)).toBeGreaterThan(0); + }); + it("correctly rounds values between 0.5 and 1", () => { + expect(calculateCoreUpgradeCostNode(1, 0.4, 1)).toBe(0); + expect(calculateCoreUpgradeCostNode(1, 0.5, 1)).toBeGreaterThan(0); + expect(calculateCoreUpgradeCostNode(1, 0.9999999999999999, 1)).toBeGreaterThan(0); + }); + it("limits maximum level correctly", () => { + expect(calculateCoreUpgradeCostNode(HacknetNodeConstants.MaxCores, 1, 1)).toBe(Infinity); + expect(calculateCoreUpgradeCostNode(HacknetNodeConstants.MaxCores + 1, 1, 1)).toBe(Infinity); + expect(calculateCoreUpgradeCostNode(HacknetNodeConstants.MaxCores - 1, 1, 1)).toBeGreaterThan(0); + expect(calculateCoreUpgradeCostNode(HacknetNodeConstants.MaxCores - 2, 5, 1)).toBe(Infinity); + }); + }); +}); + +describe("HacknetServer calculations", () => { + describe("calculateLevelUpgradeCost applies limits", () => { + it("bails out for NaN", () => { + expect(calculateLevelUpgradeCostServer(1, NaN, 1)).toBe(0); + }); + it("fails for invalid extraLevels", () => { + expect(calculateLevelUpgradeCostServer(1, -1, 1)).toBe(0); + expect(calculateLevelUpgradeCostServer(1, 0, 1)).toBe(0); + expect(calculateLevelUpgradeCostServer(1, 1, 1)).toBeGreaterThan(0); + }); + it("correctly rounds values between 0.5 and 1", () => { + expect(calculateLevelUpgradeCostServer(1, 0.4, 1)).toBe(0); + expect(calculateLevelUpgradeCostServer(1, 0.5, 1)).toBeGreaterThan(0); + expect(calculateLevelUpgradeCostServer(1, 0.9999999999999999, 1)).toBeGreaterThan(0); + }); + it("limits maximum level correctly", () => { + expect(calculateLevelUpgradeCostServer(HacknetServerConstants.MaxLevel, 1, 1)).toBe(Infinity); + expect(calculateLevelUpgradeCostServer(HacknetServerConstants.MaxLevel + 1, 1, 1)).toBe(Infinity); + expect(calculateLevelUpgradeCostServer(HacknetServerConstants.MaxLevel - 1, 1, 1)).toBeGreaterThan(0); + expect(calculateLevelUpgradeCostServer(HacknetServerConstants.MaxLevel - 2, 5, 1)).toBe(Infinity); + }); + }); + + describe("calculateRamUpgradeCost applies limits", () => { + it("bails out for NaN", () => { + expect(calculateRamUpgradeCostServer(1, NaN, 1)).toBe(0); + }); + it("fails for invalid extraLevels", () => { + expect(calculateRamUpgradeCostServer(1, -1, 1)).toBe(0); + expect(calculateRamUpgradeCostServer(1, 0, 1)).toBe(0); + expect(calculateRamUpgradeCostServer(1, 1, 1)).toBeGreaterThan(0); + }); + it("correctly rounds values between 0.5 and 1", () => { + expect(calculateRamUpgradeCostServer(1, 0.4, 1)).toBe(0); + expect(calculateRamUpgradeCostServer(1, 0.5, 1)).toBeGreaterThan(0); + expect(calculateRamUpgradeCostServer(1, 0.9999999999999999, 1)).toBeGreaterThan(0); + }); + it("limits maximum level correctly", () => { + expect(calculateRamUpgradeCostServer(HacknetServerConstants.MaxRam, 1, 1)).toBe(Infinity); + expect(calculateRamUpgradeCostServer(HacknetServerConstants.MaxRam + 1, 1, 1)).toBe(Infinity); + expect(calculateRamUpgradeCostServer(HacknetServerConstants.MaxRam - 1, 1, 1)).toBeGreaterThan(0); + expect(calculateRamUpgradeCostServer(HacknetServerConstants.MaxRam - 2, 5, 1)).toBe(Infinity); + }); + }); + + describe("calculateCoreUpgradeCost applies limits", () => { + it("bails out for NaN", () => { + expect(calculateCoreUpgradeCostServer(1, NaN, 1)).toBe(0); + }); + it("fails for invalid extraLevels", () => { + expect(calculateCoreUpgradeCostServer(1, -1, 1)).toBe(0); + expect(calculateCoreUpgradeCostServer(1, 0, 1)).toBe(0); + expect(calculateCoreUpgradeCostServer(1, 1, 1)).toBeGreaterThan(0); + }); + it("correctly rounds values between 0.5 and 1", () => { + expect(calculateCoreUpgradeCostServer(1, 0.4, 1)).toBe(0); + expect(calculateCoreUpgradeCostServer(1, 0.5, 1)).toBeGreaterThan(0); + expect(calculateCoreUpgradeCostServer(1, 0.9999999999999999, 1)).toBeGreaterThan(0); + }); + it("limits maximum level correctly", () => { + expect(calculateCoreUpgradeCostServer(HacknetServerConstants.MaxCores, 1, 1)).toBe(Infinity); + expect(calculateCoreUpgradeCostServer(HacknetServerConstants.MaxCores + 1, 1, 1)).toBe(Infinity); + expect(calculateCoreUpgradeCostServer(HacknetServerConstants.MaxCores - 1, 1, 1)).toBeGreaterThan(0); + expect(calculateCoreUpgradeCostServer(HacknetServerConstants.MaxCores - 2, 5, 1)).toBe(Infinity); + }); + }); +});