import {NS} from "NetscriptDefinitions"; enum Type { newNode = "node", level = "level", ram = "ram", core = "code" } export async function main(ns: NS) { let timeout: number = ns.args[0] let nodes = ns.hacknet.numNodes() let costs: {type: Type, cost: number}[] = [] while (true) { costs = [] // Go through each node and get the cheapest upgrade for (let i = 0; i < nodes; i++) { costs.push(getCheapestCost(ns, i)) } // Buy the cheapest upgrade from all nodes let cheapest = Math.min(...costs.map(c => c.cost)) // Find the index of the cheapest cost in the list let index = costs.findIndex(c => c.cost === cheapest) // Wait to buy the cheapest upgrade try { await buy(ns, costs[index].type, costs[index].cost, index, timeout) } catch (e) { ns.tprint(e) ns.exit() } // Make sure that the number of nodes is up-to-date nodes = ns.hacknet.numNodes() } } /** * Wait until the player has enough money to buy something * @param ns Global NS object * @param money Amount of money to wait for * @param timeout=-1 Number of seconds to wait before timing out. * @throws Error if the timeout is reached * @note This function will wait forever by default */ async function waitUntilMoney(ns: NS, money: number, timeout: number = -1) { while (ns.getServerMoneyAvailable("home") < money) { await ns.sleep(1000) if (timeout == 0) { throw new Error("Timed out waiting for money") } else if (timeout > -1) { timeout--; } } } async function buy(ns: NS, type: Type, cost: number, node: number, timeout: number) { await waitUntilMoney(ns, cost, timeout) switch (type) { case Type.newNode: ns.hacknet.purchaseNode() break case Type.level: ns.hacknet.upgradeLevel(node) break case Type.ram: ns.hacknet.upgradeRam(node) break case Type.core: ns.hacknet.upgradeCore(node) break } } function getCheapestCost(ns: NS, node: number) { let nodeCost = ns.hacknet.getPurchaseNodeCost() let levelCost = ns.hacknet.getLevelUpgradeCost(node) let ramCost = ns.hacknet.getRamUpgradeCost(node) let coreCost = ns.hacknet.getCoreUpgradeCost(node) let cheapest = Math.min(nodeCost, levelCost, ramCost, coreCost) switch (cheapest) { case nodeCost: return {type: Type.newNode, cost: nodeCost} case levelCost: return {type: Type.level, cost: levelCost} case ramCost: return {type: Type.ram, cost: ramCost} case coreCost: return {type: Type.core, cost: coreCost} } }