mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2026-05-02 05:47:14 +02:00
IPVGO: Prevent issues caused by resetting the board while the go AI is in flight (#1608)
This commit is contained in:
committed by
GitHub
parent
4f426e1b20
commit
2a5b0ca4e9
@@ -34,18 +34,22 @@ export function makeAIMove(boardState: BoardState, useOfflineCycles = true): Pro
|
||||
return Go.nextTurn;
|
||||
}
|
||||
isAiThinking = true;
|
||||
let encounteredError = false;
|
||||
|
||||
// If the AI is disabled, simply make a promise to be resolved once the player makes a move as white
|
||||
if (boardState.ai === GoOpponent.none) {
|
||||
GoEvents.emit();
|
||||
// Update currentTurnResolver to call Go.nextTurn's resolve function with the last played move's details
|
||||
Go.nextTurn = new Promise((resolve) => (currentTurnResolver = () => resolve(getPreviousMoveDetails())));
|
||||
resetAI();
|
||||
}
|
||||
// If an AI is in use, find the faction's move in response, and resolve the Go.nextTurn promise once it is found and played.
|
||||
else {
|
||||
const currentMoveCount = Go.currentGame.previousBoards.length;
|
||||
Go.nextTurn = getMove(boardState, GoColor.white, Go.currentGame.ai, useOfflineCycles).then(
|
||||
async (play): Promise<Play> => {
|
||||
if (boardState !== Go.currentGame) return play; //Stale game
|
||||
if (boardState !== Go.currentGame) {
|
||||
//Stale game
|
||||
encounteredError = true;
|
||||
return play;
|
||||
}
|
||||
|
||||
// Handle AI passing
|
||||
if (play.type === GoPlayType.pass) {
|
||||
@@ -59,6 +63,13 @@ export function makeAIMove(boardState: BoardState, useOfflineCycles = true): Pro
|
||||
|
||||
// Handle AI making a move
|
||||
await waitCycle(useOfflineCycles);
|
||||
|
||||
if (currentMoveCount !== Go.currentGame.previousBoards.length || boardState !== Go.currentGame) {
|
||||
console.warn("AI move attempted, but the board state has changed.");
|
||||
encounteredError = true;
|
||||
return play;
|
||||
}
|
||||
|
||||
const aiUpdatedBoard = makeMove(boardState, play.x, play.y, GoColor.white);
|
||||
|
||||
// Handle the AI breaking. This shouldn't ever happen.
|
||||
@@ -75,13 +86,22 @@ export function makeAIMove(boardState: BoardState, useOfflineCycles = true): Pro
|
||||
// Once the AI moves (or the player playing as white with No AI moves),
|
||||
// clear the isAiThinking semaphore and update the board UI.
|
||||
Go.nextTurn = Go.nextTurn.finally(() => {
|
||||
isAiThinking = false;
|
||||
if (!encounteredError) {
|
||||
isAiThinking = false;
|
||||
}
|
||||
GoEvents.emit();
|
||||
});
|
||||
|
||||
return Go.nextTurn;
|
||||
}
|
||||
|
||||
export function resetAI(thinking = true) {
|
||||
isAiThinking = thinking;
|
||||
GoEvents.emit();
|
||||
// Update currentTurnResolver to call Go.nextTurn's resolve function with the last played move's details
|
||||
Go.nextTurn = new Promise((resolve) => (currentTurnResolver = () => resolve(getPreviousMoveDetails())));
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the current turn.
|
||||
* This is used for players manually playing against their script on the no-ai board.
|
||||
|
||||
@@ -4,7 +4,7 @@ import { Player } from "@player";
|
||||
import { AugmentationName, GoColor, GoOpponent, GoPlayType, GoValidity } from "@enums";
|
||||
import { Go, GoEvents } from "../Go";
|
||||
import { getNewBoardState, makeMove, passTurn, updateCaptures, updateChains } from "../boardState/boardState";
|
||||
import { makeAIMove } from "../boardAnalysis/goAI";
|
||||
import { makeAIMove, resetAI } from "../boardAnalysis/goAI";
|
||||
import {
|
||||
evaluateIfMoveIsValid,
|
||||
getControlledSpace,
|
||||
@@ -292,6 +292,7 @@ export function resetBoardState(
|
||||
}
|
||||
|
||||
Go.currentGame = getNewBoardState(boardSize, opponent, true);
|
||||
resetAI(false);
|
||||
GoEvents.emit(); // Trigger a Go UI rerender
|
||||
logger(`New game started: ${opponent}, ${boardSize}x${boardSize}`);
|
||||
return simpleBoardFromBoard(Go.currentGame.board);
|
||||
|
||||
@@ -18,7 +18,7 @@ import { GoScoreModal } from "./GoScoreModal";
|
||||
import { GoGameboard } from "./GoGameboard";
|
||||
import { GoSubnetSearch } from "./GoSubnetSearch";
|
||||
import { CorruptableText } from "../../ui/React/CorruptableText";
|
||||
import { makeAIMove, resolveCurrentTurn } from "../boardAnalysis/goAI";
|
||||
import { makeAIMove, resetAI, resolveCurrentTurn } from "../boardAnalysis/goAI";
|
||||
import { GoScoreExplanation } from "./GoScoreExplanation";
|
||||
|
||||
interface GoGameboardWrapperProps {
|
||||
@@ -144,6 +144,7 @@ export function GoGameboardWrapper({ showInstructions }: GoGameboardWrapperProps
|
||||
}
|
||||
|
||||
Go.currentGame = getNewBoardState(newBoardSize, newOpponent, true);
|
||||
resetAI(false);
|
||||
rerender();
|
||||
resolveCurrentTurn();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user