

Bitburner – 從自動部屬 Hacknet 入門
source link: https://fredxxx123.wordpress.com/2022/03/06/bitburner-%E5%BE%9E%E8%87%AA%E5%8B%95%E9%83%A8%E5%B1%AC-hacknet-%E5%85%A5%E9%96%80/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Bitburner – 從自動部屬 Hacknet 入門
有多少錢就買甚麼 換個角度來說, 就是選擇升級/購買選項中最低價的項目
在整個撰寫的過程中, 需要到處蒐集資訊 (API document/IDE 提示/別人的程式碼…etc)
hacknet 相關的 API 都集中在一起:
找到所有的 server, 就會用到 numNodes
const count = ns.hacknet.numNodes();
for (let i = 0; i < count; i++) { ... }
取得購買新節點的費用: getPurchaseNodeCost
const cost = ns.hacknet.getPurchaseNodeCost();
升級相關費用的 API 參數需求都長得一樣
cost = ns.hacknet.getLevelUpgradeCost(nodeIndex, 1);
cost = ns.hacknet.getRamUpgradeCost(nodeIndex, 1);
cost = ns.hacknet.getCoreUpgradeCost(nodeIndex, 1);
JS 相關語法:
以上這些就可以先找出最低價的項目:
/** @param {NS} ns **/
export async function main(ns) {
// 預設以購買新 node server 為開頭
// 紀錄最便宜的花費
let cheapestCost = ns.hacknet.getPurchaseNodeCost();
// 紀錄最便宜項目的node序號(如果有的話)
let cheapestIndex = -1;
// 紀錄最便宜項目的類型
let cheapestType = "new";
// 取得目前擁有的節點數量
const count = ns.hacknet.numNodes();
// 遍歷所有節點
for (let i = 0; i < count; i++) {
// upgrade level
let cost = ns.hacknet.getLevelUpgradeCost(i, 1);
ns.print(`node: ${i}, cost of level: ${cost}, cheapestCost: ${cheapestCost}`);
if (cost < cheapestCost) {
cheapestCost = cost;
cheapestIndex = i;
cheapestType = "level";
}
// upgrade ram
cost = ns.hacknet.getRamUpgradeCost(i, 1);
ns.print(`node: ${i}, cost of ram: ${cost}, cheapestCost: ${cheapestCost}`);
if (cost < cheapestCost) {
cheapestCost = cost;
cheapestIndex = i;
cheapestType = "ram";
}
// upgrade core
cost = ns.hacknet.getCoreUpgradeCost(i, 1);
ns.print(`node: ${i}, cost of core: ${cost}, cheapestCost: ${cheapestCost}`);
if (cost < cheapestCost) {
cheapestCost = cost;
cheapestIndex = i;
cheapestType = "core";
}
}
// show hint
ns.print(`cheapest item is node ${cheapestIndex}'s ${cheapestType}, cost is ${cheapestCost}`);
}
這段就是像在 UI 上的檢查流程
既然找到目標, 確認 log 內容也沒問題, 就可以付諸行動
這裡會用到:
JS 相關:
就可以寫成:
switch (cheapestType) {
case "new":
ns.hacknet.purchaseNode();
ns.print(`buy new node`);
break;
case "level":
ns.hacknet.upgradeLevel(cheapestIndex, 1);
ns.print(`upgrade ${cheapestIndex}'s level`);
break;
case "ram":
ns.hacknet.upgradeRam(cheapestIndex, 1);
ns.print(`upgrade ${cheapestIndex}'s ram`);
break;
case "core":
ns.hacknet.upgradeCore(cheapestIndex, 1);
ns.print(`upgrade ${cheapestIndex}'s core`);
break;
}
確認上述內容都可以正確如預期般的運作
最後就是讓它在背景持續地運作
這裡會用到:
就可以寫成:
while(true) {
// do something here...
// 等待 5000 毫秒(等同於 5 秒)
await ns.sleep(5000)
}
實作-all
整個合在一起就變成:
export async function main(ns) {
while (true) {
// 預設以購買新 node server 為開頭
// 紀錄最便宜的花費
let cheapestCost = ns.hacknet.getPurchaseNodeCost();
// 紀錄最便宜項目的node序號(如果有的話)
let cheapestIndex = -1;
// 紀錄最便宜項目的類型
let cheapestType = "new";
// 取得目前擁有的節點數量
const count = ns.hacknet.numNodes();
for (let i = 0; i < count; i++) {
// upgrade level
let cost = ns.hacknet.getLevelUpgradeCost(i, 1);
ns.print(`node: ${i}, cost of level: ${cost}, cheapestCost: ${cheapestCost}`);
if (cost < cheapestCost) {
cheapestCost = cost;
cheapestIndex = i;
cheapestType = "level";
}
// upgrade ram
cost = ns.hacknet.getRamUpgradeCost(i, 1);
ns.print(`node: ${i}, cost of ram: ${cost}, cheapestCost: ${cheapestCost}`);
if (cost < cheapestCost) {
cheapestCost = cost;
cheapestIndex = i;
cheapestType = "ram";
}
// upgrade core
cost = ns.hacknet.getCoreUpgradeCost(i, 1);
ns.print(`node: ${i}, cost of core: ${cost}, cheapestCost: ${cheapestCost}`);
if (cost < cheapestCost) {
cheapestCost = cost;
cheapestIndex = i;
cheapestType = "core";
}
}
// show hint
ns.print(`cheapest item is node ${cheapestIndex}'s ${cheapestType}, cost is ${cheapestCost}`);
// 確認是否有項目被找到
if (cheapestCost < Number.MAX_VALUE) {
switch (cheapestType) {
case "new":
ns.hacknet.purchaseNode();
ns.print(`buy new node`);
break;
case "level":
ns.hacknet.upgradeLevel(cheapestIndex, 1);
ns.print(`upgrade ${cheapestIndex}'s level`);
break;
case "ram":
ns.hacknet.upgradeRam(cheapestIndex, 1);
ns.print(`upgrade ${cheapestIndex}'s ram`);
break;
case "core":
ns.hacknet.upgradeCore(cheapestIndex, 1);
ns.print(`upgrade ${cheapestIndex}'s core`);
break;
}
}
// 等待一會
await ns.sleep(5000);
}
}
最後…還沒結束
這是從實際操作轉成程式碼的最基本型態, 下一步就會依據此版本為基礎不但地進行改造, e.g.:
- 升級花費不超過某個價格
- 控制檢查頻率
- 強化閱讀性
- 應對一些少見的/極端的狀況
- 其他更好的演算法
Recommend
-
67
前几天基友送我了一款游戏,叫做Hacknet,黑客模拟器。游戏讲述的是一名黑客Bit死亡后,将操作系统Hacknet
-
100
<p>GatsbyJS 是一個現代化開發網站的網站產生系統,擁有完整、豐富且開源的生態圈。它利用 React + GraphQL 產生的多頁面應用,讓前端工程師,編輯,用戶都感到滿意。就讓我們一步步地探索這個系統吧。</p>
-
14
類 Python 的合約語言 Vyper 開發入門:與 Solidity 差異、用 Truffle 部署、ERC20 賣幣合約實做有鑒於個人近期關注的 Uniswap 及 Curve 皆用 Vyper 實作,索性瀏覽了官方文件並嘗試一些開發工具,希望此文能減少一些讀者初嘗 Vy...
-
12
ZKP 與智能合約的開發入門這篇文章將以程式碼範例,說明 Zero Knowledge Proofs 與智能合約的結合,能夠為以太坊的生態系帶來什麼創新的應用。本文為 Tornado Cash 研究系列的 Part 2,本系列...
-
7
PCIe 4.0 入門解決方案,Western Digital 推出 WD_Black SN750 SE NVMe SSD 延續 WD_Black SN750 名號,但是核心設計解決方案大不同。
-
15
Bitburner Bitburner is a programming-based incremental game that revolves around hacking and cyberpunk themes. The game can be played at
-
6
關於遊戲機制 必然需要 coding 正常來說會花不少時間掛網 離線時間依據各種機制有不同的計算方式 因為有組件價格加成的機制, 所以很多時候進到下一個循環會更快
-
6
Bitburner – intro Bitburner 是一款最近出在 Steam 上真正認真寫扣的遊戲 , for FREE!!
-
9
Bitburner – 終端機(terminal)
-
7
舊專案沒做的,就把他做起來吧!一個 Rails 專案,有三台機器,每次部屬分別要手動部屬,但其實這個可以做自動化三台機器分別是不同的權限使用但都吃同一個專案,並非 load balance 那種情況這邊我只用自己的電腦來做,所以這三台機器都分...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK