Crates.io | chessie |
lib.rs | chessie |
version | 2.0.0 |
source | src |
created_at | 2024-09-20 20:33:55.24057 |
updated_at | 2024-11-02 06:37:05.561084 |
description | Fast chess library, suitable for use in chess engines |
homepage | https://github.com/dannyhammer/chessie |
repository | https://github.com/dannyhammer/chessie |
max_upload_size | |
id | 1381768 |
size | 1,937,954 |
A fast Chess / Chess960 library, suitable for use in chess engines.
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.
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);
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.
Several state-of-the-art chess programming ideas have been incorporated into this library, as well as several Rust-specific paradigms.
Iterator
trait, and allow generation of moves to/from specific squares (such as only generating moves for pawns, or only generating captures).Special thanks in particular to:
2.0.0
:
CastlingRights
to store a Square
instead of a File
.print_perft
in favor of the following functions: perft
, splitperft
, perft_generic
.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).Display
implementation for MoveKind
.Game::attacks_by_color
to quickly access attack/defend maps.examples/
:
splitperft.rs
, as it was redundant.perft.rs
to use clap
and be overall cleaner.1.2.1
:
1.2.0
:
Position::can_draw_by_insufficient_material
.Square::is_light
to return the opposite bool.1.1.0
:
FromIterator<Square>
for Bitboard
.Game
is printed.1.0.0
:
Game::get_legal_moves
now computes legal moves in bulk rather than relying on MoveGenIter::collect
.Bitboard
and other primitives.examples/
and benches
.prng.rs
into chessie-types
so it can be used for magic generation, removing our dependency on rand
.#[inline(always)]
to a lot of functions/methods. Seems to have improved efficiency.CastlingRights
and it's storage in Position
. Should make Chess960 integration easier later.0.1.0
: