Reference

Contents

Index

OrbisChessEngine.BoardType
Board

A chess board representation using bitboards.

  • bitboards: A fixed-size vector where each element corresponds to a piece type's bitboard.
  • side_to_move: The side to move.
  • castling_rights: A 4-bit integer representing castling rights (KQkq).
  • en_passant: The square index (0-63) for en passant target, or -1 if none.
  • halfmove_clock: The number of halfmoves since the last capture or pawn move (for the fifty-move rule).
  • position_history: A vector of position Zobrist hashes for detecting threefold repetition.
  • undo_stack: A stack of UndoInfo structs for unmaking moves.
  • undo_index: The current index in the undo stack.
  • eval_score: Cached evaluation score from White's point of view.
  • game_phase_value: Cached phase numerator (sum of weights) for evaluation scaling.
source
OrbisChessEngine.BoardMethod
Board(; fen::String = START_FEN)

Construct a chess Board object from a FEN string.

  • fen::String: a FEN string representing the board position. Defaults to START_FEN (the standard starting position).

Example

b1 = Board()
# Only a white king on E1 and a black king on E8 with white to move
b2 = Board(fen = "4k3/8/8/8/8/8/8/4K3 w - - 0 1")
source
OrbisChessEngine.GameType
Game

A struct representing a chess game with time control.

  • board: The current state of the chess board.
  • white_time: Time remaining for White in milliseconds.
  • black_time: Time remaining for Black in milliseconds.
  • increment: Time increment per move in milliseconds.
source
OrbisChessEngine.GameMethod
Game(tc::AbstractString; fen::String = START_FEN)

Create a Game object with a specified time control and optional starting position.

  • tc::AbstractString: Time control string, e.g., "5+3" (5 minutes + 3 seconds increment).
  • fen::String: Optional FEN string to start the game (default: START_FEN).

Example

g1 = Game("3+2")    # 3 minutes + 2 seconds increment
g2 = Game("10+0")  # 10 minutes, no increment
g3 = Game("5+5", fen="8/8/8/8/8/8/8/K6k w - - 0 1")  # custom starting position
source
OrbisChessEngine.GameMethod
Game(; minutes=3, increment=2, fen::String = START_FEN)

Create a Game object with a specified time control and optional starting position.

  • minutes: Initial time in minutes for both players (default: 3).
  • increment: Increment in seconds per move (default: 2).
  • fen::String: Optional FEN string to start the game (default: START_FEN).

Example

g1 = Game()                        # 3+2 game from starting position
g2 = Game(minutes=5, increment=0) # 5-minute blitz game with no increment
g3 = Game(fen="8/8/8/8/8/8/8/K6k w - - 0 1")  # starting from custom FEN
source
OrbisChessEngine.MoveType
Move

A chess move.

  • from is a square index (0-63)
  • to is a square index (0-63)
  • promotion is the piece type promoted to (0 if none)
  • capture is captured piece type (0 if none)
  • castling: 0 = normal, 1 = kingside, 2 = queenside
  • en_passant: true if en passant capture
source
OrbisChessEngine.MoveMethod
Move(board::Board, str::AbstractString)

Construct a Move from a long algebraic string like "e2e4" or "e7e8=Q", using the board to infer capture, en passant, and castling.

Captures are inferred based on the board state (so "e4d5" captures if d5 is occupied by opponent). Castling can be specified with "O-O" (kingside) or "O-O-O" (queenside). Also accepts "o-o", "0-0", "o-o-o", "0-0-0".

Note, that this function does not validate the legality of the move; it only constructs the Move object.

Example

Illegal moves are also allowed; legality is not checked here.

julia> board = Board();

julia> mv = Move(board, "e2e4")
e2e4

julia> make_move!(board, mv)

julia> mv = Move(board, "d7d4")
d7d4

julia> make_move!(board, mv)
source
OrbisChessEngine.SearchResultType
SearchResult

Result of a search operation.

  • score: the evaluation score of the position, from White's perspective.
  • move: the best move found (NO_MOVE if none was found).
  • from_book: whether move came from the opening book rather than search.
  • complete: false if this result was cut short by the time budget before finishing.
source
OrbisChessEngine.UndoInfoType
UndoInfo

Information needed to undo a move

  • captured_piece: The piece type that was captured, or 0 if none.
  • en_passant: The previous en passant square.
  • castling_rights: The previous castling rights.
  • halfmove_clock: The previous halfmove clock.
  • moved_piece: The piece type that was moved.
  • promotion: The piece type if the move was a promotion, or 0 otherwise.
  • is_en_passant: A boolean indicating if the move was an en passant capture.
  • prev_eval_score: The evaluation score before the move.
  • prev_game_phase_value: The game phase value before the move.
source
OrbisChessEngine.apply_moves!Method
apply_moves!(board::Board, moves::AbstractString...)

