Crate chessie

Source
Expand description

§Chessie

A fast Chess / Chess960 library, suitable for use in chess engines.

§Overview

This library provides a clean, easy-to-use API for creating and working with chess games. It supports Forsyth-Edwards Notation (FEN) strings for creating positions, as well as Universal Chess Interface (UCI) notation for pieces, squares, moves, and more.

One minor goal of mine for this project was to include documentation tests for every function. As a result, nearly every function in this library has examples of how to use them that double as unit tests.

§Examples

Simple performance test (perft):

use chessie::Game;

fn perft(game: &Game, depth: usize) -> u64 {
    // Recursion limit; return 1, since we're fathoming this node.
    if depth == 0 {
        return 1;
    }

    // Recursively accumulate the nodes from the remaining depths
    game.get_legal_moves().into_iter().fold(0, |nodes, mv| {
        nodes + perft(&game.with_move_made(mv), depth - 1)
    })
}

let game = Game::default(); // Default starting position
let nodes = perft(&game, 2);
assert_eq!(nodes, 400);
  • Note: This library has a perft function included.

Only generate moves from specific squares (Knights, in this case):

use chessie::{Game, Color};
let game = Game::default(); // Default starting position
let mask = game.knights(Color::White);
for mv in game.get_legal_moves_from(mask) {
    print!("{mv} ");
}
// b1a3 b1c3 g1f3 g1h3

Only generate moves that capture enemy pieces (en passant excluded):

use chessie::Game;
let game = Game::from_fen("r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq - 0 1").unwrap();
for mv in game.into_iter().only_captures() {
    print!("{mv} ");
}
// e2a6 g2h3 f3h3 f3f6 d5e6 e5g6 e5d7 e5f7

More examples can be found in the examples/ directory.

§Features

Several state-of-the-art chess programming ideas have been incorporated into this library, as well as several Rust-specific paradigms.

§Current

  • User-friendly, heavily-documented, easy-to-read, safe API.
  • (Almost) every function has examples in its documentation.
  • Ability to create, modify, and read chess positions.
  • Compact representation of primitive types such as squares (8 bits) and moves (16 bits).
  • Incremental move generation API through Rust’s Iterator trait, and allow generation of moves to/from specific squares (such as only generating moves for pawns, or only generating captures).
  • Bulk move generation using some faster techniques than iterators, as well.
  • Bitboards for piece layout and move generation.
  • Magic Bitboards for sliding piece move generation.
  • And many more that I may have neglected to mention
  • Chess960 (and Double Chess960) support, with utility functions for converting to/from standard/Chess960 notation for castling rights, FEN strings, and castling moves.

§Future

§Acknowledgements:

Special thanks in particular to:

