IPVGO: Tweak cheat success scaling so it is applicable even to endgame stats (#1194)

This commit is contained in:
Michael Ficocelli 2024-03-30 19:22:53 -04:00 committed by GitHub
parent 6beb6e9f95
commit 6c9555ba32
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 57 additions and 6 deletions

@ -467,7 +467,7 @@ export function initBitNodes() {
<br /> <br />
Level 2: Permanently unlocks the go.cheat API Level 2: Permanently unlocks the go.cheat API
<br /> <br />
Level 3: 25% increased success rate for the go.cheat API Level 3: 25% additive increased success rate for the go.cheat API
<br /> <br />
<br /> <br />
This Source-File also increases the maximum favor you can gain for each faction from IPvGO to: This Source-File also increases the maximum favor you can gain for each faction from IPvGO to:

@ -416,10 +416,25 @@ export async function determineCheatSuccess(
/** /**
* Cheating success rate scales with player's crime success rate, and decreases with prior cheat attempts. * Cheating success rate scales with player's crime success rate, and decreases with prior cheat attempts.
*
* The source file bonus is additive success chance on top of the other multipliers.
*
* Cheat success chance required for N cheats with 100% success rate in a game:
*
* 1 100% success rate cheat requires +66% increased crime success rate
* 2 100% success cheats: +145% increased crime success rate
* 3: +282%
* 4: +535%
* 5: +1027%
* 7: +4278%
* 10: +59,854%
* 12: +534,704%
* 15: +31,358,645%
*/ */
export function cheatSuccessChance(cheatCount: number) { export function cheatSuccessChance(cheatCount: number) {
const sourceFileBonus = Player.sourceFileLvl(14) === 3 ? 1.25 : 1; const sourceFileBonus = Player.sourceFileLvl(14) === 3 ? 0.25 : 0;
return Math.min(0.6 * 0.65 ** cheatCount * Player.mults.crime_success * sourceFileBonus, 1); const cheatCountScalar = (0.7 - 0.02 * cheatCount) ** cheatCount;
return Math.max(Math.min(0.6 * cheatCountScalar * Player.mults.crime_success + sourceFileBonus, 1), 0);
} }
/** /**

@ -243,7 +243,7 @@ export function initSourceFiles() {
<br /> <br />
Level 2: Permanently unlocks the go.cheat API in other BitNodes Level 2: Permanently unlocks the go.cheat API in other BitNodes
<br /> <br />
Level 3: 25% increased success rate for the go.cheat API Level 3: 25% additive increased success rate for the go.cheat API
<br /> <br />
<br /> <br />
This Source-File also increases the maximum favor you can gain for each faction from IPvGO to: This Source-File also increases the maximum favor you can gain for each faction from IPvGO to:

@ -1,11 +1,12 @@
import { setPlayer } from "@player"; import { Player, setPlayer } from "@player";
import { GoColor, GoOpponent, GoPlayType } from "@enums"; import { AugmentationName, GoColor, GoOpponent, GoPlayType } from "@enums";
import { Go } from "../../../src/Go/Go"; import { Go } from "../../../src/Go/Go";
import { boardStateFromSimpleBoard, simpleBoardFromBoard } from "../../../src/Go/boardAnalysis/boardAnalysis"; import { boardStateFromSimpleBoard, simpleBoardFromBoard } from "../../../src/Go/boardAnalysis/boardAnalysis";
import { import {
cheatPlayTwoMoves, cheatPlayTwoMoves,
cheatRemoveRouter, cheatRemoveRouter,
cheatRepairOfflineNode, cheatRepairOfflineNode,
cheatSuccessChance,
getChains, getChains,
getControlledEmptyNodes, getControlledEmptyNodes,
getGameState, getGameState,
@ -19,12 +20,24 @@ import {
import { PlayerObject } from "../../../src/PersonObjects/Player/PlayerObject"; import { PlayerObject } from "../../../src/PersonObjects/Player/PlayerObject";
import "../../../src/Faction/Factions"; import "../../../src/Faction/Factions";
import { getNewBoardState } from "../../../src/Go/boardState/boardState"; import { getNewBoardState } from "../../../src/Go/boardState/boardState";
import { installAugmentations } from "../../../src/Augmentation/AugmentationHelpers";
import { AddToAllServers } from "../../../src/Server/AllServers";
import { Server } from "../../../src/Server/Server";
import { initSourceFiles } from "../../../src/SourceFile/SourceFiles";
jest.mock("../../../src/Faction/Factions", () => ({ jest.mock("../../../src/Faction/Factions", () => ({
Factions: {}, Factions: {},
})); }));
jest.mock("../../../src/ui/GameRoot", () => ({
Router: {
page: () => ({}),
toPage: () => ({}),
},
}));
setPlayer(new PlayerObject()); setPlayer(new PlayerObject());
AddToAllServers(new Server({ hostname: "home" }));
describe("Netscript Go API unit tests", () => { describe("Netscript Go API unit tests", () => {
describe("makeMove() tests", () => { describe("makeMove() tests", () => {
@ -304,4 +317,27 @@ describe("Netscript Go API unit tests", () => {
expect(Go.currentGame.board[4]?.[4]?.color).toEqual(GoColor.empty); expect(Go.currentGame.board[4]?.[4]?.color).toEqual(GoColor.empty);
}); });
}); });
describe("Cheat success chance unit tests", () => {
it("should have a base chance", () => {
expect(cheatSuccessChance(0)).toEqual(0.6);
});
it("should have a scaled chance based on cheat count", () => {
expect(cheatSuccessChance(4)).toEqual(0.6 * (0.7 - 0.08) ** 4);
});
it("should have a scaled chance based on layer cheat success level", () => {
Player.setBitNodeNumber(13);
initSourceFiles();
Player.queueAugmentation(AugmentationName.BrachiBlades);
Player.queueAugmentation(AugmentationName.GrapheneBrachiBlades);
Player.queueAugmentation(AugmentationName.INFRARet);
Player.queueAugmentation(AugmentationName.PCMatrix);
Player.queueAugmentation(AugmentationName.NeuroFluxGovernor);
installAugmentations();
expect(cheatSuccessChance(4)).toEqual(0.6 * (0.7 - 0.08) ** 4 * Player.mults.crime_success);
});
});
}); });