Fixed a few minor bugs with submitting solutions for Coding Contracts. Started on Getting STarted Guide for wiki

This commit is contained in:
danielyxie 2019-02-26 18:26:29 -08:00 committed by danielyxie
parent d54e39c9c6
commit 9879d07d7c
11 changed files with 104 additions and 57 deletions

@ -64,9 +64,9 @@ documentation_title = '{0} Documentation'.format(project)
# built documents. # built documents.
# #
# The short X.Y version. # The short X.Y version.
version = '0.43' version = '0.44'
# The full version, including alpha/beta/rc tags. # The full version, including alpha/beta/rc tags.
release = '0.43.0' release = '0.44.1'
# The language for content autogenerated by Sphinx. Refer to documentation # The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages. # for a list of supported languages.

@ -1,9 +1,11 @@
Guides & Tips Guides & Tips
============= =============
Getting Started Guide for Intermediate Programmers
What BitNode should I do?
Beginners FAQ
.. toctree:: .. toctree::
:maxdepth: 3 :maxdepth: 3
Getting Started Guide for Beginner Programmers Getting Started Guide for Beginner Programmers <guidesandtips/gettingstartedguideforbeginnerprogrammers>
Getting Started Guide for Intermediate Programmers
What BitNode should I do?

@ -0,0 +1,47 @@
Getting Started Guide for Beginner Programmers
==============================================
.. note:: Note that the scripts and strategies given in this guide aren't necessarily
optimal. They're just meant to introduce you to the game and help you get
started.
This is an introductory guide to getting started with Bitburner. It is not meant to be a
comprehensive guide for the entire game, only the early stages. If you are confused
or overwhelmed by the game, especially the programming and scripting aspects, this
guide is perfect for you!
Note that this guide is tailored towards those with minimal programming experience.
Introduction
------------
Bitburner is a cyberpunk-themed incremental RPG. The player progresses by raising
their :ref:`gameplay_stats`, earning money, and :ref:`climbing the corporate ladder <gameplay_companies>`.
Eventually, after reaching certain criteria, the player will begin receiving invitations
from :ref:`gameplay_factions`. Joining these factions and working for them will unlock
:ref:`gameplay_augmentations`. Purchasing and installing Augmentations provide persistent
upgrades and are necessary for progressing in the game.
The game has a minimal story/quest-line that can be followed to reach the end of the game.
Since this guide is only about getting started with Bitburner, it will not cover the
entire "quest-line".
First Steps
-----------
I'm going to assume you followed the introductory tutorial when you first began the game.
In this introductory tutorial you created a script called `foodnstuff.script` and ran it
on the `foodnstuff` server. Right now, we'll kill this script. There are two ways
to do this:
1. You can go to the Terminal and enter::
$ kill foodnstuff.script
2. You can go to the "Active Scripts" page (:ref:`Keyboard shortcut <shortcuts>` Alt + s) and
press the "Kill Script" button for `foodnstuff.script`.
If you skipped the introductory tutorial, then ignore the part above. Instead, go to the
"Hacknet Nodes" page (:ref:`Keyboard shortcut <shortcuts>` Alt + h) and purchase a
Hacknet Node to start generating some passive income.
Creating our First Scripts
--------------------------

