Skip to content

nemeott/rust-chess

Repository files navigation

rust-chess

rust-chess is a Python package that acts as a bridge between the chess crate and Python. It aims to provide a high-performance chess library that is largely compatible with python-chess syntax.

This repository provides:

  • A Python package rust-chess created using Maturin.
  • A type stub (rust_chess.pyi) providing hover documentation and examples in IDEs.
  • A micro-benchmark comparison against python-chess in the file compare.py.

WARNING

This project is almost out of alpha/beta phase (pun intended). Expect some breaking changes, refactoring, and new features.

Overview

Quick usage example:

import rust_chess as rc

board = rc.Board()  # Create a board
move = rc.Move.from_uci("e2e4")  # Create move from UCI

# Check if the move is legal for the current board
if board.is_legal_move(move):
    # Make a move on the current board
    # Disable the legality check since we already know the move is legal
    board.make_move(move, check_legality=False)

# Make move onto a new board
new_board = board.make_move_new(rc.Move("e7e5"))

# Get the FEN of the current board
print(board.get_fen())

# Generate the next move
move = board.generate_next_move()

# Create a list of all legal moves (exhausts the generator)
moves = list(board.generate_legal_moves())

# The generator saves state
assert move not in moves

# Reset the generator to be able to generate moves again
board.reset_move_generator()

# Generate legal captures
captures = list(board.generate_legal_captures())

Use IDE completion or read the generated stub (rust_chess.pyi) for detailed function signatures and documentation. Actual documentation coming soon (TM).

Features

Data Types and Constants

  • Color: WHITE, BLACK, COLORS
  • PieceType: PAWN, KNIGHT, BISHOP, ROOK, QUEEN, KING, PIECE_TYPES
  • Piece: WHITE_PAWN ... BLACK_KING, COLORED_PIECES
  • Square: A1 .. H8, SQUARES
  • Bitboard: BB_EMPTY, BB_FULL, BB_FILE_A ... BB_FILE_H, BB_RANK_1 ... BB_RANK_8, BB_FILES, BB_RANKS
  • Move: TODO: Add castling and null moves?
  • PyRepetitionDetectionMode enum: .NONE, .PARTIAL, .FULL
    • Currently no difference between partial and full for now, but the plan is to have partial have a smaller history list
  • CastleRights enum: .NO_RIGHTS, .QUEENSIDE, .KINGSIDE, .BOTH
  • BoardStatus enum: .ONGOING, .FIVE_FOLD_REPETITION, .SEVENTY_FIVE_MOVES, .INSUFFICIENT_MATERIAL, .STALEMATE, .CHECKMATE
  • Board: No constants.

Basic Features Overview

  • Create a Board from an optional FEN string with board = rc.Board().
  • Get the FEN of a board by calling get_fen() on a board object.
  • Iterate over every square using the rc.SQUARES constant or get an individual square by using the corresponding constant (ex. rc.E2).
  • Create a Bitboard from an integer or square.
    • Supports bitwise operators, shift operators, popcnt, iteration, and conversion to and from a Square.
  • Get many different bitboards for the current board including board.get_color_bitboard(rc.WHITE), board.get_piece_type_bitboard(rc.PAWN), board.get_checkers_bitboard(), and more.
  • Create a move from a source and destination square, with an optional promotion piece type using move = rc.Move(rc.E2, rc.E4).
    • Can also create a move from a UCI string using move = rc.Move("e2e4") or move = rc.Move.from_uci("e2e4").
  • Check if a move is legal with board.is_legal_move(move).
  • Generate all legal moves or captures for a board by iterating over board.generate_legal_moves() and board.generate_legal_captures().
    • The generator remembers state; make sure to reset it with board.reset_move_generator() if you want to iterate over the moves again.
  • Generate the next move for the generator with board.generate_next_move().
  • Generate moves for a specific bitboard mask by setting it with board.set_move_generator_mask(mask_bitboard) and then calling board.generate_moves().
  • Apply a move to a board with board.make_move(move, check_legality=[True]|False).
    • check_legality defaults to True (can disable if you already know the move is legal for an extra performance boost).
  • Apply a move to a new board with new_board = board.make_move_new(move).
  • Check what piece, piece type, or color is on a square with the corresponding get_piece_on, get_piece_type_on, and get_color_on functions.
  • Get the BoardStatus enum of a board with board.get_status().
    • Can also call individual status check functions like board.is_checkmate(), board.is_insufficient_material(), board.is_fifty_moves(), and more.

Installation

Requires Python 3.10+.

