Skip to content

Commit

Permalink
CODEBASE: Fix lint errors 4 (bitburner-official#1773)
Browse files Browse the repository at this point in the history
Co-authored-by: Michael Ficocelli <[email protected]>
  • Loading branch information
catloversg and ficocelliguy authored Nov 14, 2024
1 parent 4f84a89 commit 97ca8c5
Show file tree
Hide file tree
Showing 23 changed files with 123 additions and 99 deletions.
11 changes: 6 additions & 5 deletions src/Go/SaveLoad.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ export function loadGo(data: unknown): boolean {
// If it's the AI's turn, initiate their turn, which will populate nextTurn
if (currentGame.previousPlayer === GoColor.black && currentGame.ai !== GoOpponent.none) {
makeAIMove(currentGame).catch((error) => {
showError(error);
showError(new Error(`Error while making first IPvGO AI move: ${error}`, { cause: error }));
});
}
// If it's not the AI's turn and we're not in gameover status, initialize nextTurn promise based on the previous move/pass
Expand Down Expand Up @@ -152,9 +152,10 @@ function loadStats(stats: unknown): PartialRecord<GoOpponent, OpponentStats> | s
const entries = Object.entries(stats);
for (const [opponent, opponentStats] of entries) {
if (!getEnumHelper("GoOpponent").isMember(opponent)) return `Invalid opponent in Go.stats: ${opponent}`;
if (!opponentStats || typeof opponentStats !== "object") "Non-object encountered for an opponent's stats";
assertLoadingType<OpponentStats>(opponentStats);
const { favor, highestWinStreak, losses, nodes, wins, oldWinStreak, winStreak, nodePower } = opponentStats;
if (!opponentStats || typeof opponentStats !== "object") return "Non-object encountered for an opponent's stats";
assertLoadingType<OpponentStats>(opponentStats as object);
const { favor, highestWinStreak, losses, nodes, wins, oldWinStreak, winStreak, nodePower } =
opponentStats as OpponentStats;
// Integers >= 0. Todo: make a better helper for this.
if (!isInteger(favor) || favor < 0) return "A favor entry in Go.stats was invalid";
if (!isInteger(highestWinStreak) || highestWinStreak < 0) return "A highestWinStreak entry in Go.stats was invalid";
Expand Down Expand Up @@ -183,7 +184,7 @@ function loadSimpleBoard(simpleBoard: unknown, requiredSize?: number): SimpleBoa
if (!simpleBoard.every((column) => typeof column === "string" && column.length === requiredSize)) {
return "Incorrect types or column size while loading a SimpleBoard.";
}
return simpleBoard;
return simpleBoard as SimpleBoard;
}

function loadStoredCycles(storedCycles: unknown): number {
Expand Down
18 changes: 15 additions & 3 deletions src/Go/Types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export type Move = {
createsLife?: boolean;
};

type MoveType =
export type MoveType =
| "capture"
| "defendCapture"
| "eyeMove"
Expand All @@ -25,8 +25,20 @@ type MoveType =
| "corner"
| "random";

type MoveFunction = () => Promise<Move | null>;
export type MoveOptions = Record<MoveType, MoveFunction>;
export type MoveOptions = {
readonly eyeMove: () => Move | null;
readonly random: () => Move | null;
readonly defendCapture: () => Promise<Move | null>;
readonly corner: () => Move | null;
readonly defend: () => Move | null;
readonly pattern: () => Promise<Move | null>;
readonly capture: () => Promise<Move | null>;
readonly growth: () => Move | null;
readonly eyeBlock: () => Move | null;
readonly surround: () => Move | null;
readonly expansion: () => Move | null;
readonly jump: () => Move | null;
};

export type EyeMove = {
point: PointState;
Expand Down
10 changes: 4 additions & 6 deletions src/Go/boardAnalysis/boardAnalysis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -696,16 +696,14 @@ export function getPreviousMove(): [number, number] | null {
return null;
}

for (const rowIndexString in Go.currentGame.board) {
const row = Go.currentGame.board[+rowIndexString] ?? [];
for (const pointIndexString in row) {
const point = row[+pointIndexString];
const priorColor = point && priorBoard && getColorOnBoardString(priorBoard, point.x, point.y);
for (const [rowIndex, row] of Go.currentGame.board.entries()) {
for (const [pointIndex, point] of row.entries()) {
const priorColor = point && getColorOnBoardString(priorBoard, point.x, point.y);
const currentColor = point?.color;
const isPreviousPlayer = currentColor === Go.currentGame.previousPlayer;
const isChanged = priorColor !== currentColor;
if (priorColor && currentColor && isPreviousPlayer && isChanged) {
return [+rowIndexString, +pointIndexString];
return [rowIndex, pointIndex];
}
}
}
Expand Down
103 changes: 48 additions & 55 deletions src/Go/boardAnalysis/goAI.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Board, BoardState, EyeMove, Move, MoveOptions, Play, PointState } from "../Types";
import type { Board, BoardState, EyeMove, Move, MoveOptions, MoveType, Play, PointState } from "../Types";

import { Player } from "@player";
import { AugmentationName, GoColor, GoOpponent, GoPlayType } from "@enums";
Expand Down Expand Up @@ -153,13 +153,13 @@ export async function getMove(

// If no priority move is chosen, pick one of the reasonable moves
const moveOptions = [
(await moves.growth())?.point,
(await moves.surround())?.point,
(await moves.defend())?.point,
(await moves.expansion())?.point,
moves.growth()?.point,
moves.surround()?.point,
moves.defend()?.point,
moves.expansion()?.point,
(await moves.pattern())?.point,
(await moves.eyeMove())?.point,
(await moves.eyeBlock())?.point,
moves.eyeMove()?.point,
moves.eyeBlock()?.point,
]
.filter(isNotNullish)
.filter((point) => evaluateIfMoveIsValid(boardState, point.x, point.y, player, false));
Expand Down Expand Up @@ -221,12 +221,12 @@ function isSmart(faction: GoOpponent, rng: number) {
async function getNetburnersPriorityMove(moves: MoveOptions, rng: number): Promise<PointState | null> {
if (rng < 0.2) {
return getIlluminatiPriorityMove(moves, rng);
} else if (rng < 0.4 && (await moves.expansion())) {
return (await moves.expansion())?.point ?? null;
} else if (rng < 0.6 && (await moves.growth())) {
return (await moves.growth())?.point ?? null;
} else if (rng < 0.4 && moves.expansion()) {
return moves.expansion()?.point ?? null;
} else if (rng < 0.6 && moves.growth()) {
return moves.growth()?.point ?? null;
} else if (rng < 0.75) {
return (await moves.random())?.point ?? null;
return moves.random()?.point ?? null;
}

return null;
Expand All @@ -242,10 +242,10 @@ async function getSlumSnakesPriorityMove(moves: MoveOptions, rng: number): Promi

if (rng < 0.2) {
return getIlluminatiPriorityMove(moves, rng);
} else if (rng < 0.6 && (await moves.growth())) {
return (await moves.growth())?.point ?? null;
} else if (rng < 0.6 && moves.growth()) {
return moves.growth()?.point ?? null;
} else if (rng < 0.65) {
return (await moves.random())?.point ?? null;
return moves.random()?.point ?? null;
}

return null;
Expand All @@ -260,7 +260,7 @@ async function getBlackHandPriorityMove(moves: MoveOptions, rng: number): Promis
return (await moves.capture())?.point ?? null;
}

const surround = await moves.surround();
const surround = moves.surround();

if (surround && surround.point && (surround.newLibertyCount ?? 999) <= 1) {
//console.debug("surround move chosen");
Expand All @@ -282,7 +282,7 @@ async function getBlackHandPriorityMove(moves: MoveOptions, rng: number): Promis
} else if (rng < 0.75 && surround) {
return surround.point;
} else if (rng < 0.8) {
return (await moves.random())?.point ?? null;
return moves.random()?.point ?? null;
}

return null;
Expand All @@ -307,7 +307,7 @@ async function getTetradPriorityMove(moves: MoveOptions, rng: number): Promise<P
return (await moves.pattern())?.point ?? null;
}

const surround = await moves.surround();
const surround = moves.surround();
if (surround && surround.point && (surround?.newLibertyCount ?? 9) <= 1) {
//console.debug("surround move chosen");
return surround.point;
Expand Down Expand Up @@ -350,40 +350,38 @@ async function getIlluminatiPriorityMove(moves: MoveOptions, rng: number): Promi
return (await moves.defendCapture())?.point ?? null;
}

if (await moves.eyeMove()) {
if (moves.eyeMove()) {
//console.debug("Create eye move chosen");
return (await moves.eyeMove())?.point ?? null;
return moves.eyeMove()?.point ?? null;
}

const surround = await moves.surround();
const surround = moves.surround();
if (surround && surround.point && (surround?.newLibertyCount ?? 9) <= 1) {
//console.debug("surround move chosen");
return surround.point;
}

if (await moves.eyeBlock()) {
if (moves.eyeBlock()) {
//console.debug("Block eye move chosen");
return (await moves.eyeBlock())?.point ?? null;
return moves.eyeBlock()?.point ?? null;
}

if (await moves.corner()) {
if (moves.corner()) {
//console.debug("Corner move chosen");
return (await moves.corner())?.point ?? null;
return moves.corner()?.point ?? null;
}

const hasMoves = [await moves.eyeMove(), await moves.eyeBlock(), await moves.growth(), moves.defend, surround].filter(
(m) => m,
).length;
const hasMoves = [moves.eyeMove(), moves.eyeBlock(), moves.growth(), moves.defend, surround].filter((m) => m).length;
const usePattern = rng > 0.25 || !hasMoves;

if ((await moves.pattern()) && usePattern) {
//console.debug("pattern match move chosen");
return (await moves.pattern())?.point ?? null;
}

if (rng > 0.4 && (await moves.jump())) {
if (rng > 0.4 && moves.jump()) {
//console.debug("Jump move chosen");
return (await moves.jump())?.point ?? null;
return moves.jump()?.point ?? null;
}

if (rng < 0.6 && surround && surround.point && (surround?.newLibertyCount ?? 9) <= 2) {
Expand Down Expand Up @@ -508,7 +506,7 @@ function getDisputedTerritoryMoves(board: Board, availableSpaces: PointState[],
/**
* Finds all moves that increases the liberties of the player's pieces, making them harder to capture and occupy more space on the board.
*/
async function getLibertyGrowthMoves(board: Board, player: GoColor, availableSpaces: PointState[]) {
function getLibertyGrowthMoves(board: Board, player: GoColor, availableSpaces: PointState[]) {
const friendlyChains = getAllChains(board).filter((chain) => chain[0].color === player);

if (!friendlyChains.length) {
Expand Down Expand Up @@ -551,8 +549,8 @@ async function getLibertyGrowthMoves(board: Board, player: GoColor, availableSpa
/**
* Find a move that increases the player's liberties by the maximum amount
*/
async function getGrowthMove(board: Board, player: GoColor, availableSpaces: PointState[], rng: number) {
const growthMoves = await getLibertyGrowthMoves(board, player, availableSpaces);
function getGrowthMove(board: Board, player: GoColor, availableSpaces: PointState[], rng: number) {
const growthMoves = getLibertyGrowthMoves(board, player, availableSpaces);

const maxLibertyCount = Math.max(...growthMoves.map((l) => l.newLibertyCount - l.oldLibertyCount));

Expand All @@ -563,8 +561,8 @@ async function getGrowthMove(board: Board, player: GoColor, availableSpaces: Poi
/**
* Find a move that specifically increases a chain's liberties from 1 to more than 1, preventing capture
*/
async function getDefendMove(board: Board, player: GoColor, availableSpaces: PointState[]) {
const growthMoves = await getLibertyGrowthMoves(board, player, availableSpaces);
function getDefendMove(board: Board, player: GoColor, availableSpaces: PointState[]) {
const growthMoves = getLibertyGrowthMoves(board, player, availableSpaces);
const libertyIncreases =
growthMoves?.filter((move) => move.oldLibertyCount <= 1 && move.newLibertyCount > move.oldLibertyCount) ?? [];

Expand All @@ -582,7 +580,7 @@ async function getDefendMove(board: Board, player: GoColor, availableSpaces: Poi
* Find a move that reduces the opponent's liberties as much as possible,
* capturing (or making it easier to capture) their pieces
*/
async function getSurroundMove(board: Board, player: GoColor, availableSpaces: PointState[], smart = true) {
function getSurroundMove(board: Board, player: GoColor, availableSpaces: PointState[], smart = true) {
const opposingPlayer = player === GoColor.black ? GoColor.white : GoColor.black;
const enemyChains = getAllChains(board).filter((chain) => chain[0].color === opposingPlayer);

Expand Down Expand Up @@ -741,12 +739,7 @@ function getEyeBlockingMove(board: Board, player: GoColor, availablePoints: Poin
/**
* Gets a group of reasonable moves based on the current board state, to be passed to the factions' AI to decide on
*/
function getMoveOptions(
boardState: BoardState,
player: GoColor,
rng: number,
smart = true,
): { [s in keyof MoveOptions]: () => Promise<Move | null> } {
function getMoveOptions(boardState: BoardState, player: GoColor, rng: number, smart = true) {
const board = boardState.board;
const availableSpaces = findDisputedTerritory(boardState, player, smart);
const contestedPoints = getDisputedTerritoryMoves(board, availableSpaces);
Expand All @@ -756,7 +749,7 @@ function getMoveOptions(
// needlessly extend the game, unless they actually can change the score
const endGameAvailable = !contestedPoints.length && boardState.passCount;

const moveOptions: { [s in keyof MoveOptions]: Move | null | undefined } = {
const moveOptions: { [s in MoveType]: Move | null | undefined } = {
capture: undefined,
defendCapture: undefined,
eyeMove: undefined,
Expand All @@ -771,7 +764,7 @@ function getMoveOptions(
random: undefined,
};

const moveOptionGetters: { [s in keyof MoveOptions]: () => Promise<Move | null> } = {
const moveOptionGetters: MoveOptions = {
capture: async () => {
const surroundMove = await retrieveMoveOption("surround");
return surroundMove && surroundMove?.newLibertyCount === 0 ? surroundMove : null;
Expand All @@ -785,30 +778,30 @@ function getMoveOptions(
? defendMove
: null;
},
eyeMove: async () => (endGameAvailable ? null : getEyeCreationMove(board, player, availableSpaces) ?? null),
eyeBlock: async () => (endGameAvailable ? null : getEyeBlockingMove(board, player, availableSpaces) ?? null),
eyeMove: () => (endGameAvailable ? null : getEyeCreationMove(board, player, availableSpaces) ?? null),
eyeBlock: () => (endGameAvailable ? null : getEyeBlockingMove(board, player, availableSpaces) ?? null),
pattern: async () => {
const point = endGameAvailable ? null : await findAnyMatchedPatterns(board, player, availableSpaces, smart, rng);
return point ? { point } : null;
},
growth: async () => (endGameAvailable ? null : (await getGrowthMove(board, player, availableSpaces, rng)) ?? null),
expansion: async () => (await getExpansionMove(board, availableSpaces, rng, expansionMoves)) ?? null,
jump: async () => (await getJumpMove(board, player, availableSpaces, rng, expansionMoves)) ?? null,
defend: async () => (await getDefendMove(board, player, availableSpaces)) ?? null,
surround: async () => (await getSurroundMove(board, player, availableSpaces, smart)) ?? null,
corner: async () => {
growth: () => (endGameAvailable ? null : getGrowthMove(board, player, availableSpaces, rng) ?? null),
expansion: () => getExpansionMove(board, availableSpaces, rng, expansionMoves) ?? null,
jump: () => getJumpMove(board, player, availableSpaces, rng, expansionMoves) ?? null,
defend: () => getDefendMove(board, player, availableSpaces) ?? null,
surround: () => getSurroundMove(board, player, availableSpaces, smart) ?? null,
corner: () => {
const point = getCornerMove(board);
return point ? { point } : null;
},
random: async () => {
random: () => {
// Only offer a random move if there are some contested spaces on the board.
// (Random move should not be picked if the AI would otherwise pass turn.)
const point = contestedPoints.length ? availableSpaces[Math.floor(rng * availableSpaces.length)] : null;
return point ? { point } : null;
},
};
} as const;

async function retrieveMoveOption(id: keyof typeof moveOptions): Promise<Move | null> {
async function retrieveMoveOption(id: MoveType): Promise<Move | null> {
await waitCycle();
if (moveOptions[id] !== undefined) {
return moveOptions[id] ?? null;
Expand Down
2 changes: 1 addition & 1 deletion src/Go/boardAnalysis/patternMatching.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
import type { Board, PointState } from "../Types";

import { GoColor } from "@enums";
import { sleep } from "./goAI";
import { findEffectiveLibertiesOfNewMove } from "./boardAnalysis";
import { sleep } from "./goAI";

export const threeByThreePatterns = [
// 3x3 piece patterns; X,O are color pieces; x,o are any state except the opposite color piece;
Expand Down
4 changes: 2 additions & 2 deletions src/Go/boardState/goStyles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const fadeLoop = keyframes`
}
`;

export const pointStyle = makeStyles<void, Size | Point | Structure | Highlight>({ uniqId: "pointStyle" })(
export const pointStyle = makeStyles<unknown, Size | Point | Structure | Highlight>({ uniqId: "pointStyle" })(
(theme: Theme, _, classes) => ({
hover: {},
valid: {},
Expand Down Expand Up @@ -396,7 +396,7 @@ export const pointStyle = makeStyles<void, Size | Point | Structure | Highlight>
}),
);

export const boardStyles = makeStyles<void, Size | "background">({ uniqId: "boardStyles" })(
export const boardStyles = makeStyles<unknown, Size | "background">({ uniqId: "boardStyles" })(
(theme: Theme, _, classes) => ({
tab: {
paddingTop: 0,
Expand Down
15 changes: 12 additions & 3 deletions src/Go/effects/netscriptGoImplementation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,11 @@ export function cheatRemoveRouter(
successRngOverride?: number,
ejectRngOverride?: number,
): Promise<Play> {
const point = Go.currentGame.board[x][y]!;
const point = Go.currentGame.board[x][y];
if (!point) {
logger(`Cheat failed. The point ${x},${y} is already offline.`);
return Go.nextTurn;
}
return determineCheatSuccess(
logger,
() => {
Expand All @@ -498,8 +502,13 @@ export function cheatPlayTwoMoves(
successRngOverride?: number,
ejectRngOverride?: number,
): Promise<Play> {
const point1 = Go.currentGame.board[x1][y1]!;
const point2 = Go.currentGame.board[x2][y2]!;
const point1 = Go.currentGame.board[x1][y1];
const point2 = Go.currentGame.board[x2][y2];

if (!point1 || !point2) {
logger(`Cheat failed. One of the points ${x1},${y1} or ${x2},${y2} is already offline.`);
return Go.nextTurn;
}

return determineCheatSuccess(
logger,
Expand Down
Loading

0 comments on commit 97ca8c5

Please sign in to comment.