import { SearchTree } from "../tree/searchtree.js"; import { MinimaxOpts, MinimaxResult } from "./index.js"; import { Node, SearchExit } from "../index.js"; /** * Class for performing a minimax search. * * **Probability based searches coming soon** * * ## Usage * See the {@link Negamax} documentation for general usage, its is very similar. * * The differences are as follows: * - The {@link NegamaxOpts.optimal} flag is not supported (and won't be) * - The {@link MinimaxOpts.pruneByPathLength}, {@link MinimaxOpts.randomBest} and * {@link MinimaxOpts.randomWeight} options are not yet available. * - In the {@link Minimax.CreateChildNode} callback, the {@link NodeAim} must be * explicitly set according to the players turn. This allows repeated turns, i.e setting it as {@link NodeAim.MAX} * two turns in a row. * * * @typeParam GS - The object representing the state of the game * @typeParam M - The object representing a move in the game * @typeParam D - Extra data used in evaluation not suitable for storing in the gamestate * * @category Minimax */ export declare class Minimax extends SearchTree { /** * * @param root Root node to start the tree from * @param opts Optional options to configure the minimax algorithm */ constructor(root: Node, opts?: MinimaxOpts); /** * * @param depth Overide the depth property in {@link MinimaxOpts.depth} * @returns The result of the search */ protected evalDepth(depth?: number): MinimaxResult; /** * Implements the minimax algorithm up to a given depth of search. * Recursively calls itself until `depth` is `0` or {@link NodeType.LEAF} * node is reached and evaluated. * * Node values and best child are chosen according to the * {@link NodeAim} of the parent nodes. * * Returns early if timeout occurs * * @param node Node to evaluate or search children * @param depth Depth to search from this node * @param alpha minimum guaranteed score * @param beta maximum guaranteed score from minimising player * @returns Reason for returning. */ protected minimax(node: Node, depth: number, alpha: number, beta: number): SearchExit; /** * Goes through all of nodes children to find child with * minimum inherited value */ protected minimumBestChild(node: Node, depth: number): { exit: SearchExit; best: Node | undefined; }; /** * Goes through all of nodes children to find child with * minimum inherited value */ protected maximumBestChild(node: Node, depth: number): { exit: SearchExit; best: Node | undefined; }; /** * Find the best child of a node using alpha beta pruning * @param node Node to find best child of * @param depth Depth to limit search to * @param alpha Current alpha value * @param beta current beta value * @returns Reason for exit and opional best child */ protected alphaBetaBestChild(node: Node, depth: number, alpha: number, beta: number): { exit: SearchExit; best: Node | undefined; }; /** * * @param node Node to assign value to * @param leaf `true` if node is a leaf * @returns reason for exit. Either {@link SearchExit.FULL_DEPTH} or {@link SearchExit.DEPTH}. */ protected assignNodeValue(node: Node, leaf: boolean): SearchExit; }