@ -510,44 +510,15 @@ export let CONSTANTS: IMap<any> = {
LatestUpdate: LatestUpdate:
` `
v0.44.0 v0.44.1
* Bladeburner Changes: * Duplicate Sleeve changes:
** Reduced the amount of rank needed to earn a skill point ** You can now purchase Augmentations for your Duplicate Sleeves
** Reduced the effects of the "Reaper" and "Evasive System" skills ** Sleeves are now assigned to Shock Recovery task by default
** Increased the effect of the "Hyperdrive" and "Hands of Midas" skills ** Shock Recovery and Synchronize tasks are now twice as effective
** Slightly increased the rate which the skill point cost rises for almost all skills
** The "Overlock" Skill now has a maximum level of 90 instead of 95
** Money earned from Contracts increased by 400%
** Changed the way population affects success rate. Extreme populations now have less dramatic effects
** Added two new General Actions: Diplomacy and Hyperbolic Regeneration Chamber
** Lowered the rep and money cost of the "Blade's Simulacrum" augmentation
** Significantly decreased the initial amount of Contracts/Operations (the "Contracts/Operations remaining" value)
** Decreased the rate at which the amount of Contracts/Operations increases over time
** Decreased the number of successes you need to increase the max level of a Contract/Operation
** Increased the average number of Synthoid communities each city has
** Reduced the amount by which a successful raid will decrease the population of a city
** The "riots" event will now increase the chaos of a city by a greater amount
** Significantly increased the effect that Agility and Dexterity have on action time
* Added new BitNode multipliers: * Bug Fix: 'rm' Terminal and Netscript commands now work on non-program files that have '.exe' in the name (by Github user MasonD)
** HomeComputerRamCost - Affects how much it costs to upgrade home computer's RAM * Bug Fix: The 'Find All Valid Math Expressions' Coding Contract should now properly ignore whitespace in answers
** DaedalusAugsRequirement - Affects how many Augmentations you need in order to get invited to Daedalus * Bug Fix: The 'Merge Overlapping Intervals' Coding Contract should now properly accept 2D arrays when being attempted through Netscript
** FourSigmaMarketDataCost - Affects how much it costs to unlock the stock market's 4S Market Data
** FourSigmaMarketDataApiCost - Affects how much it costs to unlock the stock market's 4S Market Data API
* A few minor changes to BitNode multipliers across the board (mostly for the new multipliers)
* 'The Covenant' now requires 20 total Augmentations to get invited, rather than 30
* You can now purchase permanent Duplicate Sleeves from 'The Covenant'. This requires Source-File 10, and you must be in BN-10 or after
* You can now track where all of your money comes from in the 'Stats' page
* Increased the money gained from Coding Contracts by 50%
* getCharacterInformation() function now returns the player's HP and max HP
* Bug Fix: You can no longer disconnect the enemy's connections in Hacking Missions
* Bug Fix: Duplicate Sleeve faction reputation gain is now properly affected by faction favor
* Bug Fix: After installing Augmentations, the Terminal display will now correctly show the current server as "home"
* Bug Fix: Fixed an exploit where you could change the duration of timed functions (e.g. hack, weaken) in NetscriptJS
* Bug Fix: You should now properly be able to use the ServerProfile.exe program
* Bug Fix: Prevented exploit that allowed you to accept faction invites programmatically through NetscriptJS
* Bug Fix: Faction invitations for megacorporations should now work properly
` `
} }

