diff --git a/src/CodingContractGenerator.js b/src/CodingContractGenerator.js new file mode 100644 index 000000000..c56290330 --- /dev/null +++ b/src/CodingContractGenerator.js @@ -0,0 +1,76 @@ +import {CodingContract, + CodingContractRewardType, + CodingContractTypes} from "./CodingContracts"; +import {Factions} from "./Faction"; +import {Player} from "./Player"; +import {AllServers} from "./Server"; + +import {getRandomInt} from "../utils/helpers/getRandomInt"; + +export function generateRandomContract() { + // First select a random problem type + const problemTypes = Object.keys(CodingContractTypes); + let randIndex = getRandomInt(0, problemTypes.length - 1); + let problemType = problemTypes[randIndex]; + + // Then select a random reward type. 'Money' will always be the last reward type + var reward = {}; + reward.type = getRandomInt(0, CodingContractRewardType.Money); + + // Change type based on certain conditions + var factionsThatAllowHacking = Player.factions.filter((fac) => { + try { + return Factions[fac].getInfo().offerHackingWork; + } catch (e) { + console.error(`Error when trying to filter Hacking Factions for Coding Contract Generation: ${e}`); + return false; + } + }); + if (reward.type === CodingContractRewardType.FactionReputation && factionsThatAllowHacking.length === 0) { + reward.type = CodingContractRewardType.CompanyReputation; + } + if (reward.type === CodingContractRewardType.FactionReputationAll && factionsThatAllowHacking.length === 0) { + reward.type = CodingContractRewardType.CompanyReputation; + } + if (reward.type === CodingContractRewardType.CompanyReputation && Player.companyName === "") { + reward.type = CodingContractRewardType.Money; + } + + // Add additional information based on the reward type + switch (reward.type) { + case CodingContractRewardType.FactionReputation: + // Get a random faction that player is a part of. That + // faction must allow hacking contracts + var numFactions = factionsThatAllowHacking.length; + var randFaction = factionsThatAllowHacking[getRandomInt(0, numFactions - 1)]; + reward.name = randFaction; + break; + case CodingContractRewardType.CompanyReputation: + if (Player.companyName !== "") { + reward.name = Player.companyName; + } else { + reward.type = CodingContractRewardType.Money; + } + break; + default: + break; + } + + // Choose random server + const servers = Object.keys(AllServers); + randIndex = getRandomInt(0, servers.length - 1); + var randServer = AllServers[servers[randIndex]]; + while (randServer.purchasedByPlayer === true) { + randIndex = getRandomInt(0, servers.length - 1); + randServer = AllServers[servers[randIndex]]; + } + + let contractFn = `contract-${getRandomInt(0, 1e6)}`; + while (randServer.contracts.filter((c) => {return c.fn === contractFn}).length > 0) { + contractFn = `contract-${getRandomInt(0, 1e6)}`; + } + if (reward.name) { contractFn += `-${reward.name.replace(/\s/g, "")}`; } + let contract = new CodingContract(contractFn, problemType, reward); + + randServer.addContract(contract); +} diff --git a/src/DevMenu.js b/src/DevMenu.js index bad2ccfd2..7226723a5 100644 --- a/src/DevMenu.js +++ b/src/DevMenu.js @@ -1,13 +1,14 @@ -import {AugmentationNames} from "./Augmentations" -import {Programs} from "./CreateProgram" -import {Factions} from "./Faction"; -import {Player} from "./Player"; -import {AllServers} from "./Server"; -import {hackWorldDaemon} from "./RedPill"; -import {Terminal} from "./Terminal"; -import {exceptionAlert} from "../utils/helpers/exceptionAlert"; -import {createElement} from "../utils/uiHelpers/createElement"; -import {removeElementById} from "../utils/uiHelpers/removeElementById"; +import {AugmentationNames} from "./Augmentations"; +import {generateRandomContract} from "./CodingContractGenerator"; +import {Programs} from "./CreateProgram"; +import {Factions} from "./Faction"; +import {Player} from "./Player"; +import {AllServers} from "./Server"; +import {hackWorldDaemon} from "./RedPill"; +import {Terminal} from "./Terminal"; +import {exceptionAlert} from "../utils/helpers/exceptionAlert"; +import {createElement} from "../utils/uiHelpers/createElement"; +import {removeElementById} from "../utils/uiHelpers/removeElementById"; const devMenuContainerId = "dev-menu-container"; @@ -60,7 +61,7 @@ export function createDevMenu() { }, innerText: "Destroy Current BitNode", tooltip: "Will grant Source-File for the BitNode", - }) + }); // Experience / stats const statsHeader = createElement("h2", { @@ -358,7 +359,18 @@ export function createDevMenu() { } }, innerText: "Add cycles to Gang mechanic", - }) + }); + + // Coding Contracts + const contractsHeader = createElement("h2", {innerText: "Coding Contracts"}); + + const generateRandomContractBtn = createElement("button", { + class: "std-button", + clickListener: () => { + generateRandomContract(); + }, + innerText: "Generate Random Contract", + }); // Add everything to container, then append to main menu const devMenuContainer = createElement("div", { diff --git a/src/data/codingcontracttypes.ts b/src/data/codingcontracttypes.ts index 15bc3a380..27c29d382 100644 --- a/src/data/codingcontracttypes.ts +++ b/src/data/codingcontracttypes.ts @@ -230,8 +230,11 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ desc: (arr: number[]) => { return ["You are given the following array of integers:\n\n", `${arr}\n\n`, - "Each element in the array represents your maximum jump length", - "at that position. Assuming you are initially positioned", + "Each element in the array represents your MAXIMUM jump length", + "at that position. This means that if you are at position i and your", + "maximum jump length is n, you can jump to any position from", + "i to i+n.", + "\n\nAssuming you are initially positioned", "at the start of the array, determine whether you are", "able to reach the last index exactly.\n\n", "Your answer should be submitted as 1 or 0, representing true and false respectively"].join(" "); @@ -242,7 +245,11 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ const arr: number[] = []; arr.length = len; for (let i: number = 0; i < arr.length; ++i) { - arr[i] = getRandomInt(0, 24); + if (Math.random() < 0.2) { + arr[i] = 0; // 20% chance of being 0 + } else { + arr[i] = getRandomInt(0, 24); + } } return arr; @@ -278,7 +285,7 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ difficulty: 3, gen: () => { const intervals: number[][] = []; - const numIntervals: number = getRandomInt(1, 15); + const numIntervals: number = getRandomInt(1, 20); for (let i: number = 0; i < numIntervals; ++i) { const start: number = getRandomInt(1, 25); const end: number = start + getRandomInt(1, 10); @@ -322,8 +329,11 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ "an array with all possible valid IP address combinations", "that can be created from the string:\n\n", `${data}\n\n`, - "Example:\n\n", - "25525511135 -> [255.255.11.135, 255.255.111.35]"].join(" "); + "Note that an octet cannot begin with a '0' unless the number", + "itself is actually 0. For example, '192.168.010.1' is not a valid IP.\n\n", + "Examples:\n\n", + "25525511135 -> [255.255.11.135, 255.255.111.35]\n", + "1938718066 -> [193.87.180.66]"].join(" "); }, difficulty: 3, gen: () => { diff --git a/src/engine.js b/src/engine.js index 87115b1fc..cd565de26 100644 --- a/src/engine.js +++ b/src/engine.js @@ -24,8 +24,7 @@ import {BitNodes, initBitNodes, import {Bladeburner} from "./Bladeburner"; import {CharacterOverview} from "./CharacterOverview"; import {cinematicTextFlag} from "./CinematicText"; -import {CodingContract, CodingContractRewardType, - CodingContractTypes} from "./CodingContracts"; +import {generateRandomContract} from "./CodingContractGenerator"; import {CompanyPositions, initCompanies} from "./Company"; import {Corporation} from "./CompanyManagement"; import {CONSTANTS} from "./Constants"; @@ -1089,71 +1088,7 @@ const Engine = { if (Engine.Counters.contractGeneration <= 0) { // X% chance of a contract being generated if (Math.random() <= 0.25) { - // First select a random problem type - const problemTypes = Object.keys(CodingContractTypes); - let randIndex = getRandomInt(0, problemTypes.length - 1); - let problemType = problemTypes[randIndex]; - - // Then select a random reward type. 'Money' will always be the last reward type - var reward = {}; - reward.type = getRandomInt(0, CodingContractRewardType.Money); - - // Change type based on certain conditions - var factionsThatAllowHacking = Player.factions.filter((fac) => { - try { - return Factions[fac].getInfo().offerHackingWork; - } catch (e) { - console.error(`Error when trying to filter Hacking Factions for Coding Contract Generation: ${e}`); - return false; - } - }); - if (reward.type === CodingContractRewardType.FactionReputation && factionsThatAllowHacking.length === 0) { - reward.type = CodingContractRewardType.CompanyReputation; - } - if (reward.type === CodingContractRewardType.FactionReputationAll && factionsThatAllowHacking.length === 0) { - reward.type = CodingContractRewardType.CompanyReputation; - } - if (reward.type === CodingContractRewardType.CompanyReputation && Player.companyName === "") { - reward.type = CodingContractRewardType.Money; - } - - // Add additional information based on the reward type - switch (reward.type) { - case CodingContractRewardType.FactionReputation: - // Get a random faction that player is a part of. That - // faction must allow hacking contracts - var numFactions = factionsThatAllowHacking.length; - var randFaction = factionsThatAllowHacking[getRandomInt(0, numFactions - 1)]; - reward.name = randFaction; - break; - case CodingContractRewardType.CompanyReputation: - if (Player.companyName !== "") { - reward.name = Player.companyName; - } else { - reward.type = CodingContractRewardType.Money; - } - break; - default: - break; - } - - // Choose random server - const servers = Object.keys(AllServers); - randIndex = getRandomInt(0, servers.length - 1); - var randServer = AllServers[servers[randIndex]]; - while (randServer.purchasedByPlayer === true) { - randIndex = getRandomInt(0, servers.length - 1); - randServer = AllServers[servers[randIndex]]; - } - - let contractFn = `contract-${getRandomInt(0, 1e6)}`; - while (randServer.contracts.filter((c) => {return c.fn === contractFn}).length > 0) { - contractFn = `contract-${getRandomInt(0, 1e6)}`; - } - if (reward.name) { contractFn += `-${reward.name.replace(/\s/g, "")}`; } - let contract = new CodingContract(contractFn, problemType, reward); - - randServer.addContract(contract); + generateRandomContract(); } Engine.Counters.contractGeneration = 3000; }