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
- Support for parsing/writing Extended Position Description (EPD).
- Support for parsing/writing Portable Game Notation (PGN).
- Support for parsing/writing Standard Algebraic Notation (SAN).
- Support for other variants, like Horde Chess.
- Proper support for un-making moves.
- General optimizations. See the “Issues” tab for more.
§Acknowledgements:
Special thanks in particular to:
- Sebastian Lague, for his chess programming series on YouTube that ultimate inspired me to do this project.
- The Chess Programming Wiki, and all those who contribute to free, open-source knowledge.
- The folks over at the Engine Programming Discord, for their patience with my silly questions and invaluable help overall.
- Analog-Hors, for an excellent article on magic bitboards
§Changelog
2.0.0
:- Breaking:
- Refactored
CastlingRights
to store aSquare
instead of aFile
. - Removed
print_perft
in favor of the following functions:perft
,splitperft
,perft_generic
.
- Refactored
- 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 tocozy_chess
for this idea).
- Made modules private so their re-exports don’t clutter up the docs.
- Added a
Display
implementation forMoveKind
. - 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 useclap
and be overall cleaner.
- Removed
- Breaking:
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.
- Added
1.1.0
:- Fixed bug causing illegal positions to crash move generator
- Implemented
FromIterator<Square>
forBitboard
. - 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 onMoveGenIter::collect
.- Some breaking changes with method names in
Bitboard
and other primitives. - General code cleanup (more docs, more tests, etc.).
- Added
examples/
andbenches
. - Moved
prng.rs
intochessie-types
so it can be used for magic generation, removing our dependency onrand
. - Added
#[inline(always)]
to a lot of functions/methods. Seems to have improved efficiency. - Modified
CastlingRights
and it’s storage inPosition
. 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. - Bitboard
Iter - An iterator over all set bits in a
Bitboard
. - Bitboard
Subset Iter - An iterator over all possible subsets of a
Bitboard
. - Board
- Represents all pieces and their locations on a chess board.
- Board
Iter - An iterator over a set of squares on a
Board
. - Castling
Rights - 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.
- Move
GenIter - 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.
- Zobrist
Key - Represents a key generated from a Zobrist Hash
Enums§
- Color
- Represents the color of a player, piece, square, etc. within a chess board.
- Move
Kind - Represents the different kinds of moves that can be made during a chess game.
- Piece
Kind - 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
atsquare
, givenblockers
. - 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 thecolor
pieces that attacksquare
. - compute_
attacks_ by - Computes a
Bitboard
of all squares attacked bycolor
. - 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 bycolor
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 atsquare
. - 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 betweenfrom
andto
(exclusive) set to1
. - ray_
containing - Fetches a
Bitboard
with all of the bits along the ray containingfrom
andto
set to1
. - 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§
- Move
List - An alias for an
arrayvec::ArrayVec
containing at mostMAX_NUM_MOVES
moves.