UNPKG

goban

Version:

[![License: Apache-2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/online-go/goban)

428 lines (427 loc) 15.7 kB
import { BoardState, BoardConfig } from "./BoardState"; import { MoveTree, MoveTreeJson } from "./MoveTree"; import { ScoreEstimator } from "./ScoreEstimator"; import { GobanBase, GobanEvents } from "../GobanBase"; import { JGOFTimeControl, JGOFNumericPlayerColor, JGOFMove, JGOFPlayerSummary, JGOFIntersection, JGOFSealingIntersection } from "./formats/JGOF"; import { AdHocPackedMove } from "./formats/AdHocFormat"; import { EventEmitter } from "eventemitter3"; import { GameClock, StallingScoreEstimate } from "./protocol"; export declare const AUTOSCORE_TRIALS = 1000; export declare const AUTOSCORE_TOLERANCE = 0.1; export type GobanEnginePhase = "play" | "stone removal" | "finished"; export type GobanEngineRules = "chinese" | "aga" | "japanese" | "korean" | "ing" | "nz"; export type GobanEngineSuperKoAlgorithm = "psk" | "csk" | "ssk" | "noresult" | "ing"; export interface PlayerScore { total: number; stones: number; territory: number; prisoners: number; scoring_positions: string; handicap: number; komi: number; } export interface Score { white: PlayerScore; black: PlayerScore; } export interface GobanEnginePlayerEntry { id: number; username: string; country?: string; rank?: number; /** The accepted stones for the stone removal phase that the player has accepted */ accepted_stones?: string; /** Whether or not the player has accepted scoring with strict seki mode on or not */ accepted_strict_seki_mode?: boolean; /** XXX: The server is using these, the client may or may not be, we need to normalize this */ name?: string; pro?: boolean; } export type GobanMovesArray = Array<AdHocPackedMove> | Array<JGOFMove>; export interface GobanEngineConfig extends BoardConfig { game_id?: number | string; review_id?: number; game_name?: string; player_id?: number; tournament_id?: number; ladder_id?: number; group_ids?: Array<number>; initial_player?: PlayerColor; width?: number; height?: number; disable_analysis?: boolean; handicap_rank_difference?: number; handicap?: number; komi?: number; rules?: GobanEngineRules; phase?: GobanEnginePhase; initial_state?: GobanEngineInitialState; marks?: { [mark: string]: string; }; latencies?: { [player_id: string]: number; }; player_pool?: { [id: number]: GobanEnginePlayerEntry; }; players?: { black: GobanEnginePlayerEntry; white: GobanEnginePlayerEntry; }; rengo?: boolean; rengo_teams?: { black: Array<GobanEnginePlayerEntry>; white: Array<GobanEnginePlayerEntry>; }; rengo_casual_mode?: boolean; reviews?: { [review_id: number]: GobanEnginePlayerEntry; }; is_game_record?: boolean; time_control?: JGOFTimeControl; moves?: GobanMovesArray; move_tree?: MoveTreeJson; ranked?: boolean; original_disable_analysis?: boolean; original_sgf?: string; free_handicap_placement?: boolean; score?: Score; outcome?: string; winner?: number | "black" | "white" | "tie"; start_time?: number; end_time?: number; game_date?: string; allow_self_capture?: boolean; automatic_stone_removal?: boolean; allow_ko?: boolean; allow_superko?: boolean; score_territory?: boolean; score_territory_in_seki?: boolean; strict_seki_mode?: boolean; score_stones?: boolean; score_passes?: boolean; score_prisoners?: boolean; score_handicap?: boolean; white_must_pass_last?: boolean; aga_handicap_scoring?: boolean; opponent_plays_first_after_resume?: boolean; superko_algorithm?: GobanEngineSuperKoAlgorithm; stalling_score_estimate?: StallingScoreEstimate; clock?: GameClock; /** When loading initial state or moves, by default GobanEngine will try and * handle bad data by just resorting to 'edit placing' moves. If this is * true, then those errors are thrown instead. */ throw_all_errors?: boolean; /** Removed stones in stone removal phase * Passing an array of JGOFMove objects is preferred, the string * format exists for historical backwards compatibility. It is an * encoded move string, e.g. "aa" for A19 */ removed?: string | JGOFMove[]; /** Intersections that need to be sealed before scoring should happen */ needs_sealing?: JGOFSealingIntersection[]; ogs?: { black_stones: string; black_territory: string; black_seki_eyes: string; black_dead_stones: string; white_stones: string; white_territory: string; white_seki_eyes: string; white_dead_stones: string; }; time_per_move?: number; errors?: Array<{ error: string; stack: any; }>; /** Deprecated, I don't think we need this anymore, but need to be sure */ ogs_import?: boolean; ladder?: number; black_player_id?: number; white_player_id?: number; } export interface GobanEngineInitialState { black?: string; white?: string; } /** Reviews are constructed by a stream of modifications messages, * this interface describes the format of those modification messages. * A message can contain any number of the fields listed. */ export interface ReviewMessage { /** The review ID. This is used when sending from the client to the server, * but is not sent by the server back to the client (as the id is encoded * in the message event name) */ "review_id"?: number; /** timestamp (ms) */ "ts"?: number; /** from (move number) */ "f"?: number; /** Moves made */ "m"?: string; /** official move [reviewing live game] */ "om"?: [number, number, number]; /** official undo [reviewing live game] */ "undo"?: boolean; /** text note for the current node */ "t"?: string; /** text append to the current node */ "t+"?: string; /** Marks made */ "k"?: { [mark: string]: string; }; /** pen point */ "pp"?: [number, number]; /** pen color / pen start */ "pen"?: string; /** Chat message */ "chat"?: { chat_id: string; player_id: number; channel: string; date: number; /** Turn number */ from: number; /** this might just be "string", i'm not entirely sure */ moves: AdHocPackedMove | string; }; /** Remove's the given chat by id */ "remove-chat"?: string; /** Clears the pen drawings on the node */ "clearpen"?: boolean; /** Delete */ "delete"?: number; /** Sets the owner of the review */ "owner"?: number | { id: number; username: string; }; /** Initial gamedata to review */ "gamedata"?: GobanEngineConfig; /** Sets the controller of the review */ "controller"?: number | { id: number; username: string; }; /** Updated information about the players, such as name etc. */ "player_update"?: JGOFPlayerSummary; } export interface PuzzleConfig extends BoardConfig { mode?: string; name?: string; puzzle_type?: string; initial_state?: GobanEngineInitialState; marks?: { [mark: string]: string; }; puzzle_autoplace_delay?: number; puzzle_opponent_move_mode?: PuzzleOpponentMoveMode; puzzle_player_move_mode?: PuzzlePlayerMoveMode; puzzle_rank?: number; puzzle_description?: string; puzzle_collection?: number; initial_player?: PlayerColor; move_tree?: MoveTreeJson; } export type PuzzlePlayerMoveMode = "free" | "fixed"; export type PuzzleOpponentMoveMode = "manual" | "automatic"; export type PuzzlePlacementSetting = { mode: "play"; } | { mode: "setup"; color: JGOFNumericPlayerColor; } | { mode: "place"; color: 0; }; export type PlayerColor = "black" | "white"; export declare class GobanEngine extends BoardState { throw_all_errors?: boolean; handicap_rank_difference?: number; handicap: number; initial_state: GobanEngineInitialState; komi: number; move_tree: MoveTree; move_tree_layout_vector: Array<number>; move_tree_layout_hash: { [coords: string]: MoveTree; }; move_tree_layout_dirty: boolean; readonly name: string; player_pool: { [id: number]: GobanEnginePlayerEntry; }; latencies?: { [player_id: string]: number; }; players: { black: GobanEnginePlayerEntry; white: GobanEnginePlayerEntry; }; puzzle_collection: number; puzzle_description: string; puzzle_opponent_move_mode: PuzzleOpponentMoveMode; puzzle_player_move_mode: PuzzlePlayerMoveMode; puzzle_rank: number; puzzle_type: string; readonly config: GobanEngineConfig; readonly disable_analysis: boolean; time_control: JGOFTimeControl; game_id: number; review_id?: number; decoded_moves: Array<JGOFMove>; automatic_stone_removal: boolean; group_ids?: Array<number>; rengo?: boolean; rengo_teams?: { [colour: string]: Array<GobanEnginePlayerEntry>; }; rengo_casual_mode: boolean; stalling_score_estimate?: StallingScoreEstimate; readonly is_game_record: boolean; private _phase; get phase(): GobanEnginePhase; set phase(phase: GobanEnginePhase); private _cur_move; get cur_move(): MoveTree; set cur_move(cur_move: MoveTree); private _cur_review_move; get cur_review_move(): MoveTree | undefined; set cur_review_move(cur_review_move: MoveTree | undefined); private _last_official_move; get last_official_move(): MoveTree; set last_official_move(last_official_move: MoveTree); private _strict_seki_mode; get strict_seki_mode(): boolean; set strict_seki_mode(strict_seki_mode: boolean); private _rules; get rules(): GobanEngineRules; set rules(rules: GobanEngineRules); private _winner?; get winner(): number | "black" | "white" | undefined; set winner(winner: number | "black" | "white" | undefined); private _undo_requested?; get undo_requested(): number | undefined; set undo_requested(undo_requested: number | undefined); private _outcome; get outcome(): string; set outcome(outcome: string); private aga_handicap_scoring; private allow_ko; private allow_self_capture; private allow_superko; private superko_algorithm; private dontStoreBoardHistory; free_handicap_placement: boolean; private loading_sgf; private move_before_jump?; needs_sealing?: Array<JGOFSealingIntersection>; score_prisoners: boolean; score_stones: boolean; score_handicap: boolean; score_territory: boolean; score_territory_in_seki: boolean; territory_included_in_sgf: boolean; constructor(config: GobanEngineConfig, goban_callback?: GobanBase, dontStoreBoardHistory?: boolean); /** * Decodes any of the various ways we express moves that we've accumulated over the years into * a unified `JGOFMove[]`. */ decodeMoves(move_obj: string | AdHocPackedMove | AdHocPackedMove[] | JGOFMove | JGOFMove[] | [object] | undefined): JGOFMove[]; encodeMoves(lst: JGOFMove[]): string; encodeMove(lst: JGOFMove): string; /** * Decodes a move string like `"A11"` into a move object like `{x: 0, y: 10}`. Also * handles the special cases like `".."` and "pass" which map to `{x: -1, y: -1}`. */ decodePrettyCoordinates(coordinates: string): JGOFMove; /** Encodes an x,y pair or a move object like {x: 0, y: 0} into a move string like "A1" */ prettyCoordinates(x: JGOFMove): string; prettyCoordinates(x: number, y: number): string; private getState; private setState; currentPositionId(): string; followPath(from_turn: number, moves: AdHocPackedMove | string, cb?: (x: number, y: number, edited: boolean, color: number) => void): Array<MoveTree>; updatePlayers(player_update: JGOFPlayerSummary): void; /** Returns true if there was a previous to show */ showPrevious(): boolean; /** Returns true if there was a next to show */ showNext(): boolean; /** Returns true if there was a next to show */ showNextTrunk(): boolean; jumpTo(node?: MoveTree | null): void; jumpToLastOfficialMove(): void; /** Saves our current move as our last official move */ setLastOfficialMove(): void; /** returns true if our current move is our last official move */ isLastOfficialMove(): boolean; /** Returns a move string from the given official move number (aka branch point) */ getMoveDiff(): { from: number; moves: string; }; setAsCurrentReviewMove(): void; deleteCurMove(): void; gameCanBeCancelled(): boolean; jumpToOfficialMoveNumber(move_number: number): void; private opponent; private captureGroup; isParticipant(player_id: number): boolean; isActivePlayer(player_id: number): boolean; playerToMoveOnOfficialBranch(): number; playerToMove(): number; playerNotToMove(): number; otherPlayer(): JGOFNumericPlayerColor; playerColor(player_id?: number): "black" | "white" | "invalid"; colorToMove(): "black" | "white"; colorNotToMove(): "black" | "white"; playerByColor(color: PlayerColor | JGOFNumericPlayerColor): JGOFNumericPlayerColor; /** Returns the number of stones removed. If you want the coordinates of * the stones removed, pass in a removed_stones array to append the moves * to. */ place(x: number, y: number, checkForKo?: boolean, errorOnSuperKo?: boolean, dontCheckForSuperKo?: boolean, dontCheckForSelfCapture?: boolean, isTrunkMove?: boolean, removed_stones?: Array<JGOFIntersection>): number; isBoardRepeating(superko_rule: GobanEngineSuperKoAlgorithm): boolean; editPlace(x: number, y: number, color: JGOFNumericPlayerColor, isTrunkMove?: boolean): void; initialStatePlace(x: number, y: number, color: JGOFNumericPlayerColor, dont_record_placement?: boolean): void; resetMoveTree(): void; computeInitialStateForForkedGame(): { black: string; white: string; }; setNeedsSealing(x: number, y: number, needs_sealing?: boolean): void; getStoneRemovalString(): string; getMoveNumber(): number; getCurrentMoveNumber(): number; /** * Computes the score of the current board state. * * If only_prisoners is true, we return the same data structure for convenience, but only * the prisoners will be counted, other sources of points will be zero. */ computeScore(only_prisoners?: boolean): Score; handicapMovesLeft(): number; /** * This function migrates old config's to whatever our current standard is * for configs. */ private static migrateConfig; /** * This function fills in default values for any missing fields in the * config. */ static fillDefaults(game_obj: GobanEngineConfig): GobanEngineConfig; static clearRuleSettings(game_obj: GobanEngineConfig): GobanEngineConfig; private parseSGF; estimateScore(trials: number, tolerance: number, prefer_remote?: boolean, should_autoscore?: boolean): ScoreEstimator; getMoveByLocation(x: number, y: number, include_forward_search: boolean): MoveTree | null; exportAsPuzzle(): PuzzleConfig; getBlackPrisoners(): number; getWhitePrisoners(): number; getHandicapPointAdjustmentForWhite(): number; parentEventEmitter?: EventEmitter<GobanEvents>; emit<K extends keyof GobanEvents>(event: K, ...args: EventEmitter.EventArgs<GobanEvents, K>): boolean; setRemoved(x: number, y: number, removed: boolean, emit_stone_removal_updated?: boolean): void; }