from typing import Final

WHITE: Final[int]
BLACK: Final[int]
TOTAL_INPUT_PLANES: Final[int]
HISTORY_LENGTH: Final[int]
PIECE_PLANES: Final[int]
CONSTANT_PLANES: Final[int]
NUM_DIRECTIONS: Final[int]
NUM_KNIGHT_DELTAS: Final[int]
NUM_UNDERPROMO_DIRECTIONS: Final[int]
NUM_UNDERPROMO_PIECES: Final[int]
NUM_PROMOTION_ORIENTATIONS: Final[int]

def parse_pgn(pgn: str) -> list[PgnGame]: ...

class Board:
    def __init__(self, width: int, height: int, fen: str) -> None: ...
    @staticmethod
    def standard() -> Board: ...
    @staticmethod
    def empty(width: int, height: int) -> Board: ...
    def to_fen(self) -> str: ...
    def get_piece(self, col: int, row: int) -> Piece | None: ...
    def set_piece(self, col: int, row: int, piece: Piece | None = None) -> None: ...
    def clear(self) -> None: ...
    def width(self) -> int: ...
    def height(self) -> int: ...
    def __str__(self) -> str: ...
    def __repr__(self) -> str: ...

class Game:
    def __init__(self, width: int, height: int, fen: str, castling_enabled: bool) -> None: ...
    @staticmethod
    def standard() -> Game: ...
    def turn(self) -> int: ...
    def fullmove_number(self) -> int: ...
    def halfmove_clock(self) -> int: ...
    def castling_enabled(self) -> bool: ...
    def has_kingside_castling_rights(self, color: int) -> bool: ...
    def has_queenside_castling_rights(self, color: int) -> bool: ...
    def make_move(self, move_: Move) -> bool: ...
    def make_move_unchecked(self, move_: Move) -> None: ...
    def unmake_move(self) -> bool: ...
    def is_legal_move(self, move_: Move) -> bool: ...
    def legal_moves(self) -> list[Move]: ...
    def psuedo_legal_moves(self) -> list[Move]: ...
    def legal_moves_for_position(self, col: int, row: int) -> list[Move]: ...
    def move_to_lan(self, move_: Move) -> str: ...
    def move_from_lan(self, lan: str) -> Move: ...
    def move_to_san(self, move_: Move) -> str: ...
    def move_from_san(self, san: str) -> Move: ...
    def is_check(self) -> bool: ...
    def is_checkmate(self) -> bool: ...
    def is_stalemate(self) -> bool: ...
    def is_over(self) -> bool: ...
    def width(self) -> int: ...
    def height(self) -> int: ...
    def get_piece(self, col: int, row: int) -> Piece | None: ...
    def set_piece(self, col: int, row: int, piece: Piece | None = None) -> None: ...
    def legal_action_indices(self) -> list[int]: ...
    def apply_action(self, action: int) -> bool: ...
    def encode_game_planes(self) -> tuple[list[float], int, int, int]: ...
    def action_planes_count(self) -> int: ...
    def decode_action(self, action: int) -> Move | None: ...
    def total_actions(self) -> int: ...
    def board_shape(self) -> tuple[int, int]: ...
    def input_plane_count(self) -> int: ...
    def reward_absolute(self) -> float: ...
    def reward_from_perspective(self, perspective: int) -> float: ...
    def is_insufficient_material(self) -> bool: ...
    def has_legal_en_passant(self) -> bool: ...
    def en_passant_square(self) -> Position | None: ...
    def outcome(self) -> GameOutcome | None: ...
    def to_fen(self) -> str: ...
    def clone(self) -> Game: ...
    def __hash__(self) -> int: ...
    def __str__(self) -> str: ...
    def __repr__(self) -> str: ...

class Move:
    @staticmethod
    def from_rowcol(src_col: int, src_row: int, dst_col: int, dst_row: int) -> Move: ...
    @classmethod
    def from_lan(cls, lan: str, board_width: int, board_height: int) -> Move: ...
    def src_square(self) -> tuple[int, int]: ...
    def dst_square(self) -> tuple[int, int]: ...
    def promotion(self) -> str | None: ...
    def to_lan(self) -> str: ...
    def encode(self, width: int, height: int) -> int | None: ...
    def __str__(self) -> str: ...
    def __repr__(self) -> str: ...
    def __eq__(self, other: Move) -> bool: ...
    def __hash__(self) -> int: ...

class Piece:
    def __init__(self, piece_type: str, color: int) -> None: ...
    def color(self) -> int: ...
    def symbol(self) -> str: ...
    def __str__(self) -> str: ...
    def __repr__(self) -> str: ...

class Position:
    def __init__(self, col: int, row: int) -> None: ...
    def col(self) -> int: ...
    def row(self) -> int: ...
    def __str__(self) -> str: ...
    def __repr__(self) -> str: ...

class GameOutcome:
    def winner(self) -> int | None: ...
    def encode_winner_absolute(self) -> float: ...
    def encode_winner_from_perspective(self, perspective: int) -> float: ...
    def is_draw(self) -> bool: ...
    def __str__(self) -> str: ...
    def __repr__(self) -> str: ...
    def __eq__(self, other: GameOutcome) -> bool: ...

class PgnGame:
    def headers(self) -> list[tuple[str, str]]: ...
    def header(self, key: str) -> str | None: ...
    def white(self) -> str | None: ...
    def black(self) -> str | None: ...
    def result(self) -> str: ...
    def moves(self) -> list[Move]: ...
    def starting_fen(self) -> str | None: ...
    def starting_game(self) -> Game: ...
    def game(self) -> Game: ...
    def __repr__(self) -> str: ...

class SearchResult:
    best_move: Move
    best_move_lan: str
    ponder_move: Move | None
    ponder_move_lan: str | None
    score_cp: int | None
    score_mate: int | None
    depth: int | None
    nodes: int | None
    pv: list[str]
    def __str__(self) -> str: ...
    def __repr__(self) -> str: ...

class UciEngine:
    def __init__(
        self,
        program: str,
        args: list[str] = ...,
    ) -> None: ...
    def engine_name(self) -> str | None: ...
    def engine_author(self) -> str | None: ...
    def set_option(self, name: str, value: str) -> None: ...
    def is_ready(self) -> None: ...
    def new_game(self) -> None: ...
    def new_game_from_fen(self, fen: str) -> None: ...
    def set_position_startpos(self) -> None: ...
    def set_position_fen(self, fen: str) -> None: ...
    def set_position_pgn_start(self, pgn_game: PgnGame) -> None: ...
    def make_move(self, move_: Move) -> bool: ...
    def make_move_lan(self, lan: str) -> bool: ...
    def go_depth(self, depth: int) -> SearchResult: ...
    def go_movetime(self, ms: int) -> SearchResult: ...
    def go_clock(self, wtime: int, btime: int, winc: int, binc: int) -> SearchResult: ...
    def go_bestmove_depth(self, depth: int) -> Move: ...
    def go_bestmove_movetime(self, ms: int) -> Move: ...
    def turn(self) -> int: ...
    def is_over(self) -> bool: ...
    def legal_moves(self) -> list[Move]: ...
    def undo(self) -> None: ...
    def send_command(self, cmd: str) -> str: ...
    def quit(self) -> None: ...
    def __repr__(self) -> str: ...
