Merge pull request #3954 from Snarling/contractFix

CONTRACTS: FIX #3755 change input handling for contract attempts
This commit is contained in:
hydroflame 2022-08-23 12:44:27 -03:00 committed by GitHub
commit fa099c22ab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 19 additions and 30 deletions

@ -1,5 +1,7 @@
import { WorkerScript } from "../Netscript/WorkerScript";
import { IPlayer } from "../PersonObjects/IPlayer";
import { Player as player } from "../Player";
import { is2DArray } from "../utils/helpers/is2DArray";
import { is2DArray } from "../utils/helpers/is2DArray
import { CodingContract } from "../CodingContracts";
import { CodingAttemptOptions, CodingContract as ICodingContract } from "../ScriptEditor/NetscriptDefinitions";
import { InternalAPI, NetscriptContext } from "../Netscript/APIWrapper";
@ -34,20 +36,11 @@ export function NetscriptCodingContract(): InternalAPI<ICodingContract> {
const hostname = helpers.string(ctx, "hostname", _hostname);
const contract = getCodingContract(ctx, "attempt", hostname, filename);
// Convert answer to string. If the answer is a 2D array, then we have to
// manually add brackets for the inner arrays
let answerStr = "";
if (is2DArray(answer)) {
const answerComponents = [];
for (let i = 0; i < answer.length; ++i) {
answerComponents.push(["[", String(answer[i]), "]"].join(""));
}
answerStr = answerComponents.join(",");
} else {
answerStr = String(answer);
}
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.
const answerStr = JSON.stringify(answer);
const creward = contract.reward;
if (creward === null) throw new Error("Somehow solved a contract that didn't have a reward");

@ -3222,7 +3222,12 @@ export interface CodingContract {
* @param opts - Optional parameters for configuring function behavior.
* @returns True if the solution was correct, false otherwise. If the returnReward option is configured, then the function will instead return a string. If the contract is successfully solved, the string will contain a description of the contracts reward. Otherwise, it will be an empty string.
*/
attempt(answer: string[] | number, filename: string, host?: string, opts?: CodingAttemptOptions): boolean | string;
attempt(
answer: string | number | any[],
filename: string,
host?: string,
opts?: CodingAttemptOptions,
): boolean | string;
/**
* Get the type of a coding contract.

@ -1422,9 +1422,13 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [
},
solver: (_data: unknown, ans: string): boolean => {
const data = _data as [number, [number, number][]];
//Sanitize player input
const sanitizedPlayerAns: string = removeBracketsFromArrayString(ans);
//Case where the player believes there is no solution.
//Attempt to construct one to check if this is correct.
if (ans == "[]") {
if (sanitizedPlayerAns === "") {
//Helper function to get neighbourhood of a vertex
function neighbourhood(vertex: number): number[] {
const adjLeft = data[1].filter(([a]) => a == vertex).map(([, b]) => b);
@ -1473,12 +1477,9 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [
return false;
}
//Sanitize player input
const sanitizedPlayerAns: string = removeBracketsFromArrayString(ans);
//Solution provided case
const sanitizedPlayerAnsArr: string[] = sanitizedPlayerAns.split(",");
const coloring: number[] = sanitizedPlayerAnsArr.map((val) => parseInt(val));
//Solution provided case
if (coloring.length == data[0]) {
const edges = data[1];
const validColors = [0, 1];

@ -1,10 +0,0 @@
export function isArray(arr: unknown): arr is unknown[] {
return Array.isArray(arr);
}
// 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: unknown): arr is unknown[][] {
return isArray(arr) && arr.every((u) => isArray(u));
}