§Changelog

  • 2.0.0:
    • Breaking:
      • Refactored CastlingRights to store a Square instead of a File.
      • Removed print_perft in favor of the following functions: perft, splitperft, perft_generic.
    • Added support for Chess960 (Fischer Random) and Double Chess960 (Double Fischer Random).
      • Internally changed the representation of Castling moves to “King takes Rook” to support Chess960.
      • Added utilities for converting to/from Chess960 and standard castling moves.
      • All Display implementations now utilize the alternate formatter (#) to print either standard or Chess960 notation for FEN strings, castling rights, and castling moves (Thanks to cozy_chess for this idea).
    • Made modules private so their re-exports don’t clutter up the docs.
    • Added a Display implementation for MoveKind.
    • Improved movegen efficiency a bit.
    • Added Game::attacks_by_color to quickly access attack/defend maps.
    • Updated examples/:
      • Removed splitperft.rs, as it was redundant.
      • Changed perft.rs to use clap and be overall cleaner.
  • 1.2.1:
    • Fixed major bug causing Zobrist keys to not update properly when making moves on positions (thanks @Serdra on the EP discord).
  • 1.2.0:
    • Added Position::can_draw_by_insufficient_material.
    • Fixed bug causing Square::is_light to return the opposite bool.
  • 1.1.0:
    • Fixed bug causing illegal positions to crash move generator
    • Implemented FromIterator<Square> for Bitboard.
    • Added function for playing null moves, and adjusted how Game is printed.
  • 1.0.0:
    • Massive performance increase (over 200%) in move generation (benchmarks).
    • Game::get_legal_moves now computes legal moves in bulk rather than relying on MoveGenIter::collect.
    • Some breaking changes with method names in Bitboard and other primitives.
    • General code cleanup (more docs, more tests, etc.).
    • Added examples/ and benches.
    • Moved prng.rs into chessie-types so it can be used for magic generation, removing our dependency on rand.
    • Added #[inline(always)] to a lot of functions/methods. Seems to have improved efficiency.
    • Modified CastlingRights and it’s storage in Position. Should make Chess960 integration easier later.
  • 0.1.0:
    • Initial release

Modules§

prelude
Re-exports all the things you’ll need.

Structs§

Bitboard
A Bitboard represents the game board as a set of bits. They are used for various computations, such as fetching valid moves or computing move costs.
BitboardIter
An iterator over all set bits in a Bitboard.
BitboardSubsetIter
An iterator over all possible subsets of a Bitboard.
Board
Represents all pieces and their locations on a chess board.
BoardIter
An iterator over a set of squares on a Board.
CastlingRights
Represents the castling rights of a single player
File
Represents one of eight ranks on a chess board.
Game
A game of chess.
Move
Represents a move made on a chess board, including whether a piece is to be promoted.
MoveGenIter
An iterator over all legal moves in a specific position.
Piece
Represents a chess piece on the game board.
Position
Represents the current state of the game, including move counters.
Rank
Represents one of eight ranks on a chess board.
Square
Represents a single square on an 8x8 chess board.
XoShiRo
A pseudo-random number generator using the “xoshiro” algorithm.
ZobristKey
Represents a key generated from a Zobrist Hash

Enums§

Color
Represents the color of a player, piece, square, etc. within a chess board.
MoveKind
Represents the different kinds of moves that can be made during a chess game.
PieceKind
Represents the kind (or “role”) that a chess piece can be.

Constants§

BISHOP_DELTAS
Deltas for the movement of the Bishop.
FEN_KIWIPETE
A popular FEN string for debugging move generation.
FEN_STARTPOS
FEN string for the starting position of chess.
KNIGHT_DELTAS
Deltas for the movement of the Knight.
MAX_NUM_MOVES
Maximum possible number of moves in a given chess position.
NUM_CASTLING_RIGHTS
Number of possible combinations of castling rights.
QUEEN_DELTAS
Deltas for the movement of the Queen.
ROOK_DELTAS
Deltas for the movement of the Rook.

Functions§

attacks_for
Fetch the default, pseudo-legal attacks for piece at square, given blockers.
bishop_attacks
Computes the possible moves for a Bishop at a given Square with the provided blockers.
bishop_rays
Computes the (unblocked) moves for a Bishop at a given Square.
compute_attackers_to
Computes a Bitboard of all the color pieces that attack square.
compute_attacks_by
Computes a Bitboard of all squares attacked by color.
compute_checkers_and_pinmask
compute_checkmask
Computes a checkmask for the current board state.
compute_pinmask_for
Computes a pinmask of the board, centered on square.
generate_magics
Generate magics for the Bishop and Rook and store them in <outdir>/rook_magics.rs and <outdir>/bishop_magics.rs.
generate_piece_attack_datfiles
Generates the default mobility for each of the pieces of standard chess, and writes the mobility to new files created in outdir.
generate_ray_table_datfiles
Generates .dat files for ray tables.
king_attacks
Fetch the raw, unblocked attacks for a king on the provided square.
knight_attacks
Fetch the raw, unblocked attacks for a knight on the provided square.
pawn_attack_map
Computes a Bitboard of all squares attacked by color Pawns, excluding En Passant for convenience.
pawn_attacks
Fetch the raw, unblocked attacks for a pawn of the provided color on the provided square.
pawn_moves
Computes a Bitboard for the attacks and pushes of a Pawn at square.
pawn_pushes
Fetch the raw, unblocked pushes for a pawn of the provided color on the provided square.
perft
Perform a perft at the specified depth, collecting only data about the number of possible positions (nodes).
perft_generic
Generic version of perft that allows you to specify whether to perform bulk counting and splitperft.
queen_attacks
Computes the possible moves for a Queen at a given Square with the provided blockers.
ray_between
Fetches a Bitboard with all of the bits along the ray between from and to (exclusive) set to 1.
ray_containing
Fetches a Bitboard with all of the bits along the ray containing from and to set to 1.
rook_attacks
Computes the possible moves for a Rook at a given Square with the provided blockers.
rook_rays
Computes the (unblocked) moves for a Rook at a given Square.
splitperft
Perform a splitperft at the specified depth, collecting only data about the number of possible positions (nodes), and printing the number of nodes reachable after each move available at the root node.

Type Aliases§

MoveList
An alias for an arrayvec::ArrayVec containing at most MAX_NUM_MOVES moves.