A pip package is available at: (https://pypi.org/project/rust-chess)[https://pypi.org/project/rust-chess]

  1. Set up a virtual environment:
python -m venv .venv
source .venv/bin/activate
# Or
uv venv
source .venv/bin/activate
  1. Use the pip package:
pip install rust-chess
# Or
uv pip install rust-chess

Building From Source

  1. Set up a virtual environment:
python -m venv .venv
source .venv/bin/activate
# Or
uv venv
source .venv/bin/activate
  1. Clone the repository:
git clone https://github.com/nemeott/rust-chess.git
cd rust-chess
  1. Build and install the Python package:
./build.sh
pip install target/wheels/rust_chess-0.3.2-cp313-cp313-linux_x86_64.whl
# Or
uv pip install target/wheels/rust_chess-0.3.2-cp313-cp313-linux_x86_64.whl

# Or build and install in current virtual environment
./develop.sh

Roadmap

  • Color
    • Color constants
    • Comparison between colors and booleans
  • PieceType
    • Piece type constants
    • Get internal index representation
    • Printing
      • Basic characters
      • Unicode characters
  • Piece
    • Piece constants
    • Get internal piece type index representation
    • Printing
      • Basic characters
      • Unicode characters
  • Square
    • Square constants
    • Square creation and parsing
    • Get the rank and file from a square
    • Create a square from rank, file, or vice versa
    • Get the color of a square
    • Get the index of square
    • Use a square as an index
    • Rich comparison operators
    • Flip a square vertically
    • Bitboard conversion
    • Get adjacent squares
    • Get square forward/backward depending on color
    • Printing
  • Bitboard
    • File and rank constants
    • Creation from a square or integer
    • Bitboard operations
      • Between bitboards
      • Between a bitboard and integer
    • Count the number of bits
    • Flip vertically
    • Iterate over the squares in a bitboard
    • Printing
      • Flip printing direction by default?
  • Move
    • Move creation from data types or UCI
    • Castling move constants
    • Null move constant?
  • MoveGenerator
    • Generate the next move*, legal move, and legal capture
    • Generate moves, legal moves, and legal captures
    • Support iterating over the generator
    • Specify the generator mask (bitboard of squares the generator will generate for)
    • Remove a generator mask (bitboard of squares the generator will avoid)
    • Remove a move from the generator
    • Reset the generator
  • CastleRights
    • Get castle rights (No rights, queenside, kingside, both)
    • Set castle rights? (use cases?)
    • Rich comparison operators
  • BoardStatus
    • Game-ending conditions
      • Checkmate
      • Stalemate
      • Insufficient material
      • Fivefold repetition
    • Potential draw conditions
      • Threefold repetition
      • Fifty moves
    • Rich comparison operators
  • Board
    • FEN parsing and printing
    • SAN move parsing
    • Human readable printing
      • Basic characters
      • ASCII with colors?
      • Unicode characters
    • Get color, piece type, and piece on a square
    • Get king square for a color
    • Get the en passant square
    • Check if move is zeroing
    • Check if move is legal
    • Quick legality detection for psuedo-legal moves
    • Check if move is a capture
    • Check if move is en passant
    • Make moves on the current or new board
      • Make null moves (make_null_move)
      • Make null moves on new board
    • Get bitboards
      • Pinned pieces
      • Checking pieces
      • Color pieces
      • Piece type
      • Piece
      • All pieces
    • Zobrist hashing
    • Comparison operators (using Zobrist hash)
    • Move history
      • Repetition detection
    • Cache default board for faster creation?
    • Piece-Square Table support?
  • Miscellaneous
    • PGN support (parsing and writing)
    • UCI protocol basics
    • Opening book support
    • Improved Python ergonomics (e.g., more Pythonic wrappers where appropriate)
    • Comprehensive test suite
      • Docstring tests
      • Other tests
    • Working GitHub action (😢)

Comparison with python-chess

python-chess generates moves in reverse order (H8, H7, ...)* rust-chess generates moves in normal order (A1, A2, ...).

Performance

compare.py was used for a quick benchmark and comparison between the same operations for rust-chess and python-chess. The comparison script was run with large iteration counts (n = 100,000) and profiled using PySpy. The key observations from that analysis are as follows:

  • Small/simple operations (e.g., some tiny getters, Python-exposed primitives) can be slightly slower because of Rust<->Python boundary costs.
  • Complex and heavy operations are substantially faster in rust-chess:
    • Creating moves from UCI.
    • Board initialization.
    • FEN parsing and printing.
    • Generating legal moves and legal captures.
    • Checking move legality and check.

More detailed analysis is documented inside the file, including time deltas per function.

Notable Limitations

  • Bridge overhead: Small functions and data types are slower due to the bridge overhead, however heavy computations are much faster.
  • No board history yet: Undo/pop are not available currently. Make moves onto a new board and pass it into a function instead for now.
  • Reliability: The library has not been widely tested yet. It has somewhat detailed docstring tests but not every edge case is guaranteed to be covered.

License

MIT License.

About

Python wrapper of the Rust chess crate.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages