CONTRACTS: Proposal for Contract Progression System (#2230)

This commit is contained in:
gmcew
2025-07-10 22:25:36 +01:00
committed by GitHub
parent c5799616ce
commit 3fc65a2de4
9 changed files with 21 additions and 16 deletions

View File

@@ -14,6 +14,7 @@ export type CodingContractObject = {
data: CodingContractSignatures[T][0]; data: CodingContractSignatures[T][0];
submit: (answer: CodingContractSignatures[T][1] | string) => string; submit: (answer: CodingContractSignatures[T][1] | string) => string;
description: string; description: string;
difficulty: number;
numTriesRemaining: () => number; numTriesRemaining: () => number;
}; };
}[keyof CodingContractSignatures]; }[keyof CodingContractSignatures];

View File

@@ -70,17 +70,20 @@ export function tryGeneratingRandomContract(numberOfTries: number): void {
} }
export function generateRandomContract(): void { export function generateRandomContract(): void {
// First select a random problem type
const problemType = getRandomProblemType();
// Then select a random reward type. 'Money' will always be the last reward type
const reward = getRandomReward();
// Choose random server // Choose random server
const randServer = getRandomServer(); const randServer = getRandomServer();
if (randServer === null) { if (randServer === null) {
return; return;
} }
// Then select a random reward type. 'Money' will always be the last reward type
const reward = getRandomReward();
// Finally select a random problem type.
// Difficulty is capped to not overwhelm a new player.
const totalSFs = [...Player.sourceFiles].reduce<number>((total, [__bn, lvl]) => (total += lvl), 0);
const maxDif = 2 * totalSFs + 1;
const problemType = getRandomProblemType(maxDif);
const contractFn = getRandomFilename(randServer, reward); const contractFn = getRandomFilename(randServer, reward);
const contract = new CodingContract(contractFn, problemType, reward); const contract = new CodingContract(contractFn, problemType, reward);
@@ -179,8 +182,8 @@ function sanitizeRewardType(rewardType: CodingContractRewardType): CodingContrac
return type; return type;
} }
function getRandomProblemType(): CodingContractName { function getRandomProblemType(maxDif = 10): CodingContractName {
const problemTypes = Object.values(CodingContractName); const problemTypes = Object.values(CodingContractName).filter((x) => CodingContractTypes[x].difficulty <= maxDif);
const randIndex = getRandomIntInclusive(0, problemTypes.length - 1); const randIndex = getRandomIntInclusive(0, problemTypes.length - 1);
return problemTypes[randIndex]; return problemTypes[randIndex];

View File

@@ -96,7 +96,7 @@ export const algorithmicStockTrader: Pick<
"If no profit can be made, then the answer should be 0.", "If no profit can be made, then the answer should be 0.",
].join(" "); ].join(" ");
}, },
difficulty: 5, difficulty: 4,
generate: (): number[] => { generate: (): number[] => {
const len: number = getRandomIntInclusive(3, 50); const len: number = getRandomIntInclusive(3, 50);
const arr: number[] = []; const arr: number[] = [];

View File

@@ -21,7 +21,7 @@ export const arrayJumpingGame: Pick<
"Your answer should be submitted as 1 or 0, representing true and false respectively.", "Your answer should be submitted as 1 or 0, representing true and false respectively.",
].join(" "); ].join(" ");
}, },
difficulty: 2.5, difficulty: 2,
generate: (): number[] => { generate: (): number[] => {
const len: number = getRandomIntInclusive(3, 25); const len: number = getRandomIntInclusive(3, 25);
const arr: number[] = []; const arr: number[] = [];

View File

@@ -8,7 +8,7 @@ export const hammingCode: Pick<
CodingContractName.HammingCodesEncodedBinaryToInteger | CodingContractName.HammingCodesIntegerToEncodedBinary CodingContractName.HammingCodesEncodedBinaryToInteger | CodingContractName.HammingCodesIntegerToEncodedBinary
> = { > = {
[CodingContractName.HammingCodesIntegerToEncodedBinary]: { [CodingContractName.HammingCodesIntegerToEncodedBinary]: {
difficulty: 5, difficulty: 6,
desc: (n: number): string => { desc: (n: number): string => {
return [ return [
"You are given the following decimal value: \n", "You are given the following decimal value: \n",
@@ -43,7 +43,7 @@ export const hammingCode: Pick<
validateAnswer: (ans): ans is string => typeof ans === "string", validateAnswer: (ans): ans is string => typeof ans === "string",
}, },
[CodingContractName.HammingCodesEncodedBinaryToInteger]: { [CodingContractName.HammingCodesEncodedBinaryToInteger]: {
difficulty: 8, difficulty: 9,
desc: (n: string): string => { desc: (n: string): string => {
return [ return [
"You are given the following encoded binary string: \n", "You are given the following encoded binary string: \n",

View File

@@ -18,7 +18,7 @@ export const totalWaysToSum: Pick<
"two positive integers?", "two positive integers?",
].join(" "); ].join(" ");
}, },
difficulty: 1.5, difficulty: 1,
generate: (): number => { generate: (): number => {
return getRandomIntInclusive(8, 100); return getRandomIntInclusive(8, 100);
}, },

View File

@@ -8,7 +8,7 @@ They can be accessed through the [Terminal](terminal.md) or through [Scripts](sc
Each contract has a limited number of attempts. Each contract has a limited number of attempts.
If you provide the wrong answer too many times and exceed the number of attempts, the contract will self destruct (delete itself). If you provide the wrong answer too many times and exceed the number of attempts, the contract will self destruct (delete itself).
Currently, Coding Contracts are randomly generated and spawned over time. Coding Contracts are randomly generated and spawn over time. Initially, you'll only see a small range of the easier contracts, but as you progress further through the game more challenging ones will unlock.
They can appear on any [server](servers.md) (including your home computer), except for your purchased [servers](servers.md). They can appear on any [server](servers.md) (including your home computer), except for your purchased [servers](servers.md).
## Running in Terminal ## Running in Terminal
@@ -27,6 +27,7 @@ Interacting with Coding Contracts via the [Terminal](terminal.md) can be tedious
Consider using the [API](https://github.com/bitburner-official/bitburner-src/blob/stable/markdown/bitburner.codingcontract.md) to automate various aspects of your solution. Consider using the [API](https://github.com/bitburner-official/bitburner-src/blob/stable/markdown/bitburner.codingcontract.md) to automate various aspects of your solution.
For example, some contracts have long solutions while others have even longer solutions. For example, some contracts have long solutions while others have even longer solutions.
You might want to use the [API](https://github.com/bitburner-official/bitburner-src/blob/stable/markdown/bitburner.codingcontract.md) to automate the process of submitting your solution rather than copy and paste a long solution into an answer box. You might want to use the [API](https://github.com/bitburner-official/bitburner-src/blob/stable/markdown/bitburner.codingcontract.md) to automate the process of submitting your solution rather than copy and paste a long solution into an answer box.
The [Coding Contract API](https://github.com/bitburner-official/bitburner-src/blob/stable/markdown/bitburner.codingcontract.md) can also be used to find out useful information about a contract including the number of attempts you have left, the type of contract and its difficulty.
However, using the [API](https://github.com/bitburner-official/bitburner-src/blob/stable/markdown/bitburner.codingcontract.md) comes at a cost. However, using the [API](https://github.com/bitburner-official/bitburner-src/blob/stable/markdown/bitburner.codingcontract.md) comes at a cost.
Like most functions in other APIs, almost all of the functions in the [Coding Contract API](https://github.com/bitburner-official/bitburner-src/blob/stable/markdown/bitburner.codingcontract.md) have a RAM cost. Like most functions in other APIs, almost all of the functions in the [Coding Contract API](https://github.com/bitburner-official/bitburner-src/blob/stable/markdown/bitburner.codingcontract.md) have a RAM cost.
@@ -67,7 +68,6 @@ There are currently four possible rewards for solving a Coding Contract:
- Money - Money
The `amount` of the reward varies based on the difficulty of the problem posed by the Coding Contract. The `amount` of the reward varies based on the difficulty of the problem posed by the Coding Contract.
There is no way to know what a Coding Contract's exact reward will be until it is solved.
## Notes ## Notes

View File

@@ -92,7 +92,6 @@ export function NetscriptCodingContract(): InternalAPI<ICodingContract> {
const filename = helpers.string(ctx, "filename", _filename); const filename = helpers.string(ctx, "filename", _filename);
const host = _host ? helpers.string(ctx, "host", _host) : ctx.workerScript.hostname; const host = _host ? helpers.string(ctx, "host", _host) : ctx.workerScript.hostname;
const contract = getCodingContract(ctx, host, filename); const contract = getCodingContract(ctx, host, filename);
return structuredClone(contract.getData()); return structuredClone(contract.getData());
}, },
getContract: (ctx) => (_filename, _host?) => { getContract: (ctx) => (_filename, _host?) => {
@@ -109,6 +108,7 @@ export function NetscriptCodingContract(): InternalAPI<ICodingContract> {
return attemptContract(ctx, server, contract, answer); return attemptContract(ctx, server, contract, answer);
}, },
description: contract.getDescription(), description: contract.getDescription(),
difficulty: contract.getDifficulty(),
numTriesRemaining: () => { numTriesRemaining: () => {
helpers.checkEnvFlags(ctx); helpers.checkEnvFlags(ctx);
return contract.getMaxNumTries() - contract.tries; return contract.getMaxNumTries() - contract.tries;

View File

@@ -8780,6 +8780,7 @@ export type CodingContractObject = {
data: CodingContractSignatures[T][0]; data: CodingContractSignatures[T][0];
submit: (answer: CodingContractSignatures[T][1] | string) => string; submit: (answer: CodingContractSignatures[T][1] | string) => string;
description: string; description: string;
difficulty: number;
numTriesRemaining: () => number; numTriesRemaining: () => number;
}; };
}[keyof CodingContractSignatures]; }[keyof CodingContractSignatures];