Apply a sequence of moves in long algebraic notation (LAN) to board in-place. Only legal moves are allowed; an error is thrown if any move is illegal.

Since this function modifies board in-place, all moves up to the first illegal move are applied. The board will reflect these moves even if a subsequent move is illegal.

  • board: a Board struct representing the current chess position.
  • moves: one or more moves as LAN strings (e.g., "e2e4", "g1f3").

Example

board = Board()
apply_moves!(board, "e2e4", "e7e5", "g1f3", "b8c6", "f1b5")
source
OrbisChessEngine.apply_movesMethod
apply_moves(board::Board, moves::AbstractString...) -> Board

Return a new board with a sequence of moves in long algebraic notation (LAN) applied. The original board is left unchanged. Only legal moves are allowed; an error is thrown if any move is illegal.

  • board: a Board struct representing the current chess position.
  • moves: one or more moves as LAN strings (e.g., "e2e4", "g1f3").

Example

board = Board()  # starting position
new_board = apply_moves(board, "e2e4", "e7e5", "g1f3", "b8c6", "f1b5")
source
OrbisChessEngine.engine_move!Method
engine_move!(game::Game; opening_book::Union{Nothing, PolyglotBook}=KOMODO_OPENING_BOOK, verbose=false)

Searches for and makes a move for the current player, updating the Game struct with the updated board and time remaining.

  • game: Game struct
  • opening_book: Optional PolyglotBook for opening moves
  • verbose: If true, print move details and time used

The time allocated for the search is done automatically based on remaining time and increment. See search for details on how the search is performed.

Example

game = Game()

# Make a move using the Komodo opening book
engine_move!(game, opening_book = KOMODO_OPENING_BOOK)

# Make a move without the opening book
engine_move!(game, opening_book = nothing)
source
OrbisChessEngine.engine_moveMethod
engine_move(game::Game; opening_book::Union{Nothing, PolyglotBook}=KOMODO_OPENING_BOOK, verbose=false) -> Game

Searches for and makes a move for the current player, returning a new Game struct with the updated board and time remaining.

  • game: Game struct
  • opening_book: Optional PolyglotBook for opening moves
  • verbose: If true, print move details and time used

The time allocated for the search is done automatically based on remaining time and increment. See search for details on how the search is performed.

Example

game1 = Game()

# Make a move using the Komodo opening book
game2 = engine_move(game, opening_book = KOMODO_OPENING_BOOK)

# Make a move without the opening book
game3 = engine_move(game, opening_book = nothing)
source
OrbisChessEngine.evaluateMethod
evaluate(board::Board) -> Int

Evaluate a position from White's perspective using piece-square tables.

A static material+PST sum only: it does not check for checkmate, stalemate, or draws (too expensive to run at every quiescence node), which is instead _search's responsibility since it already generates legal moves anyway.

Example

julia> board = Board();

julia> evaluate(board)
0
source
OrbisChessEngine.game_statusMethod
game_status(x::Union{Board,Game}) -> Symbol

Return the current game status.

Returns one of:

  • :checkmate_white
  • :checkmate_black
  • :stalemate
  • :draw_threefold
  • :draw_fiftymove
  • :draw_insufficient_material
  • :timeout_white
  • :timeout_black
  • :ongoing

Passing a Game additionally checks each side's clock for :timeout_white/ :timeout_black, which a bare Board (no time control) cannot detect.

Example

julia> board = Board();

julia> game_status(board)
:ongoing

julia> game = Game();

julia> game_status(game)
:ongoing
source
OrbisChessEngine.in_checkMethod
in_check(board::Board, side::Side) -> Bool

Check if the king of the given side is in check

  • board: Board struct
  • side: Side (WHITE or BLACK)

Returns: Bool

source
OrbisChessEngine.make_move!Method
make_move!(board::Board, m::Move)

Apply the move m to board in-place, updating the board state, castling rights, en passant square, halfmove clock, and internal evaluation.

  • board: a Board struct representing the current chess position.
  • m: a Move object. Typically created from a long algebraic notation (LAN) string using Move(board, "e2e4").

Example

board = Board()
mv = Move(board, "e2e4")
make_move!(board, mv)
source
OrbisChessEngine.make_moveMethod
make_move(board::Board, m::Move)

Return a new board with the move m applied, leaving the original board unchanged. Updates castling rights, en passant square, halfmove clock, and internal evaluation.

  • board: a Board struct representing the current chess position.
  • m: a Move object. Typically created from a long algebraic notation (LAN) string using Move(board, "e2e4").

Example

board = Board()
mv = Move(board, "e2e4")
new_board = make_move(board, mv)
source
OrbisChessEngine.perftMethod
perft(board::Board, depth::Int) -> Int

