mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-18 05:33:54 +01:00
IPVGO: Remove unneeded functions from boardState.ts (#1270)
This commit is contained in:
parent
b7962ad8ab
commit
38d99ff15e
@ -9,8 +9,7 @@ import {
|
||||
getBoardCopy,
|
||||
getEmptySpaces,
|
||||
getNewBoardState,
|
||||
isDefined,
|
||||
isNotNull,
|
||||
isNotNullish,
|
||||
updateCaptures,
|
||||
updateChains,
|
||||
} from "../boardState/boardState";
|
||||
@ -155,9 +154,7 @@ const resetChainsById = (board: Board, chainIds: string[]) => {
|
||||
export function findEffectiveLibertiesOfNewMove(board: Board, x: number, y: number, player: GoColor) {
|
||||
const friendlyChains = getAllChains(board).filter((chain) => chain[0].color === player);
|
||||
const neighbors = findAdjacentLibertiesAndAlliesForPoint(board, x, y, player);
|
||||
const neighborPoints = [neighbors.north, neighbors.east, neighbors.south, neighbors.west]
|
||||
.filter(isNotNull)
|
||||
.filter(isDefined);
|
||||
const neighborPoints = [neighbors.north, neighbors.east, neighbors.south, neighbors.west].filter(isNotNullish);
|
||||
// Get all chains that the new move will connect to
|
||||
const allyNeighbors = neighborPoints.filter((neighbor) => neighbor.color === player);
|
||||
const allyNeighborChainLiberties = allyNeighbors
|
||||
@ -166,7 +163,7 @@ export function findEffectiveLibertiesOfNewMove(board: Board, x: number, y: numb
|
||||
return chain?.[0]?.liberties ?? null;
|
||||
})
|
||||
.flat()
|
||||
.filter(isNotNull);
|
||||
.filter(isNotNullish);
|
||||
|
||||
// Get all empty spaces that the new move connects to that aren't already part of friendly liberties
|
||||
const directLiberties = neighborPoints.filter((neighbor) => neighbor.color === GoColor.empty);
|
||||
@ -188,8 +185,7 @@ export function findEffectiveLibertiesOfNewMove(board: Board, x: number, y: numb
|
||||
export function findMaxLibertyCountOfAdjacentChains(boardState: BoardState, x: number, y: number, player: GoColor) {
|
||||
const neighbors = findAdjacentLibertiesAndAlliesForPoint(boardState.board, x, y, player);
|
||||
const friendlyNeighbors = [neighbors.north, neighbors.east, neighbors.south, neighbors.west]
|
||||
.filter(isNotNull)
|
||||
.filter(isDefined)
|
||||
.filter(isNotNullish)
|
||||
.filter((neighbor) => neighbor.color === player);
|
||||
|
||||
return friendlyNeighbors.reduce((max, neighbor) => Math.max(max, neighbor?.liberties?.length ?? 0), 0);
|
||||
@ -207,8 +203,7 @@ export function findEnemyNeighborChainWithFewestLiberties(board: Board, x: numbe
|
||||
const chains = getAllChains(board);
|
||||
const neighbors = findAdjacentLibertiesAndAlliesForPoint(board, x, y, player);
|
||||
const friendlyNeighbors = [neighbors.north, neighbors.east, neighbors.south, neighbors.west]
|
||||
.filter(isNotNull)
|
||||
.filter(isDefined)
|
||||
.filter(isNotNullish)
|
||||
.filter((neighbor) => neighbor.color === player);
|
||||
|
||||
const minimumLiberties = friendlyNeighbors.reduce(
|
||||
@ -353,10 +348,7 @@ function findNeighboringChainsThatFullyEncircleEmptySpace(
|
||||
|
||||
const evaluationBoard = getBoardCopy(board);
|
||||
const examplePoint = candidateChain[0];
|
||||
const otherChainNeighborPoints = removePointAtIndex(neighborChainList, index)
|
||||
.flat()
|
||||
.filter(isNotNull)
|
||||
.filter(isDefined);
|
||||
const otherChainNeighborPoints = removePointAtIndex(neighborChainList, index).flat().filter(isNotNullish);
|
||||
otherChainNeighborPoints.forEach((point) => {
|
||||
const pointToEdit = evaluationBoard[point.x]?.[point.y];
|
||||
if (pointToEdit) {
|
||||
|
@ -8,7 +8,7 @@ import {
|
||||
getAllPotentialEyes,
|
||||
getAllValidMoves,
|
||||
} from "./boardAnalysis";
|
||||
import { contains, isNotNull } from "../boardState/boardState";
|
||||
import { contains, isNotNullish } from "../boardState/boardState";
|
||||
|
||||
/**
|
||||
* Any empty space fully encircled by the opponent is not worth playing in, unless one of its borders explicitly has a weakness
|
||||
@ -57,7 +57,7 @@ export function findDisputedTerritory(boardState: BoardState, player: GoColor, e
|
||||
}
|
||||
|
||||
const libertiesInsideOfSpaceToAnalyze = liberties
|
||||
.filter(isNotNull)
|
||||
.filter(isNotNullish)
|
||||
.filter((point) => contains(space.chain, point));
|
||||
|
||||
// If the chain has any liberties outside the empty space being analyzed, it is not yet fully surrounded,
|
||||
|
@ -3,7 +3,7 @@ import type { Board, BoardState, EyeMove, Move, MoveOptions, Play, PointState }
|
||||
import { Player } from "@player";
|
||||
import { AugmentationName, GoOpponent, GoColor, GoPlayType } from "@enums";
|
||||
import { opponentDetails } from "../Constants";
|
||||
import { findNeighbors, floor, isDefined, isNotNull, makeMove, passTurn } from "../boardState/boardState";
|
||||
import { findNeighbors, isNotNullish, makeMove, passTurn } from "../boardState/boardState";
|
||||
import {
|
||||
evaluateIfMoveIsValid,
|
||||
evaluateMoveResult,
|
||||
@ -111,11 +111,10 @@ export async function getMove(
|
||||
(await moves.eyeMove())?.point,
|
||||
(await moves.eyeBlock())?.point,
|
||||
]
|
||||
.filter(isNotNull)
|
||||
.filter(isDefined)
|
||||
.filter(isNotNullish)
|
||||
.filter((point) => evaluateIfMoveIsValid(boardState, point.x, point.y, player, false));
|
||||
|
||||
const chosenMove = moveOptions[floor(rng.random() * moveOptions.length)];
|
||||
const chosenMove = moveOptions[Math.floor(rng.random() * moveOptions.length)];
|
||||
|
||||
if (chosenMove) {
|
||||
await sleep(200);
|
||||
@ -393,7 +392,7 @@ function isCornerAvailableForMove(board: Board, x1: number, y1: number, x2: numb
|
||||
*/
|
||||
function getExpansionMove(board: Board, availableSpaces: PointState[], rng: number, moveArray?: Move[]) {
|
||||
const moveOptions = moveArray ?? getExpansionMoveArray(board, availableSpaces);
|
||||
const randomIndex = floor(rng * moveOptions.length);
|
||||
const randomIndex = Math.floor(rng * moveOptions.length);
|
||||
return moveOptions[randomIndex];
|
||||
}
|
||||
|
||||
@ -410,7 +409,7 @@ function getJumpMove(board: Board, player: GoColor, availableSpaces: PointState[
|
||||
].some((point) => point?.color === player),
|
||||
);
|
||||
|
||||
const randomIndex = floor(rng * moveOptions.length);
|
||||
const randomIndex = Math.floor(rng * moveOptions.length);
|
||||
return moveOptions[randomIndex];
|
||||
}
|
||||
|
||||
@ -469,14 +468,13 @@ async function getLibertyGrowthMoves(board: Board, player: GoColor, availableSpa
|
||||
// Get all liberties of friendly chains as potential growth move options
|
||||
const liberties = friendlyChains
|
||||
.map((chain) =>
|
||||
chain[0].liberties?.filter(isNotNull).map((liberty) => ({
|
||||
chain[0].liberties?.filter(isNotNullish).map((liberty) => ({
|
||||
libertyPoint: liberty,
|
||||
oldLibertyCount: chain[0].liberties?.length,
|
||||
})),
|
||||
)
|
||||
.flat()
|
||||
.filter(isNotNull)
|
||||
.filter(isDefined)
|
||||
.filter(isNotNullish)
|
||||
.filter((liberty) =>
|
||||
availableSpaces.find((point) => liberty.libertyPoint.x === point.x && liberty.libertyPoint.y === point.y),
|
||||
);
|
||||
@ -509,7 +507,7 @@ async function getGrowthMove(board: Board, player: GoColor, availableSpaces: Poi
|
||||
const maxLibertyCount = Math.max(...growthMoves.map((l) => l.newLibertyCount - l.oldLibertyCount));
|
||||
|
||||
const moveCandidates = growthMoves.filter((l) => l.newLibertyCount - l.oldLibertyCount === maxLibertyCount);
|
||||
return moveCandidates[floor(rng * moveCandidates.length)];
|
||||
return moveCandidates[Math.floor(rng * moveCandidates.length)];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -527,7 +525,7 @@ async function getDefendMove(board: Board, player: GoColor, availableSpaces: Poi
|
||||
}
|
||||
|
||||
const moveCandidates = libertyIncreases.filter((l) => l.newLibertyCount - l.oldLibertyCount === maxLibertyCount);
|
||||
return moveCandidates[floor(Math.random() * moveCandidates.length)];
|
||||
return moveCandidates[Math.floor(Math.random() * moveCandidates.length)];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -546,7 +544,7 @@ async function getSurroundMove(board: Board, player: GoColor, availableSpaces: P
|
||||
.map((chain) => chain[0].liberties)
|
||||
.flat()
|
||||
.filter((liberty) => availableSpaces.find((point) => liberty?.x === point.x && liberty?.y === point.y))
|
||||
.filter(isNotNull);
|
||||
.filter(isNotNullish);
|
||||
|
||||
const captureMoves: Move[] = [];
|
||||
const atariMoves: Move[] = [];
|
||||
@ -635,7 +633,7 @@ function getEyeCreationMoves(board: Board, player: GoColor, availableSpaces: Poi
|
||||
.filter((chain) => !currentLivingGroupIDs.includes(chain[0].chain))
|
||||
.map((chain) => chain[0].liberties)
|
||||
.flat()
|
||||
.filter(isNotNull)
|
||||
.filter(isNotNullish)
|
||||
.filter((point) =>
|
||||
availableSpaces.find((availablePoint) => availablePoint.x === point.x && availablePoint.y === point.y),
|
||||
)
|
||||
@ -755,7 +753,7 @@ function getMoveOptions(
|
||||
random: async () => {
|
||||
// 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[floor(rng * availableSpaces.length)] : null;
|
||||
const point = contestedPoints.length ? availableSpaces[Math.floor(rng * availableSpaces.length)] : null;
|
||||
return point ? { point } : null;
|
||||
},
|
||||
};
|
||||
|
@ -4,7 +4,6 @@ import type { Board, PointState } from "../Types";
|
||||
import { GoColor } from "@enums";
|
||||
import { sleep } from "./goAI";
|
||||
import { findEffectiveLibertiesOfNewMove } from "./boardAnalysis";
|
||||
import { floor } from "../boardState/boardState";
|
||||
|
||||
export const threeByThreePatterns = [
|
||||
// 3x3 piece patterns; X,O are color pieces; x,o are any state except the opposite color piece;
|
||||
@ -104,7 +103,7 @@ export async function findAnyMatchedPatterns(
|
||||
}
|
||||
await sleep(10);
|
||||
}
|
||||
return moves[floor(rng * moves.length)] || null;
|
||||
return moves[Math.floor(rng * moves.length)] || null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -6,7 +6,7 @@ import { newOpponentStats } from "../Constants";
|
||||
import { getAllChains, getPlayerNeighbors } from "./boardAnalysis";
|
||||
import { getKomi } from "./goAI";
|
||||
import { getDifficultyMultiplier, getMaxFavor, getWinstreakMultiplier } from "../effects/effect";
|
||||
import { floor, isNotNull } from "../boardState/boardState";
|
||||
import { isNotNullish } from "../boardState/boardState";
|
||||
import { Factions } from "../../Faction/Factions";
|
||||
import { getEnumHelper } from "../../utils/EnumHelper";
|
||||
import { Go } from "../Go";
|
||||
@ -59,7 +59,7 @@ export function endGoGame(boardState: BoardState) {
|
||||
|
||||
if (score[GoColor.black].sum < score[GoColor.white].sum) {
|
||||
resetWinstreak(boardState.ai, true);
|
||||
statusToUpdate.nodePower += floor(score[GoColor.black].sum * 0.25);
|
||||
statusToUpdate.nodePower += Math.floor(score[GoColor.black].sum * 0.25);
|
||||
} else {
|
||||
statusToUpdate.wins++;
|
||||
statusToUpdate.oldWinStreak = statusToUpdate.winStreak;
|
||||
@ -114,7 +114,7 @@ export function resetWinstreak(opponent: GoOpponent, gameComplete: boolean) {
|
||||
*/
|
||||
function getColoredPieceCount(boardState: BoardState, color: GoColor) {
|
||||
return boardState.board.reduce(
|
||||
(sum, row) => sum + row.filter(isNotNull).filter((point) => point.color === color).length,
|
||||
(sum, row) => sum + row.filter(isNotNullish).filter((point) => point.color === color).length,
|
||||
0,
|
||||
);
|
||||
}
|
||||
|
@ -140,7 +140,7 @@ export function applyHandicap(board: Board, handicap: number): void {
|
||||
|
||||
// select random distinct moves from the move options list up to the specified handicap amount
|
||||
for (let i = 0; i < handicap && i < handicapMoveOptions.length; i++) {
|
||||
const index = floor(Math.random() * handicapMoveOptions.length);
|
||||
const index = Math.floor(Math.random() * handicapMoveOptions.length);
|
||||
handicapMoves.push(handicapMoveOptions[index]);
|
||||
handicapMoveOptions.splice(index, 1);
|
||||
}
|
||||
@ -247,16 +247,13 @@ export function findAdjacentPointsInChain(board: Board, x: number, y: number) {
|
||||
checkedPoints.push(currentPoint);
|
||||
const neighbors = findNeighbors(board, currentPoint.x, currentPoint.y);
|
||||
|
||||
[neighbors.north, neighbors.east, neighbors.south, neighbors.west]
|
||||
.filter(isNotNull)
|
||||
.filter(isDefined)
|
||||
.forEach((neighbor) => {
|
||||
if (neighbor && neighbor.color === currentPoint.color && !contains(checkedPoints, neighbor)) {
|
||||
adjacentPoints.push(neighbor);
|
||||
pointsToCheckNeighbors.push(neighbor);
|
||||
}
|
||||
checkedPoints.push(neighbor);
|
||||
});
|
||||
[neighbors.north, neighbors.east, neighbors.south, neighbors.west].filter(isNotNullish).forEach((neighbor) => {
|
||||
if (neighbor && neighbor.color === currentPoint.color && !contains(checkedPoints, neighbor)) {
|
||||
adjacentPoints.push(neighbor);
|
||||
pointsToCheckNeighbors.push(neighbor);
|
||||
}
|
||||
checkedPoints.push(neighbor);
|
||||
});
|
||||
}
|
||||
|
||||
return adjacentPoints;
|
||||
@ -312,22 +309,9 @@ export function findNeighbors(board: Board, x: number, y: number): Neighbor {
|
||||
}
|
||||
|
||||
export function getArrayFromNeighbor(neighborObject: Neighbor): PointState[] {
|
||||
return [neighborObject.north, neighborObject.east, neighborObject.south, neighborObject.west]
|
||||
.filter(isNotNull)
|
||||
.filter(isDefined);
|
||||
return [neighborObject.north, neighborObject.east, neighborObject.south, neighborObject.west].filter(isNotNullish);
|
||||
}
|
||||
|
||||
export function isNotNull<T>(argument: T | null): argument is T {
|
||||
return argument !== null;
|
||||
}
|
||||
export function isDefined<T>(argument: T | undefined): argument is T {
|
||||
return argument !== undefined;
|
||||
}
|
||||
|
||||
export function floor(n: number) {
|
||||
return ~~n;
|
||||
}
|
||||
export function ceil(n: number) {
|
||||
const floored = floor(n);
|
||||
return floored === n ? n : floored + 1;
|
||||
export function isNotNullish<T>(argument: T | undefined | null): argument is T {
|
||||
return argument != null;
|
||||
}
|
||||
|
@ -3,13 +3,12 @@ import type { Board, BoardState, PointState } from "../Types";
|
||||
import { Player } from "@player";
|
||||
import { boardSizes } from "../Constants";
|
||||
import { WHRNG } from "../../Casino/RNG";
|
||||
import { floor } from "./boardState";
|
||||
|
||||
type rand = (n1: number, n2: number) => number;
|
||||
|
||||
export function addObstacles(boardState: BoardState) {
|
||||
const rng = new WHRNG(Player.totalPlaytime ?? new Date().getTime());
|
||||
const random = (n1: number, n2: number) => n1 + floor((n2 - n1 + 1) * rng.random());
|
||||
const random = (n1: number, n2: number) => n1 + Math.floor((n2 - n1 + 1) * rng.random());
|
||||
|
||||
const shouldRemoveCorner = !random(0, 4);
|
||||
const shouldRemoveRows = !shouldRemoveCorner && !random(0, 4);
|
||||
@ -105,8 +104,8 @@ function addDeadCorner(board: Board, random: rand, size: number) {
|
||||
function addCenterBreak(board: Board, random: rand) {
|
||||
const size = board[0].length;
|
||||
const maxOffset = getScale(board);
|
||||
const xIndex = random(0, maxOffset * 2) - maxOffset + floor(size / 2);
|
||||
const length = random(1, floor(size / 2 - 1));
|
||||
const xIndex = random(0, maxOffset * 2) - maxOffset + Math.floor(size / 2);
|
||||
const length = random(1, Math.floor(size / 2 - 1));
|
||||
|
||||
board[xIndex] = board[xIndex].map((point, index) => (index < length ? null : point));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user