IPVGO: Support playing manually as white against your scripts using the No AI type board (#1296)

This commit is contained in:
Michael Ficocelli
2024-06-02 20:41:31 -04:00
committed by GitHub
parent f40d4f8e92
commit a28bb4bd99
7 changed files with 80 additions and 24 deletions
+36 -9
View File
@@ -1,7 +1,7 @@
import type { Board, BoardState, EyeMove, Move, MoveOptions, Play, PointState } from "../Types";
import { Player } from "@player";
import { AugmentationName, GoOpponent, GoColor, GoPlayType } from "@enums";
import { AugmentationName, GoColor, GoOpponent, GoPlayType } from "@enums";
import { opponentDetails } from "../Constants";
import { findNeighbors, isNotNullish, makeMove, passTurn } from "../boardState/boardState";
import {
@@ -15,22 +15,35 @@ import {
getAllEyesByChainId,
getAllNeighboringChains,
getAllValidMoves,
getPreviousMoveDetails,
} from "./boardAnalysis";
import { findDisputedTerritory } from "./controlledTerritory";
import { findAnyMatchedPatterns } from "./patternMatching";
import { WHRNG } from "../../Casino/RNG";
import { Go, GoEvents } from "../Go";
let currentAITurn: Promise<Play> | null = null;
let isAiThinking: boolean = false;
let currentTurnResolver: (() => void) | null = null;
/**
* Retrieves a move from the current faction in response to the player's move
*/
export function makeAIMove(boardState: BoardState): Promise<Play> {
// If AI is already taking their turn, return the existing turn.
if (currentAITurn) return currentAITurn;
currentAITurn = Go.nextTurn = getMove(boardState, GoColor.white, Go.currentGame.ai)
.then(async (play): Promise<Play> => {
if (isAiThinking) {
return Go.nextTurn;
}
isAiThinking = true;
// 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())));
}
// 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 {
Go.nextTurn = getMove(boardState, GoColor.white, Go.currentGame.ai).then(async (play): Promise<Play> => {
if (boardState !== Go.currentGame) return play; //Stale game
// Handle AI passing
@@ -54,15 +67,29 @@ export function makeAIMove(boardState: BoardState): Promise<Play> {
}
return play;
})
.finally(() => {
currentAITurn = null;
GoEvents.emit();
});
}
// 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;
GoEvents.emit();
});
return Go.nextTurn;
}
/**
* Resolves the current turn.
* This is used for players manually playing against their script on the no-ai board.
*/
export function resolveCurrentTurn() {
// Call the resolve function on Go.nextTurn, if it exists
currentTurnResolver?.();
currentTurnResolver = null;
}
/*
Basic GO AIs, each with some personality and weaknesses