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, AdHocPauseControl } 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;
    pause_control?: AdHocPauseControl;
    /** a bit confusing — this reflects the last time a pause was started, even if the game is not currently paused */
    paused_since?: number;
    /** Optional bot parameters */
    bot_parameters?: {
        slug: string;
        [key: string]: number | string | boolean;
    };
    /** 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);
    undo_requested_by?: number;
    private _undo_requested_move_count?;
    get undo_requested_move_count(): number;
    set undo_requested_move_count(undo_requested_move_count: number | undefined);
    getUndoRequestStones(): Array<{
        x: number;
        y: number;
        move_number: number;
    }>;
    isStoneInUndoRequest(x: number, y: number): boolean;
    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;
}
