goban-engine
Version:
This contains the built Go engine that is used by the Goban package. There are no display components in this package, only the logic for playing the game of Go, making it suitable for usage in node.js or other server-side environments.
261 lines (260 loc) • 10.2 kB
TypeScript
import { GobanEngine, GobanEngineConfig, GobanEnginePhase, GobanEngineRules, PlayerColor, PuzzleConfig, PuzzlePlacementSetting } from "./engine";
import { MoveTree, MoveTreePenMarks } from "./engine/MoveTree";
import { ScoreEstimator } from "./engine/ScoreEstimator";
import { setGobanTranslations } from "./engine/translate";
import { JGOFClock, JGOFIntersection, JGOFTimeControl, JGOFPlayerClock, JGOFTimeControlSystem, JGOFPlayerSummary, JGOFSealingIntersection, JGOFNumericPlayerColor, JGOFMove } from "./engine/formats/JGOF";
import { AdHocPackedMove, AdHocPauseControl } from "./engine/formats/AdHocFormat";
import { MessageID } from "./engine/messages";
import type { GobanSocket } from "./engine/GobanSocket";
import type { ServerToClient, GameChatLine } from "./engine/protocol";
import { EventEmitter } from "eventemitter3";
import { setGobanCallbacks } from "./Goban/callbacks";
export type GobanModes = "play" | "puzzle" | "score estimation" | "analyze" | "conditional";
export type AnalysisTool = "stone" | "draw" | "label" | "score" | "removal";
export type AnalysisSubTool = "black" | "white" | "alternate" | "letters" | "numbers" | string;
export interface GobanBounds {
top: number;
left: number;
right: number;
bottom: number;
}
export type GobanChatLog = Array<GameChatLine>;
export interface GobanConfig extends GobanEngineConfig, PuzzleConfig {
display_width?: number;
interactive?: boolean;
mode?: GobanModes;
square_size?: number | ((goban: GobanBase) => number) | "auto";
getPuzzlePlacementSetting?: () => PuzzlePlacementSetting;
chat_log?: GobanChatLog;
spectator_log?: GobanChatLog;
malkovich_log?: GobanChatLog;
pause_control?: AdHocPauseControl;
paused_since?: number;
draw_top_labels?: boolean;
draw_left_labels?: boolean;
draw_bottom_labels?: boolean;
draw_right_labels?: boolean;
bounds?: GobanBounds;
dont_draw_last_move?: boolean;
dont_show_messages?: boolean;
last_move_radius?: number;
circle_radius?: number;
one_click_submit?: boolean;
double_click_submit?: boolean;
variation_stone_opacity?: number;
stone_font_scale?: number;
auth?: string;
time_control?: JGOFTimeControl;
marks?: {
[mark: string]: string;
};
isPlayerOwner?: () => boolean;
isPlayerController?: () => boolean;
isInPushedAnalysis?: () => boolean;
leavePushedAnalysis?: () => void;
onError?: (err: Error) => void;
onScoreEstimationUpdated?: (winning_color: "black" | "white", points: number) => void;
game_type?: "temporary";
username?: string;
server_socket?: GobanSocket;
connect_to_chat?: number | boolean;
}
export interface AudioClockEvent {
/** Number of seconds left in the current period */
countdown_seconds: number;
/** Full player clock information */
clock: JGOFPlayerClock;
/** The player (id) whose turn it is */
player_id: string;
/** The player whose turn it is */
color: PlayerColor;
/** Time control system being used by the clock */
time_control_system: JGOFTimeControlSystem;
/** True if we are in overtime. This is only ever set for systems that have
* a concept of overtime.
*/
in_overtime: boolean;
}
export interface JGOFClockWithTransmitting extends JGOFClock {
black_move_transmitting: number;
white_move_transmitting: number;
}
export interface StateUpdateEvents {
mode: (d: GobanModes) => void;
title: (d: string) => void;
phase: (d: GobanEnginePhase) => void;
cur_move: (d: MoveTree) => void;
cur_review_move: (d: MoveTree | undefined) => void;
last_official_move: (d: MoveTree) => void;
submit_move: (d: (() => void) | undefined) => void;
analyze_tool: (d: AnalysisTool) => void;
analyze_subtool: (d: AnalysisSubTool) => void;
score_estimate: (d: ScoreEstimator | null) => void;
strict_seki_mode: (d: boolean) => void;
rules: (d: GobanEngineRules) => void;
winner: (d: number | undefined) => void;
undo_requested: (d: number | undefined) => void;
undo_canceled: () => void;
paused: (d: boolean) => void;
outcome: (d: string) => void;
review_owner_id: (d: number | undefined) => void;
review_controller_id: (d: number | undefined) => void;
stalling_score_estimate: ServerToClient["game/:id/stalling_score_estimate"];
}
export interface GobanEvents extends StateUpdateEvents {
"destroy": () => void;
"update": () => void;
"chat-reset": () => void;
"error": (d: any) => void;
"gamedata": (d: any) => void;
"chat": (d: any) => void;
"engine.updated": (engine: GobanEngine) => void;
"load": (config: GobanConfig) => void;
"show-message": (message: {
formatted: string;
message_id: string;
parameters?: {
[key: string]: any;
};
}) => void;
"clear-message": () => void;
"submitting-move": (tf: boolean) => void;
"chat-remove": (ids: {
chat_ids: Array<string>;
}) => void;
"move-made": () => void;
"player-update": (player: JGOFPlayerSummary) => void;
"played-by-click": (player: {
player_id: number;
x: number;
y: number;
}) => void;
"review.sync-to-current-move": () => void;
"review.updated": () => void;
"review.load-start": () => void;
"review.load-end": () => void;
"puzzle-wrong-answer": () => void;
"puzzle-correct-answer": () => void;
"state_text": (state: {
title: string;
show_moves_made_count?: boolean;
}) => void;
"advance-to-next-board": () => void;
"auto-resign": (obj: {
game_id: number;
player_id: number;
expiration: number;
}) => void;
"clear-auto-resign": (obj: {
game_id: number;
player_id: number;
}) => void;
"set-for-removal": {
x: number;
y: number;
removed: boolean;
};
"captured-stones": (obj: {
removed_stones: Array<JGOFIntersection>;
}) => void;
"stone-removal.accepted": () => void;
"stone-removal.updated": () => void;
"stone-removal.needs-sealing": (positions: undefined | JGOFSealingIntersection[]) => void;
"stone-removal.auto-scoring-started": () => void;
"stone-removal.auto-scoring-complete": () => void;
"conditional-moves.updated": () => void;
"puzzle-place": (obj: {
x: number;
y: number;
width: number;
height: number;
color: "black" | "white";
}) => void;
"clock": (clock: JGOFClockWithTransmitting | null) => void;
"audio-game-started": (obj: {
/** Player to move */
player_id: number;
}) => void;
"audio-game-ended": (winner: "black" | "white" | "tie") => void;
"audio-pass": () => void;
"audio-stone": (obj: {
x: number;
y: number;
width: number;
height: number;
color: "black" | "white";
}) => void;
"audio-other-player-disconnected": (obj: {
player_id: number;
}) => void;
"audio-other-player-reconnected": (obj: {
player_id: number;
}) => void;
"audio-clock": (event: AudioClockEvent) => void;
"audio-disconnected": () => void;
"audio-reconnected": () => void;
"audio-capture-stones": (obj: {
count: number;
already_captured: number;
}) => void;
"audio-game-paused": () => void;
"audio-game-resumed": () => void;
"audio-enter-stone-removal": () => void;
"audio-resume-game-from-stone-removal": () => void;
"audio-undo-requested": () => void;
"audio-undo-granted": () => void;
}
/**
* Goban serves as a base class for our renderers as well as a namespace for various
* classes, types, and enums.
*
* You can't create an instance of a Goban directly, you have to create an instance of
* one of the renderers, such as GobanSVG.
*/
export declare abstract class GobanBase extends EventEmitter<GobanEvents> {
static setTranslations: typeof setGobanTranslations;
static setCallbacks: typeof setGobanCallbacks;
/** Base fields **/
readonly goban_id: number;
private _destroyed;
get destroyed(): boolean;
abstract engine: GobanEngine;
abstract enablePen(): void;
abstract disablePen(): void;
abstract clearAnalysisDrawing(): void;
abstract drawPenMarks(pen_marks: MoveTreePenMarks): void;
abstract showMessage(msg_id: MessageID, parameters?: {
[key: string]: any;
}, timeout?: number): void;
abstract clearMessage(): void;
abstract drawSquare(i: number, j: number): void;
abstract redraw(force_clear?: boolean): void;
abstract move_tree_redraw(no_warp?: boolean): void;
abstract setMoveTreeContainer(container: any): void;
/** Called by engine when a location has been set to a color. */
abstract set(x: number, y: number, player: JGOFNumericPlayerColor): void;
/** Called when a location is marked or unmarked for removal */
abstract setForRemoval(x: number, y: number, removed: boolean, emit_stone_removal_updated: boolean): void;
/** Called when Engine.setState loads a previously saved board state. */
abstract setState(): void;
abstract updateScoreEstimation(): void;
constructor();
destroy(): void;
/**
* 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;
/** 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;
/**
* 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;
/** True if the game is a game record of a real life game */
get is_game_record(): boolean;
}