Compute the number of leaf nodes reachable from the given board position at the given depth (perft). It uses the Board struct to imitate search behavior. In particular, this means it still computes Zobrist hashes and updates evaluation scores, slowing it down compared to a minimal perft implementation.

Example

julia> board = Board();

julia> perft(board, 3)
8902
source
OrbisChessEngine.perft_fastMethod
perft_fast(board::Board, depth::Int) -> Int

Compute the number of leaf nodes reachable from the given board position at the given depth (perft) using multiple threads at the root. It uses the Board struct to imitate search behavior. In particular, this means it still computes Zobrist hashes and updates evaluation scores, slowing it down compared to a minimal perft implementation.

Example

julia> board = Board();

julia> perft_fast(board, 3)
8902
source
OrbisChessEngine.plotMethod
plot(x::Union{Board,Game}; board_orientation = :white, io::IO = stdout)

Display a chess board.

By default this prints a colored board to the terminal using Unicode chess piece characters. If a Makie backend (CairoMakie, GLMakie, WGLMakie, ...) together with FileIO and Images are loaded, plot instead returns a graphical Makie.Figure of the board (board_orientation and io are ignored in that case).

  • x: a Board or Game to display
  • board_orientation: :white (default) or :black to set the perspective
  • io: IO stream to print to (default: stdout)

Example

board = Board()
plot(board)

# Change orientation
plot(board; board_orientation = :black)

# Change plot preference colors
using Preferences
set_preferences!(
    OrbisChessEngine,
    "theme" => "light",
)
plot(board)

# Plot graphically instead of in the terminal.
# Use `import`, not `using`, for the Makie backend: CairoMakie/GLMakie/WGLMakie
# export their own `plot` function, which would otherwise clash with this one.
import CairoMakie, FileIO, Images
plot(board)

If the piece characters don't display correctly, try another font; we recommend "DejaVu Sans Mono".

source
OrbisChessEngine.run_uciMethod
run_uci()

Run the UCI (Universal Chess Interface) command loop, reading commands from stdin and writing responses to stdout until a "quit" command is received or stdin is closed.

See https://www.wbec-ridderkerk.nl/html/UCIProtocol.html for the protocol specification. Only a subset is implemented: go honors depth, movetime, and wtime/btime (+ increment) time control; go infinite and stop do not interrupt an in-progress search (search runs synchronously to completion), since that would require restructuring the search to run cancellably in the background.

Example

Launch as a UCI engine process, e.g. for use with a UCI-speaking GUI or cutechess-cli:

julia --project=. bin/orbis_uci.jl
source
OrbisChessEngine.searchMethod
search(
    board::Board;
    depth::Int,
    opening_book::Union{Nothing, PolyglotBook} = KOMODO_OPENING_BOOK,
    verbose::Bool = false,
    uci_info::Bool = false,
    time_budget::Int = typemax(Int),
    max_time_budget::Int = time_budget
)::SearchResult

Search for the best move using minimax with iterative deepening, alpha-beta pruning, quiescence search, null move pruning, and transposition tables.

Arguments:

  • board: current board position
  • depth: search depth
  • opening_book: if provided, uses a opening book. Default is KOMODO_OPENING_BOOK

taken from free-opening-books. Set to nothing to disable. See load_polyglot_book to load custom books.

  • verbose: if true, prints human-readable search information and principal variation (PV) at each depth
  • uci_info: if true, prints a UCI-style info depth ... score ... time ... nodes ... nps ... pv ... line at each depth (score is relative to the side to move, per the UCI spec, unlike the always-White-relative score field on the returned SearchResult)
  • time_budget: soft time limit in milliseconds; the search stops after the current depth finishes once this is reached, unless the result looks unstable (see search_root), in which case it keeps going up to max_time_budget
  • max_time_budget: hard time limit in milliseconds; can cut a depth off mid-search. Defaults to time_budget (no extension allowed)

Returns:

  • a SearchResult. move is NO_MOVE if no legal move exists (e.g. checkmate/stalemate); see SearchResult's docstring for the complete field's meaning.

Example

board = Board()
search(board; depth=5, opening_book=nothing, verbose=true, time_budget=5000)
source
OrbisChessEngine.undo_move!Method
undo_move!(board::Board, m::Move)

Undo move m on board in place, restoring previous state.

  • board: Board struct
  • m: Move struct

Example

board = Board()
copy_board = deepcopy(board)

mv = Move(board, "e2e4")
make_move!(board, mv)
undo_move!(board, mv)
board == copy_board
source
OrbisChessEngine.undo_moveMethod
undo_move(board::Board, m::Move) -> Board

Return a new board with move m undone, leaving the original board unchanged.

  • board: Board struct
  • m: Move struct

Example

board = Board()
mv = Move(board, "e2e4")

new_board = make_move(board, mv)
original_board = undo_move(new_board, mv)
board == original_board
source