mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2026-04-16 06:18:42 +02:00
CODINGCONTRACT: Add support for other answer formats (#1892)
This commit is contained in:
@@ -1,12 +1,9 @@
|
||||
import {
|
||||
CodingContract,
|
||||
CodingContractRewardType,
|
||||
CodingContractTypes,
|
||||
ICodingContractReward,
|
||||
} from "./CodingContracts";
|
||||
import { CodingContract, CodingContractRewardType, ICodingContractReward } from "./CodingContracts";
|
||||
import { CodingContractTypes } from "./data/codingcontracttypes";
|
||||
import { currentNodeMults } from "./BitNode/BitNodeMultipliers";
|
||||
import { Factions } from "./Faction/Factions";
|
||||
import { Player } from "@player";
|
||||
import { CodingContractName } from "@enums";
|
||||
import { GetServer, GetAllServers } from "./Server/AllServers";
|
||||
import { SpecialServers } from "./Server/data/SpecialServers";
|
||||
import { Server } from "./Server/Server";
|
||||
@@ -104,7 +101,7 @@ export function generateRandomContractOnHome(): void {
|
||||
serv.addContract(contract);
|
||||
}
|
||||
|
||||
export const generateDummyContract = (problemType: string): string => {
|
||||
export const generateDummyContract = (problemType: CodingContractName): string => {
|
||||
if (!CodingContractTypes[problemType]) throw new Error(`Invalid problem type: '${problemType}'`);
|
||||
const serv = Player.getHomeComputer();
|
||||
|
||||
@@ -116,7 +113,7 @@ export const generateDummyContract = (problemType: string): string => {
|
||||
};
|
||||
|
||||
interface IGenerateContractParams {
|
||||
problemType?: string;
|
||||
problemType?: CodingContractName;
|
||||
server?: string;
|
||||
fn?: ContractFilePath;
|
||||
}
|
||||
@@ -176,8 +173,8 @@ function sanitizeRewardType(rewardType: CodingContractRewardType): CodingContrac
|
||||
return type;
|
||||
}
|
||||
|
||||
function getRandomProblemType(): string {
|
||||
const problemTypes = Object.keys(CodingContractTypes);
|
||||
function getRandomProblemType(): CodingContractName {
|
||||
const problemTypes = Object.values(CodingContractName);
|
||||
const randIndex = getRandomIntInclusive(0, problemTypes.length - 1);
|
||||
|
||||
return problemTypes[randIndex];
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
import type { FactionName } from "@enums";
|
||||
import { codingContractTypesMetadata } from "./data/codingcontracttypes";
|
||||
import { FactionName, CodingContractName } from "@enums";
|
||||
import { CodingContractTypes } from "./data/codingcontracttypes";
|
||||
|
||||
import { Generic_fromJSON, Generic_toJSON, IReviverValue, constructorsForReviver } from "./utils/JSONReviver";
|
||||
import { CodingContractEvent } from "./ui/React/CodingContractModal";
|
||||
import { ContractFilePath, resolveContractFilePath } from "./Paths/ContractFilePath";
|
||||
import { assertObject } from "./utils/TypeAssertion";
|
||||
|
||||
/* Contract Types */
|
||||
export const CodingContractTypes = Object.fromEntries(codingContractTypesMetadata.map((x) => [x.name, x]));
|
||||
|
||||
// Numeric enum
|
||||
/** Enum representing the different types of rewards a Coding Contract can give */
|
||||
export enum CodingContractRewardType {
|
||||
@@ -62,9 +59,13 @@ export class CodingContract {
|
||||
tries = 0;
|
||||
|
||||
/* String representing the contract's type. Must match type in ContractTypes */
|
||||
type: string;
|
||||
type: CodingContractName;
|
||||
|
||||
constructor(fn = "default.cct", type = "Find Largest Prime Factor", reward: ICodingContractReward | null = null) {
|
||||
constructor(
|
||||
fn = "default.cct",
|
||||
type = CodingContractName.FindLargestPrimeFactor,
|
||||
reward: ICodingContractReward | null = null,
|
||||
) {
|
||||
const path = resolveContractFilePath(fn);
|
||||
if (!path) throw new Error(`Bad file path while creating a coding contract: ${fn}`);
|
||||
if (!CodingContractTypes[type]) {
|
||||
@@ -94,12 +95,22 @@ export class CodingContract {
|
||||
return CodingContractTypes[this.type].numTries ?? 10;
|
||||
}
|
||||
|
||||
getType(): string {
|
||||
getType(): CodingContractName {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
isSolution(solution: string): boolean {
|
||||
return CodingContractTypes[this.type].solver(this.state, solution);
|
||||
/** Checks if the answer is in the correct format. */
|
||||
isValid(answer: unknown): boolean {
|
||||
if (typeof answer === "string") answer = CodingContractTypes[this.type].convertAnswer(answer);
|
||||
return CodingContractTypes[this.type].validateAnswer(answer);
|
||||
}
|
||||
|
||||
isSolution(solution: unknown): boolean {
|
||||
const type = CodingContractTypes[this.type];
|
||||
if (typeof solution === "string") solution = type.convertAnswer(solution);
|
||||
if (!this.isValid(solution)) return false;
|
||||
|
||||
return type.solver(this.state, solution);
|
||||
}
|
||||
|
||||
/** Creates a popup to prompt the player to solve the problem */
|
||||
|
||||
@@ -10,12 +10,15 @@ import Button from "@mui/material/Button";
|
||||
import Select, { SelectChangeEvent } from "@mui/material/Select";
|
||||
import MenuItem from "@mui/material/MenuItem";
|
||||
import { generateContract, generateRandomContract, generateRandomContractOnHome } from "../../CodingContractGenerator";
|
||||
import { CodingContractTypes } from "../../CodingContracts";
|
||||
import { isCodingContractName } from "../../data/codingcontracttypes";
|
||||
import { CodingContractName } from "@enums";
|
||||
|
||||
export function CodingContractsDev(): React.ReactElement {
|
||||
const [codingcontract, setCodingcontract] = useState("Find Largest Prime Factor");
|
||||
const [codingcontract, setCodingcontract] = useState(CodingContractName.FindLargestPrimeFactor);
|
||||
function setCodingcontractDropdown(event: SelectChangeEvent): void {
|
||||
setCodingcontract(event.target.value);
|
||||
const value = event.target.value;
|
||||
if (!isCodingContractName(value)) return;
|
||||
setCodingcontract(value);
|
||||
}
|
||||
|
||||
function specificContract(): void {
|
||||
@@ -42,9 +45,9 @@ export function CodingContractsDev(): React.ReactElement {
|
||||
<tr>
|
||||
<td>
|
||||
<Select onChange={setCodingcontractDropdown} value={codingcontract}>
|
||||
{Object.values(CodingContractTypes).map((cc) => (
|
||||
<MenuItem key={cc.name} value={cc.name}>
|
||||
{cc.name}
|
||||
{Object.values(CodingContractName).map((name) => (
|
||||
<MenuItem key={name} value={name}>
|
||||
{name}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
|
||||
@@ -14,3 +14,4 @@ export * from "./Programs/Enums";
|
||||
export * from "./StockMarket/Enums";
|
||||
export * from "./ui/Enums";
|
||||
export * from "./Work/Enums";
|
||||
export { CodingContractName } from "./data/codingcontracttypes";
|
||||
|
||||
@@ -333,6 +333,7 @@ const codingcontract = {
|
||||
attempt: RamCostConstants.CodingContractBase,
|
||||
getContractType: RamCostConstants.CodingContractBase / 2,
|
||||
getData: RamCostConstants.CodingContractBase / 2,
|
||||
getContract: RamCostConstants.CodingContractBase * (3 / 2),
|
||||
getDescription: RamCostConstants.CodingContractBase / 2,
|
||||
getNumTriesRemaining: RamCostConstants.CodingContractBase / 5,
|
||||
createDummyContract: RamCostConstants.CodingContractBase / 5,
|
||||
|
||||
@@ -14,6 +14,7 @@ import { Terminal } from "./Terminal";
|
||||
import { Player } from "@player";
|
||||
import {
|
||||
CityName,
|
||||
CodingContractName,
|
||||
CompletedProgramName,
|
||||
CrimeType,
|
||||
FactionWorkType,
|
||||
@@ -123,6 +124,7 @@ export const enums: NSEnums = {
|
||||
ToastVariant,
|
||||
UniversityClassType,
|
||||
CompanyName,
|
||||
CodingContractName,
|
||||
};
|
||||
for (const val of Object.values(enums)) Object.freeze(val);
|
||||
Object.freeze(enums);
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import { Player } from "@player";
|
||||
import { CodingContract } from "../CodingContracts";
|
||||
import { CodingContract as ICodingContract } from "@nsdefs";
|
||||
import { CodingContractObject, CodingContract as ICodingContract } from "@nsdefs";
|
||||
import { InternalAPI, NetscriptContext } from "../Netscript/APIWrapper";
|
||||
import { helpers } from "../Netscript/NetscriptHelpers";
|
||||
import { codingContractTypesMetadata } from "../data/codingcontracttypes";
|
||||
import { CodingContractName } from "@enums";
|
||||
import { generateDummyContract } from "../CodingContractGenerator";
|
||||
import { isCodingContractName } from "../data/codingcontracttypes";
|
||||
import { type BaseServer } from "../Server/BaseServer";
|
||||
|
||||
export function NetscriptCodingContract(): InternalAPI<ICodingContract> {
|
||||
const getCodingContract = function (ctx: NetscriptContext, hostname: string, filename: string): CodingContract {
|
||||
@@ -17,43 +19,49 @@ export function NetscriptCodingContract(): InternalAPI<ICodingContract> {
|
||||
return contract;
|
||||
};
|
||||
|
||||
function attemptContract(
|
||||
ctx: NetscriptContext,
|
||||
server: BaseServer,
|
||||
contract: CodingContract,
|
||||
answer: unknown,
|
||||
): string {
|
||||
if (contract.isSolution(answer)) {
|
||||
const reward = Player.gainCodingContractReward(contract.reward, contract.getDifficulty());
|
||||
helpers.log(ctx, () => `Successfully completed Coding Contract '${contract.fn}'. Reward: ${reward}`);
|
||||
server.removeContract(contract.fn);
|
||||
return reward;
|
||||
}
|
||||
|
||||
if (++contract.tries >= contract.getMaxNumTries()) {
|
||||
helpers.log(ctx, () => `Coding Contract attempt '${contract.fn}' failed. Contract is now self-destructing`);
|
||||
server.removeContract(contract.fn);
|
||||
} else {
|
||||
helpers.log(
|
||||
ctx,
|
||||
() =>
|
||||
`Coding Contract attempt '${contract.fn}' failed. ${
|
||||
contract.getMaxNumTries() - contract.tries
|
||||
} attempt(s) remaining.`,
|
||||
);
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
return {
|
||||
attempt: (ctx) => (answer, _filename, _hostname?) => {
|
||||
const filename = helpers.string(ctx, "filename", _filename);
|
||||
const hostname = _hostname ? helpers.string(ctx, "hostname", _hostname) : ctx.workerScript.hostname;
|
||||
const contract = getCodingContract(ctx, hostname, filename);
|
||||
|
||||
if (typeof answer !== "number" && typeof answer !== "string" && !Array.isArray(answer))
|
||||
throw new Error("The answer provided was not a number, string, or array");
|
||||
|
||||
// Convert answer to string.
|
||||
// Todo: better typing for contracts, don't do this weird string conversion of the player answer
|
||||
const answerStr = typeof answer === "string" ? answer : JSON.stringify(answer);
|
||||
const creward = contract.reward;
|
||||
if (!contract.isValid(answer))
|
||||
throw helpers.errorMessage(
|
||||
ctx,
|
||||
`Answer is not in the right format for contract '${contract.type}'. Got: ${answer}`,
|
||||
);
|
||||
|
||||
const serv = helpers.getServer(ctx, hostname);
|
||||
if (contract.isSolution(answerStr)) {
|
||||
const reward = Player.gainCodingContractReward(creward, contract.getDifficulty());
|
||||
helpers.log(ctx, () => `Successfully completed Coding Contract '${filename}'. Reward: ${reward}`);
|
||||
serv.removeContract(filename);
|
||||
return reward;
|
||||
} else {
|
||||
++contract.tries;
|
||||
if (contract.tries >= contract.getMaxNumTries()) {
|
||||
helpers.log(ctx, () => `Coding Contract attempt '${filename}' failed. Contract is now self-destructing`);
|
||||
serv.removeContract(filename);
|
||||
} else {
|
||||
helpers.log(
|
||||
ctx,
|
||||
() =>
|
||||
`Coding Contract attempt '${filename}' failed. ${
|
||||
contract.getMaxNumTries() - contract.tries
|
||||
} attempts remaining.`,
|
||||
);
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
return attemptContract(ctx, serv, contract, answer);
|
||||
},
|
||||
getContractType: (ctx) => (_filename, _hostname?) => {
|
||||
const filename = helpers.string(ctx, "filename", _filename);
|
||||
@@ -65,8 +73,29 @@ export function NetscriptCodingContract(): InternalAPI<ICodingContract> {
|
||||
const filename = helpers.string(ctx, "filename", _filename);
|
||||
const hostname = _hostname ? helpers.string(ctx, "hostname", _hostname) : ctx.workerScript.hostname;
|
||||
const contract = getCodingContract(ctx, hostname, filename);
|
||||
|
||||
return structuredClone(contract.getData());
|
||||
},
|
||||
getContract: (ctx) => (_filename, _hostname?) => {
|
||||
const filename = helpers.string(ctx, "filename", _filename);
|
||||
const hostname = _hostname ? helpers.string(ctx, "hostname", _hostname) : ctx.workerScript.hostname;
|
||||
const server = helpers.getServer(ctx, hostname);
|
||||
const contract = getCodingContract(ctx, hostname, filename);
|
||||
// asserting type here is required, since it is not feasible to properly type getData
|
||||
return {
|
||||
type: contract.type,
|
||||
data: contract.getData(),
|
||||
submit: (answer: unknown) => {
|
||||
helpers.checkEnvFlags(ctx);
|
||||
return attemptContract(ctx, server, contract, answer);
|
||||
},
|
||||
description: contract.getDescription(),
|
||||
numTriesRemaining: () => {
|
||||
helpers.checkEnvFlags(ctx);
|
||||
return contract.getMaxNumTries() - contract.tries;
|
||||
},
|
||||
} as CodingContractObject;
|
||||
},
|
||||
getDescription: (ctx) => (_filename, _hostname?) => {
|
||||
const filename = helpers.string(ctx, "filename", _filename);
|
||||
const hostname = _hostname ? helpers.string(ctx, "hostname", _hostname) : ctx.workerScript.hostname;
|
||||
@@ -81,8 +110,10 @@ export function NetscriptCodingContract(): InternalAPI<ICodingContract> {
|
||||
},
|
||||
createDummyContract: (ctx) => (_type) => {
|
||||
const type = helpers.string(ctx, "type", _type);
|
||||
if (!isCodingContractName(type))
|
||||
return helpers.errorMessage(ctx, `The given type is not a valid contract type. Got '${type}'`);
|
||||
return generateDummyContract(type);
|
||||
},
|
||||
getContractTypes: () => () => codingContractTypesMetadata.map((c) => c.name),
|
||||
getContractTypes: () => () => Object.values(CodingContractName),
|
||||
};
|
||||
}
|
||||
|
||||
125
src/ScriptEditor/NetscriptDefinitions.d.ts
vendored
125
src/ScriptEditor/NetscriptDefinitions.d.ts
vendored
@@ -17,13 +17,6 @@ interface Skills {
|
||||
intelligence: number;
|
||||
}
|
||||
|
||||
// TODO: provide same treatment to CodingContractData as for SleeveTask (actual types)
|
||||
/**
|
||||
* Coding contract data will differ depending on coding contract.
|
||||
* @public
|
||||
*/
|
||||
type CodingContractData = any;
|
||||
|
||||
/** @public */
|
||||
type ScriptArg = string | number | boolean;
|
||||
|
||||
@@ -3864,7 +3857,9 @@ export interface CodingContract {
|
||||
*
|
||||
* @example
|
||||
* ```js
|
||||
* const reward = ns.codingcontract.attempt(yourSolution, filename, hostname);
|
||||
* const reward = ns.codingcontract.attempt("[solution, as, a, string]", filename, hostname);
|
||||
* // or
|
||||
* const reward = ns.codingcontract.attempt(["answer", "as", "an", "array"], filename, hostname);
|
||||
* if (reward) {
|
||||
* ns.tprint(`Contract solved successfully! Reward: ${reward}`);
|
||||
* } else {
|
||||
@@ -3872,13 +3867,13 @@ export interface CodingContract {
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @param answer - Attempted solution for the contract.
|
||||
* @param answer - Attempted solution for the contract. This can be a string formatted like submitting manually, or the answer in the format of the specific contract type.
|
||||
* @param filename - Filename of the contract.
|
||||
* @param host - Hostname of the server containing the contract. Optional. Defaults to current server if not
|
||||
* provided.
|
||||
* @returns A reward description string on success, or an empty string on failure.
|
||||
*/
|
||||
attempt(answer: string | number | any[], filename: string, host?: string): string;
|
||||
attempt(answer: any, filename: string, host?: string): string;
|
||||
|
||||
/**
|
||||
* Get the type of a coding contract.
|
||||
@@ -3892,7 +3887,7 @@ export interface CodingContract {
|
||||
* @param host - Hostname of the server containing the contract. Optional. Defaults to current server if not provided.
|
||||
* @returns Name describing the type of problem posed by the Coding Contract.
|
||||
*/
|
||||
getContractType(filename: string, host?: string): string;
|
||||
getContractType(filename: string, host?: string): `${CodingContractName}`;
|
||||
|
||||
/**
|
||||
* Get the description.
|
||||
@@ -3920,7 +3915,31 @@ export interface CodingContract {
|
||||
* @param host - Host of the server containing the contract. Optional. Defaults to current server if not provided.
|
||||
* @returns The specified contract’s data, data type depends on contract type.
|
||||
*/
|
||||
getData(filename: string, host?: string): CodingContractData;
|
||||
getData(filename: string, host?: string): any;
|
||||
|
||||
/**
|
||||
* Get various data about a specific contract.
|
||||
* @remarks
|
||||
* RAM cost: 15 GB
|
||||
*
|
||||
* The returned object includes the type, data, description as well as methods for getting the number of tries remaining and submitting your answer.
|
||||
* Depending on the type of the contract, the data is typed differently.
|
||||
* Using type-narrowing, you can get the correct type of the data:
|
||||
*
|
||||
* @example
|
||||
* ```js
|
||||
* const contract = ns.codingcontract.getContract(fileName, hostName);
|
||||
* if (contract.type === ns.enums.CodingContractName.FindLargestPrimeFactor) {
|
||||
* const data = contract.data;
|
||||
* // ^? data: number
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @param filename - Filename of the contract.
|
||||
* @param host - Host of the server containing the contract. Optional. Default to the current server if not provided.
|
||||
* @returns An object containing various data about the contract specified.
|
||||
*/
|
||||
getContract(filename: string, host?: string): CodingContractObject;
|
||||
|
||||
/**
|
||||
* Get the number of attempts remaining.
|
||||
@@ -3952,7 +3971,7 @@ export interface CodingContract {
|
||||
* @remarks
|
||||
* RAM cost: 0 GB
|
||||
*/
|
||||
getContractTypes(): string[];
|
||||
getContractTypes(): `${CodingContractName}`[];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -8331,6 +8350,85 @@ declare enum CompanyName {
|
||||
NoodleBar = "Noodle Bar",
|
||||
}
|
||||
|
||||
declare enum CodingContractName {
|
||||
FindLargestPrimeFactor = "Find Largest Prime Factor",
|
||||
SubarrayWithMaximumSum = "Subarray with Maximum Sum",
|
||||
TotalWaysToSum = "Total Ways to Sum",
|
||||
TotalWaysToSumII = "Total Ways to Sum II",
|
||||
SpiralizeMatrix = "Spiralize Matrix",
|
||||
ArrayJumpingGame = "Array Jumping Game",
|
||||
ArrayJumpingGameII = "Array Jumping Game II",
|
||||
MergeOverlappingIntervals = "Merge Overlapping Intervals",
|
||||
GenerateIPAddresses = "Generate IP Addresses",
|
||||
AlgorithmicStockTraderI = "Algorithmic Stock Trader I",
|
||||
AlgorithmicStockTraderII = "Algorithmic Stock Trader II",
|
||||
AlgorithmicStockTraderIII = "Algorithmic Stock Trader III",
|
||||
AlgorithmicStockTraderIV = "Algorithmic Stock Trader IV",
|
||||
MinimumPathSumInATriangle = "Minimum Path Sum in a Triangle",
|
||||
UniquePathsInAGridI = "Unique Paths in a Grid I",
|
||||
UniquePathsInAGridII = "Unique Paths in a Grid II",
|
||||
ShortestPathInAGrid = "Shortest Path in a Grid",
|
||||
SanitizeParenthesesInExpression = "Sanitize Parentheses in Expression",
|
||||
FindAllValidMathExpressions = "Find All Valid Math Expressions",
|
||||
HammingCodesIntegerToEncodedBinary = "HammingCodes: Integer to Encoded Binary",
|
||||
HammingCodesEncodedBinaryToInteger = "HammingCodes: Encoded Binary to Integer",
|
||||
Proper2ColoringOfAGraph = "Proper 2-Coloring of a Graph",
|
||||
CompressionIRLECompression = "Compression I: RLE Compression",
|
||||
CompressionIILZDecompression = "Compression II: LZ Decompression",
|
||||
CompressionIIILZCompression = "Compression III: LZ Compression",
|
||||
EncryptionICaesarCipher = "Encryption I: Caesar Cipher",
|
||||
EncryptionIIVigenereCipher = "Encryption II: Vigenère Cipher",
|
||||
SquareRoot = "Square Root",
|
||||
}
|
||||
|
||||
export type CodingContractSignatures = {
|
||||
[CodingContractName.FindLargestPrimeFactor]: [number, number];
|
||||
[CodingContractName.SubarrayWithMaximumSum]: [number[], number];
|
||||
[CodingContractName.TotalWaysToSum]: [number, number];
|
||||
[CodingContractName.TotalWaysToSumII]: [[number, number[]], number];
|
||||
[CodingContractName.SpiralizeMatrix]: [number[][], number[]];
|
||||
[CodingContractName.ArrayJumpingGame]: [number[], 1 | 0];
|
||||
[CodingContractName.ArrayJumpingGameII]: [number[], number];
|
||||
[CodingContractName.MergeOverlappingIntervals]: [[number, number][], [number, number][]];
|
||||
[CodingContractName.GenerateIPAddresses]: [string, string[]];
|
||||
[CodingContractName.AlgorithmicStockTraderI]: [number[], number];
|
||||
[CodingContractName.AlgorithmicStockTraderII]: [number[], number];
|
||||
[CodingContractName.AlgorithmicStockTraderIII]: [number[], number];
|
||||
[CodingContractName.AlgorithmicStockTraderIV]: [[number, number[]], number];
|
||||
[CodingContractName.MinimumPathSumInATriangle]: [number[][], number];
|
||||
[CodingContractName.UniquePathsInAGridI]: [[number, number], number];
|
||||
[CodingContractName.UniquePathsInAGridII]: [(1 | 0)[][], number];
|
||||
[CodingContractName.ShortestPathInAGrid]: [(1 | 0)[][], string];
|
||||
[CodingContractName.SanitizeParenthesesInExpression]: [string, string[]];
|
||||
[CodingContractName.FindAllValidMathExpressions]: [[string, number], string[]];
|
||||
[CodingContractName.HammingCodesIntegerToEncodedBinary]: [number, string];
|
||||
[CodingContractName.HammingCodesEncodedBinaryToInteger]: [string, number];
|
||||
[CodingContractName.Proper2ColoringOfAGraph]: [[number, [number, number][]], (1 | 0)[]];
|
||||
[CodingContractName.CompressionIRLECompression]: [string, string];
|
||||
[CodingContractName.CompressionIILZDecompression]: [string, string];
|
||||
[CodingContractName.CompressionIIILZCompression]: [string, string];
|
||||
[CodingContractName.EncryptionICaesarCipher]: [[string, number], string];
|
||||
[CodingContractName.EncryptionIIVigenereCipher]: [[string, string], string];
|
||||
[CodingContractName.SquareRoot]: [bigint, bigint, [string, string]];
|
||||
};
|
||||
|
||||
export type CodingContractData<T extends string> = T extends `${keyof CodingContractSignatures}`
|
||||
? CodingContractSignatures[T][0]
|
||||
: any;
|
||||
export type CodingContractAnswer<T extends string> = T extends `${keyof CodingContractSignatures}`
|
||||
? CodingContractSignatures[T][1]
|
||||
: any;
|
||||
|
||||
export type CodingContractObject = {
|
||||
[T in keyof CodingContractSignatures]: {
|
||||
type: T;
|
||||
data: CodingContractSignatures[T][0];
|
||||
submit: (answer: CodingContractSignatures[T][1] | string) => string;
|
||||
description: string;
|
||||
numTriesRemaining: () => number;
|
||||
};
|
||||
}[keyof CodingContractSignatures];
|
||||
|
||||
/** @public */
|
||||
export type NSEnums = {
|
||||
CityName: typeof CityName;
|
||||
@@ -8343,6 +8441,7 @@ export type NSEnums = {
|
||||
ToastVariant: typeof ToastVariant;
|
||||
UniversityClassType: typeof UniversityClassType;
|
||||
CompanyName: typeof CompanyName;
|
||||
CodingContractName: typeof CodingContractName;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,8 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { KEY } from "../../utils/helpers/keyCodes";
|
||||
|
||||
import { CodingContract, CodingContractTypes } from "../../CodingContracts";
|
||||
import { CodingContract } from "../../CodingContracts";
|
||||
import { CodingContractTypes } from "../../data/codingcontracttypes";
|
||||
import { CopyableText } from "./CopyableText";
|
||||
import { Modal } from "./Modal";
|
||||
import { EventEmitter } from "../../utils/EventEmitter";
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||
|
||||
import { Player } from "@player";
|
||||
import { AugmentationName, LocationName } from "@enums";
|
||||
import { AugmentationName, CodingContractName, LocationName } from "@enums";
|
||||
import { AddToAllServers, createUniqueRandomIp, GetAllServers, GetServer, renameServer } from "../Server/AllServers";
|
||||
import { StockMarket } from "../StockMarket/StockMarket";
|
||||
import { AwardNFG, v1APIBreak } from "./v1APIBreak";
|
||||
@@ -168,8 +168,8 @@ export function evaluateVersionCompatibility(ver: string | number): void {
|
||||
for (const contract of server.contracts) {
|
||||
//Rename old "HammingCodes: Integer to encoded Binary" contracts
|
||||
//to "HammingCodes: Integer to Encoded Binary"
|
||||
if (contract.type == "HammingCodes: Integer to encoded Binary") {
|
||||
contract.type = "HammingCodes: Integer to Encoded Binary";
|
||||
if ((contract.type as string) == "HammingCodes: Integer to encoded Binary") {
|
||||
contract.type = CodingContractName.HammingCodesIntegerToEncodedBinary;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user