Crates.io | cozy-chess |
lib.rs | cozy-chess |
version | 0.3.4 |
source | src |
created_at | 2021-09-12 14:53:02.277963 |
updated_at | 2024-04-05 10:50:33.463469 |
description | Rust Chess and Chess960 move generation library |
homepage | https://github.com/analog-hors/cozy-chess/ |
repository | https://github.com/analog-hors/cozy-chess/ |
max_upload_size | |
id | 450119 |
size | 1,422,867 |
cozy-chess
cozy-chess
is a Chess and Chess960 (Fischer Random Chess) move generation library written in Rust that aims to provide competitive move generation performance. It is largely inspired by Jordan Bray's neat chess
library. cozy-chess
aims to be a safer alternative to chess
that maintains correctness while providing similar performance.
no_std
compatiblestd
: Enable features that require std
. Currently only used for the Error
trait.pext
: Enable PEXT bitboards.By default, Rust binaries target a baseline CPU to ensure maximum compatibility at the cost of performance. cozy-chess
benefits significantly from features present in modern CPUs. For maximum performance, the target CPU can instead be set to native
to use features supported by the machine running the build. Alternatively, the target CPU can be set to x86-64-v3
, which will produce binaries that run on most modern CPUs. The target CPU may be changed by adding -C target-cpu=<CPU>
to RUSTFLAGS
.
PEXT bitboards are a faster variant of the magic bitboard algorithm used by cozy-chess
. PEXT bitboards rely on an intrinsic introduced in the BMI2 CPU extension. However, it is not enabled by default, as PEXT bitboards are slower on AMD CPUs prior to Zen 3, which implement PEXT with microcode. PEXT bitboards can be enabled through the pext
feature.
In order to support Chess960, cozy-chess
uses a king-captures-rook castling notation incompatible with the standard castling representation used by the UCI protocol. This is a common use case, so the cozy_chess::util
module provides helpers that automatically parse and convert between the formats.
# use cozy_chess::*;
// Start position
let board = Board::default();
let mut move_list = Vec::new();
board.generate_moves(|moves| {
// Unpack dense move set into move list
move_list.extend(moves);
false
});
assert_eq!(move_list.len(), 20);
# use cozy_chess::*;
// Parse position from FEN
let board = "r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq - 0 1"
.parse::<Board>()
.unwrap();
let mut total_moves = 0;
let mut total_captures = 0;
let enemy_pieces = board.colors(!board.side_to_move());
board.generate_moves(|moves| {
let mut captures = moves.clone();
// Bitmask to efficiently get all captures set-wise.
// Excluding en passant square for convenience.
captures.to &= enemy_pieces;
total_moves += moves.len();
total_captures += captures.len();
false
});
assert_eq!(total_moves, 48);
assert_eq!(total_captures, 8);
A perft implementation exists in examples/perft.rs
:
$ cargo run --release --example perft -- 7
Compiling cozy-chess v0.3.0
Finished release [optimized] target(s) in 6.37s
Running `target\release\examples\perft.exe 7`
3195901860 nodes in 10.05s (318045465 nps)
Square::relative_to
to get a square relative to some color.Board
s.Board::is_legal
said castles while in check were legal.pext
feature.Board::hash_without_ep
method for fast equivalence checks excluding the en passant square.Board::same_position
to check if two boards are equivalent under FIDE rules.Board::colored_pieces
, a shorthand for board.colors(color) & board.pieces(piece)
.BitBoard::is_subset
, BitBoard::is_superset
, and BitBoard::is_disjoint
.BitBoard
s now operate in a more set-wise manner instead of acting like a u64
. Bit operators changed to match set operators.BitBoard::popcnt
renamed to BitBoard::len
for consistency with other data structures.BoardBuilder
's fullmove_number
field changed to a u16
for usability reasons.Board
's FromStr
implementation now parses both FEN and Shredder FEN.BitBoard
no longer implements Iterator
directly.const
by default; Use the const
variants if required.Board
removed; The risk of panicking is accepted when *_unchecked
methods are called.Square::try_offset
fixed.FenParseError
is no longer unnameable.