@ -53,9 +53,6 @@ import {StockMarket, StockSymbols, SymbolToStockMap,
PositionTypes, placeOrder, cancelOrder} from "./StockMarket/StockMarket"; PositionTypes, placeOrder, cancelOrder} from "./StockMarket/StockMarket";
import { getStockmarket4SDataCost, import { getStockmarket4SDataCost,
getStockMarket4STixApiCost } from "./StockMarket/StockMarketCosts"; getStockMarket4STixApiCost } from "./StockMarket/StockMarketCosts";
import {numeralWrapper} from "./ui/numeralFormat";
import {post} from "./ui/postToTerminal";
import { setTimeoutRef } from "./utils/SetTimeoutRef";
import {TextFile, getTextFile, createTextFile} from "./TextFile"; import {TextFile, getTextFile, createTextFile} from "./TextFile";
import {unknownBladeburnerActionErrorMessage, import {unknownBladeburnerActionErrorMessage,
@ -68,8 +65,12 @@ import {makeRuntimeRejectMsg, netscriptDelay,
runScriptFromScript} from "./NetscriptEvaluator"; runScriptFromScript} from "./NetscriptEvaluator";
import {NetscriptPort} from "./NetscriptPort"; import {NetscriptPort} from "./NetscriptPort";
import Decimal from "decimal.js";
import {Page, routing} from "./ui/navigationTracking"; import {Page, routing} from "./ui/navigationTracking";
import {numeralWrapper} from "./ui/numeralFormat";
import {post} from "./ui/postToTerminal";
import { setTimeoutRef } from "./utils/SetTimeoutRef";
import { is2DArray } from "./utils/helpers/is2DArray";
import {dialogBoxCreate} from "../utils/DialogBox"; import {dialogBoxCreate} from "../utils/DialogBox";
import {isPowerOfTwo} from "../utils/helpers/isPowerOfTwo"; import {isPowerOfTwo} from "../utils/helpers/isPowerOfTwo";
import {arrayToString} from "../utils/helpers/arrayToString"; import {arrayToString} from "../utils/helpers/arrayToString";
@ -4686,7 +4687,20 @@ function NetscriptFunctions(workerScript) {
workerScript.log(`ERROR: codingcontract.getData() failed because it could find the specified contract ${fn} on server ${ip}`); workerScript.log(`ERROR: codingcontract.getData() failed because it could find the specified contract ${fn} on server ${ip}`);
return false; return false;
} }
answer = String(answer);
// Convert answer to string. If the answer is a 2D array, then we have to
// manually add brackets for the inner arrays
if (is2DArray(answer)) {
let answerComponents = [];
for (let i = 0; i < answer.length; ++i) {
answerComponents.push(["[", answer[i].toString(), "]"].join(""));
}
answer = answerComponents.join(",");
} else {
answer = String(answer);
}
const serv = safeGetServer(ip, "codingcontract.attempt()"); const serv = safeGetServer(ip, "codingcontract.attempt()");
if (contract.isSolution(answer)) { if (contract.isSolution(answer)) {
const reward = Player.gainCodingContractReward(contract.reward, contract.getDifficulty()); const reward = Player.gainCodingContractReward(contract.reward, contract.getDifficulty());

@ -16,14 +16,9 @@ import { numeralWrapper } from "../../ui/numeralFormat";
import { dialogBoxCreate } from "../../../utils/DialogBox"; import { dialogBoxCreate } from "../../../utils/DialogBox";
import { clearEventListeners } from "../../../utils/uiHelpers/clearEventListeners";
import { createElement } from "../../../utils/uiHelpers/createElement"; import { createElement } from "../../../utils/uiHelpers/createElement";
import { createPopup } from "../../../utils/uiHelpers/createPopup"; import { createPopup } from "../../../utils/uiHelpers/createPopup";
import { createPopupCloseButton } from "../../../utils/uiHelpers/createPopupCloseButton"; import { createPopupCloseButton } from "../../../utils/uiHelpers/createPopupCloseButton";
import { getSelectValue } from "../../../utils/uiHelpers/getSelectData";
import { removeChildrenFromElement } from "../../../utils/uiHelpers/removeChildrenFromElement";
import { removeElement } from "../../../utils/uiHelpers/removeElement";
import { removeElementById } from "../../../utils/uiHelpers/removeElementById";
export function createSleevePurchaseAugsPopup(sleeve: Sleeve, p: IPlayer) { export function createSleevePurchaseAugsPopup(sleeve: Sleeve, p: IPlayer) {
// You can only purchase Augmentations that are actually available from // You can only purchase Augmentations that are actually available from
@ -44,6 +39,8 @@ export function createSleevePurchaseAugsPopup(sleeve: Sleeve, p: IPlayer) {
} }
} }
// Create popup
const popupId = "purchase-sleeve-augs-popup";
// General info about buying Augmentations // General info about buying Augmentations
const info = createElement("p", { const info = createElement("p", {
@ -58,8 +55,10 @@ export function createSleevePurchaseAugsPopup(sleeve: Sleeve, p: IPlayer) {
].join(" "), ].join(" "),
}); });
const popupId = "purchase-sleeve-augs-popup"; // Close popup
const popupElems: HTMLElement[] = [info]; const closeBtn = createPopupCloseButton(popupId, { innerText: "Cancel" });
const popupElems: HTMLElement[] = [closeBtn, info];
for (const aug of availableAugs) { for (const aug of availableAugs) {
const div = createElement("div", { const div = createElement("div", {

@ -1,6 +1,7 @@
/** /**
* Module for handling the Sleeve UI * Module for handling the Sleeve UI
*/ */
import { createSleevePurchaseAugsPopup } from "./SleeveAugmentationsUI";
import { Sleeve } from "./Sleeve"; import { Sleeve } from "./Sleeve";
import { SleeveTaskType } from "./SleeveTaskTypesEnum"; import { SleeveTaskType } from "./SleeveTaskTypesEnum";
import { SleeveFaq } from "./data/SleeveFaq"; import { SleeveFaq } from "./data/SleeveFaq";
@ -277,7 +278,7 @@ function createSleeveUi(sleeve: Sleeve, allSleeves: Sleeve[]): ISleeveUIElems {
display: "block", display: "block",
innerText: "Purchase Augmentations", innerText: "Purchase Augmentations",
clickListener: () => { clickListener: () => {
createSleevePurchaseAugsPopup(sleeve, playerRef!);
} }
}); });
elems.statsPanel.appendChild(elems.stats); elems.statsPanel.appendChild(elems.stats);

@ -898,7 +898,8 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [
const sanitizedPlayerAns: string = removeBracketsFromArrayString(ans); const sanitizedPlayerAns: string = removeBracketsFromArrayString(ans);
const sanitizedPlayerAnsArr: string[] = sanitizedPlayerAns.split(","); const sanitizedPlayerAnsArr: string[] = sanitizedPlayerAns.split(",");
for (let i = 0; i < sanitizedPlayerAnsArr.length; ++i) { for (let i = 0; i < sanitizedPlayerAnsArr.length; ++i) {
sanitizedPlayerAnsArr[i] = removeQuotesFromString(sanitizedPlayerAnsArr[i]); sanitizedPlayerAnsArr[i] = removeQuotesFromString(sanitizedPlayerAnsArr[i])
.replace(/\s/g, "");;
} }
if (num == null || num.length === 0) { if (num == null || num.length === 0) {

@ -55,7 +55,7 @@ export function displayCharacterInfo(elem: HTMLElement, p: IPlayer) {
if (src.bladeburner) { parts.push(`Bladeburner: ${numeralWrapper.formatMoney(src.bladeburner)}`) }; if (src.bladeburner) { parts.push(`Bladeburner: ${numeralWrapper.formatMoney(src.bladeburner)}`) };
if (src.codingcontract) { parts.push(`Coding Contracts: ${numeralWrapper.formatMoney(src.codingcontract)}`) }; if (src.codingcontract) { parts.push(`Coding Contracts: ${numeralWrapper.formatMoney(src.codingcontract)}`) };
if (src.work) { parts.push(`Company Work: ${numeralWrapper.formatMoney(src.work)}`) }; if (src.work) { parts.push(`Company Work: ${numeralWrapper.formatMoney(src.work)}`) };
if (src.corporation) { parts.push(`Corporation: ${numeralWrapper.formatMoney(src.corporation)}}`) }; if (src.corporation) { parts.push(`Corporation: ${numeralWrapper.formatMoney(src.corporation)}`) };
if (src.crime) { parts.push(`Crimes: ${numeralWrapper.formatMoney(src.crime)}`) }; if (src.crime) { parts.push(`Crimes: ${numeralWrapper.formatMoney(src.crime)}`) };
if (src.gang) { parts.push(`Gang: ${numeralWrapper.formatMoney(src.gang)}`) }; if (src.gang) { parts.push(`Gang: ${numeralWrapper.formatMoney(src.gang)}`) };
if (src.hacking) { parts.push(`Hacking: ${numeralWrapper.formatMoney(src.hacking)}`) }; if (src.hacking) { parts.push(`Hacking: ${numeralWrapper.formatMoney(src.hacking)}`) };

@ -0,0 +1,8 @@
// Checks whether an array is a 2D array.
// For this, a 2D array is an array which contains only other arrays.
// If one element in the array is a number or string, it is NOT a 2D array
export function is2DArray(arr: any[]): boolean {
if (arr.constructor !== Array) { return false; }
return arr.every((e) => { return e.constructor === Array; });
}

4
utils/README.md Normal file

@ -0,0 +1,4 @@
This directory contains anything that does not represent an actual component of
the game. Instead, it contains utility classes, functions, etc.
The `/helper` directory contains helper functions.