Skip to main content

A bridge between the Rust chess crate and Python.

Project description

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 tests/benchmark.py.

WARNING

This project is almost out of alpha/beta phase (pun intended). Maybe 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.
  • BoardBatch: 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.
  • Create a BoardBatch to apply functions to multiple boards at once.

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:
./scripts/build.sh
pip install target/wheels/rust_chess-0.4.0-cp313-cp313-linux_x86_64.whl
# Or
uv pip install target/wheels/rust_chess-0.4.0-cp313-cp313-linux_x86_64.whl

# Or build and install in current virtual environment
./scripts/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
    • Set a retain generator mask (bitboard of squares the generator will generate for)
    • Set an exclude 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 the color, piece type, and piece on a square
    • Get the king and en passant squares
    • Get castle rights
    • Check if move is zeroing or legal
    • Quick legality detection for psuedo-legal moves
    • Check if move is a capture or en passant or is castling
    • 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?
  • BoardBatch
    • Initialization
      • Create a batch of boards from a count
      • Create a batch of boards from a list of FEN strings.
      • Create a batch of boards from a list of boards.
    • FEN parsing and printing
    • SAN move parsing
    • Human readable printing
      • Basic characters
      • ASCII with colors?
      • Unicode characters
    • Get the color, piece type, and piece on a respective square
    • Get the king and en passant squares for each board
    • Get castle rights for each board
    • Check if a resepective move is zeroing or legal for each board
    • Quick legality detection for psuedo-legal moves
    • Check if a respective move is a capture or en passant or is castling for each board
    • Make moves on the current or new board batch
    • Make null moves (make_null_move)
    • Make null moves on new board batch
    • Get bitboards for the batch
      • Pinned pieces
      • Checking pieces
      • Color pieces
      • Piece type
      • Piece
      • All pieces
    • Zobrist hashing for each board
    • Comparison operators (using Zobrist hash)
    • Move history
      • Repetition detection for each board
    • Generate the next move, legal move, and legal capture for a batch
    • Generate moves, legal moves, and legal captures for a batch
    • Return a list of the generators
    • Set the retain generator masks
    • Set the exclude generator masks
    • Remove moves from the generators
    • Reset the generators
  • 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
      • Benchmark comparision to python-chess
      • Other tests
    • Multi-threading
    • Python thread support?
    • 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

scripts/benchmark.py was used as a comprehensive benchmark comparision between similar functions in rust-chess and python-chess. Benchmarked on my Chromebook (Intel i5-1135G7). scripts/batchmark.py was used for a comparison between using methods on batches of boards. python-chess doesn't have a batch board class so this is kind of an unfair comparison. However, board batches could be useful for analyzing multiple games at once. The results from rust-chess v0.4.0 are as follows:

Benchmark Results (n=100,000)

Category Rust Time Python Time Speedup
Colors 0.005623 0.004736 0.842337
Pieces 0.018838 0.009041 0.479946
Squares 0.089639 0.045636 0.509110
Moves 0.086117 0.217042 2.520321
Board Init 0.091657 5.062907 55.237283
Board Props 0.426570 11.517537 27.000372
Board Ops 0.100331 0.578784 5.768751
Board Ops 2 0.105453 5.327600 50.521126
Make Move 0.079674 0.555655 6.974129
Make Move (New) 0.090940 0.605637 6.659730
Undo Move 0.091185 0.481893 5.284780
Next Move 0.067739 0.459672 6.785930
Generate Moves 0.208179 10.695765 51.377735
SAN Parse 0.063843 0.651645 10.207014
King Square 0.044894 0.131626 2.931930
Zobrist Hash 0.045252 1.741447 38.483714
Checkmate 0.048705 0.206944 4.248894
Insufficient Mat. 0.040469 0.174750 4.318096
Bitboard Ops 0.036695 0.067098 1.828515
Board Bitboards 0.070030 0.136282 1.946055
Castle Rights 0.060880 0.333831 5.483449
Repetitions 0.046618 13.510689 289.813933
Board Status 0.049362 0.682978 13.836119
Square/Piece Adv. 0.033849 0.048523 1.433507
Null Move 0.047808 0.322804 6.752067
Total 2.050350 53.570522 26.127503

Benchmark Results (n=10,000), (batch_size=25)

Category Rust Time Python Time Speedup
Board Init 0.028494 0.028333 0.994337
Board Props 0.127417 3.670269 28.805164
Board Ops 0.084218 1.528579 18.150214
Board Ops 2 0.035208 1.710838 48.592270
Make Move 0.046525 1.126794 24.219008
Make Move (New) 0.046996 1.506249 32.050450
Undo Move 0.046307 1.155118 24.944634
Next Move 0.063420 1.172726 18.491501
Generate Moves 0.164534 13.247108 80.513124
SAN Parse 0.061047 1.690472 27.691106
King Square 0.019242 0.326893 16.988751
Zobrist Hash 0.017036 4.458977 261.736400
Checkmate 0.024211 0.517528 21.375914
Insufficient Mat. 0.014820 0.418335 28.226859
Board Bitboards 0.055708 0.339233 6.089521
Castle Rights 0.018760 0.851835 45.407465
Repetitions 0.015187 34.786077 2290.488025
Board Status 0.024841 1.692779 68.144579
Null Move 0.019370 0.787410 40.652059
Total 0.913341 71.015554 77.753579

Analysis

  • 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.
    • Getting piece bitboards.
    • Generating moves, legal moves, and legal captures.
    • Batch move generation (WIP).
    • San parsing.
    • Zobrist hashing.
    • Checking move legality and check.
    • Repetition detection.
    • Board status checks.

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 pretty detailed docstring tests but not every edge case is guaranteed to be covered.

License

MIT License.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rust_chess-0.4.0.tar.gz (86.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

rust_chess-0.4.0-cp313-cp313-manylinux_2_38_x86_64.whl (594.3 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.38+ x86-64

File details

Details for the file rust_chess-0.4.0.tar.gz.

File metadata

  • Download URL: rust_chess-0.4.0.tar.gz
  • Upload date:
  • Size: 86.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.12.6

File hashes

Hashes for rust_chess-0.4.0.tar.gz
Algorithm Hash digest
SHA256 7b052f1d86304b22335bac43bf7b617d64a4fb501e57a955965bd01f7240e89b
MD5 894143985179d2c16eebbfb44c36db03
BLAKE2b-256 a03c9d7e951f22b1fad963c00ad9c719f5b563195fef1fa778c9306348d7bb4b

See more details on using hashes here.

File details

Details for the file rust_chess-0.4.0-cp313-cp313-manylinux_2_38_x86_64.whl.

File metadata

File hashes

Hashes for rust_chess-0.4.0-cp313-cp313-manylinux_2_38_x86_64.whl
Algorithm Hash digest
SHA256 a7289f63d2eb1b529031f2ded5f7e839dcb7988ade8440607e4ac93949e46bcf
MD5 571b10e52a8538dfa54f3e1491a3908e
BLAKE2b-256 ab037132097160f56ca6bce7800780b44876ca645ff75dd9c67b0d8386f59976

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page