Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
94 commits
Select commit Hold shift + click to select a range
e2b594e
Fix typo
Orkking2 Mar 3, 2025
cee7713
remove unnessesary conversion
Orkking2 Mar 3, 2025
7ea5647
Removed duplicate code (functions are inlined anyway)
Orkking2 Mar 3, 2025
8293deb
Build error for the first example in README.md (Issue #50)
Orkking2 Mar 3, 2025
7d28468
Added en_passant_target which produces the target of the En Passant m…
Orkking2 Mar 3, 2025
3ffaa92
Errors made more verbose
Orkking2 Mar 3, 2025
6e30c87
Silly :{
Orkking2 Mar 3, 2025
f481efb
Added en_passant_target to produce the square which can be targetted …
Orkking2 Mar 3, 2025
3af9197
removed unused std::mem import
Orkking2 Mar 3, 2025
53c8292
Inline is ignored on function prototypes
Orkking2 Mar 3, 2025
66f3465
Turned magic numbers into const usize for Rook and Bishop indexing (t…
Orkking2 Mar 4, 2025
025b017
rename
Orkking2 Mar 7, 2025
86c748d
compiler suggestion
Orkking2 Mar 7, 2025
927a64c
Make white explicitly zero and black explicitly one
Orkking2 Mar 7, 2025
baa173c
make comments on CASTLES_PER_SQUARE more verbose
Orkking2 Mar 7, 2025
b0f5351
Add more comments for Caslte rights logic
Orkking2 Mar 7, 2025
ce652a2
slight change in comments
Orkking2 Mar 7, 2025
90a5fda
Add From<Color> for bool
Orkking2 Mar 7, 2025
be989ee
inline fn from: Color -> bool
Orkking2 Mar 7, 2025
a01b08b
Horrible suggestive comment
Orkking2 Mar 7, 2025
a2754c0
CastleRights variant clarity
Orkking2 Mar 9, 2025
912a2b6
refactor unmoved_rooks
Orkking2 Mar 9, 2025
b4ea574
comment
Orkking2 Mar 9, 2025
04d7d51
comment
Orkking2 Mar 9, 2025
049186f
Changed From<Color> to From<&Color>
Orkking2 Mar 9, 2025
5336474
Shorthand struct initialization
Orkking2 Mar 9, 2025
0f7d2de
Make deprication notes clearer
Orkking2 Mar 9, 2025
85f18fc
Why is BoardStatus Ordered this doesnt make sense, status stalemate a…
Orkking2 Mar 9, 2025
f9ac1e9
Comment
Orkking2 Mar 10, 2025
3535f28
Comment
Orkking2 Mar 10, 2025
33feabb
Todos
Orkking2 Mar 10, 2025
e642642
en_passant and en_passant_target should not consume self
Orkking2 Mar 10, 2025
5720184
Remove repetitive code
Orkking2 Mar 10, 2025
be0db0c
Refactor piece_on to piece_on and piece_on_unchecked
Orkking2 Mar 10, 2025
bca631f
doctest for piece_on_unchecked
Orkking2 Mar 10, 2025
a9da3b6
Doctest for Board::color_on
Orkking2 Mar 10, 2025
289aaea
Remove repetitive code
Orkking2 Mar 10, 2025
6257f09
Large functions should not be inlined
Orkking2 Mar 10, 2025
d8a6e91
comment
Orkking2 Mar 10, 2025
eb305b5
renamed variable for increased clarity
Orkking2 Mar 10, 2025
9500b64
Larget functions should not be inline(always)
Orkking2 Mar 10, 2025
619168a
comment
Orkking2 Mar 10, 2025
09ccca1
Refactor repetitive code
Orkking2 Mar 10, 2025
5e54460
Add nostd support
Orkking2 Mar 11, 2025
6cbd823
Remove Fail dependency (unmaintained crate)
Orkking2 Mar 11, 2025
18e4f90
Updating to modern rust
Orkking2 Mar 12, 2025
ee32e2c
bug fix
Orkking2 Mar 12, 2025
01ca8c4
Add serde feature flag which allows serialization using Serde
Orkking2 Mar 12, 2025
89c26ab
allow static_mut_refs
Orkking2 Mar 12, 2025
ca8972d
Make tests that requier feature "std" only available when cfg(feature…
Orkking2 Mar 12, 2025
492bd99
Fix comment
Orkking2 Mar 13, 2025
8c6c9b7
remove nodrop
Orkking2 Mar 13, 2025
55d7ffe
spelling correction
Orkking2 Mar 13, 2025
43c0c9a
make static deterministic functions
Orkking2 Mar 13, 2025
74d91b9
Refactor InCheckType into a const IN_CHECK bool & add a has_legals fu…
Orkking2 Mar 13, 2025
05fc742
update doctests and add make_move_mutref wrapper function
Orkking2 Mar 14, 2025
8ff7f0a
Revert toml
Orkking2 Mar 14, 2025
7e23773
Refactor `Board::STARTPOS` into static `crate::STARTPOS` and remove `…
Orkking2 Mar 14, 2025
9a4139f
inline `Board::new`
Orkking2 Mar 14, 2025
0b80189
`Board::make_moves` and `Board::make_moves_new`
Orkking2 Mar 14, 2025
b3d58f0
Make use of the `Self` keyword
Orkking2 Mar 14, 2025
f8f4fce
remove unnessecary `core::` specifier
Orkking2 Mar 14, 2025
8be3c20
update liscense
Orkking2 Mar 14, 2025
a6c9ead
remove unnecessary convertion
Orkking2 Mar 14, 2025
4090957
remove more unnecessary convertions
Orkking2 Mar 14, 2025
9bb751d
make startpos public
Orkking2 Mar 15, 2025
013bea0
doctest for `STARTPOS`
Orkking2 Mar 15, 2025
7dc6e44
Change doctests for `(my|their)_castle_rights` to increase clarity an…
Orkking2 Mar 16, 2025
ef85cdc
Make use of `make_moves_new` in doctests along with noting that `vec!…
Orkking2 Mar 16, 2025
0537382
`piece_on_unchecked` should not make guarantees about what type is re…
Orkking2 Mar 16, 2025
f2258d3
significantly improve the efficiency of `get_pawn_hash`
Orkking2 Mar 16, 2025
b8dc596
Remove serde as default feature
Orkking2 Mar 16, 2025
401ff02
toml revert pt 2
Orkking2 Mar 16, 2025
927e48a
Make use of `(my|their)_castle_rights`
Orkking2 Mar 16, 2025
081dd66
Add `get_pawn_king_hash` which depends on `get_pawn_hash` and king po…
Orkking2 Mar 16, 2025
d7e5c36
refactor `Board::pieces(piece) & Board::color_combined(color)` into `…
Orkking2 Mar 16, 2025
809c0a0
type
Orkking2 Mar 16, 2025
d1adddc
remove redundant parenthesis
Orkking2 Mar 16, 2025
26d3d15
change `match` to `if let Some`
Orkking2 Mar 16, 2025
9deb3dc
rewrite doctests
Orkking2 Mar 16, 2025
e6c83dd
write -> writeln
Orkking2 Mar 16, 2025
0c321c8
remove dead `#[allow(dead_code)]`
Orkking2 Mar 16, 2025
17af896
Add `#[allow(deprecated)]` to deprecated functions' doctests
Orkking2 Mar 16, 2025
2903c1e
Revert lib.rs
Orkking2 Mar 18, 2025
704b487
`#[inline(always)]` every `#[inline]` function under 5 lines
Orkking2 Mar 20, 2025
b1aedb2
`#[inline(always)]` legals and has_legals
Orkking2 Mar 20, 2025
e62c2fb
Fix no_std bug
Orkking2 Mar 20, 2025
6c86d80
Make `default` consistent with `STARTPOS` and reformat
Orkking2 Mar 20, 2025
da4b47b
formatting
Orkking2 Mar 20, 2025
1ad0880
comment + inline + using rust iterator syntax
Orkking2 Mar 23, 2025
ab3fb16
inline -> inline(always)
Orkking2 Mar 23, 2025
74fc83f
ordering
Orkking2 Mar 23, 2025
07a22fc
Note which static references are mutated in which function call
Orkking2 Mar 23, 2025
80e73cd
Remove empty `construct.rs`
Orkking2 Mar 23, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 13 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "chess"
version = "3.2.0"
edition = "2018"
version = "4.0.0"
edition = "2021"
authors = ["Jordan Bray <[email protected]>"]
description = "This is a fast chess move generator. It has a very good set of documentation, so you should take advantage of that. It (now) generates all lookup tables with a build.rs file, which means that very little pseudo-legal move generation requires branching. There are some convenience functions that are exposed to, for example, find all the squares between two squares. This uses a copy-on-make style structure, and the Board structure is as slimmed down as possible to reduce the cost of copying the board. There are places to improve perft-test performance further, but I instead opt to be more feature-complete to make it useful in real applications. For example, I generate both a hash of the board and a pawn-hash of the board for use in evaluation lookup tables (using Zobrist hashing). There are two ways to generate moves, one is faster, the other has more features that will be useful if making a chess engine. See the documentation for more details."
build = "src/build.rs"
Expand All @@ -12,15 +12,16 @@ readme = "README.md"
keywords = ["chess", "move", "generator"]
license = "MIT"
documentation = "https://jordanbray.github.io/chess/chess/index.html"
rust-version = "1.56.0"

[dependencies]
arrayvec = "0.7.2"
nodrop = "0.1.14"
failure = "0.1.6"
arrayvec = { version = "0.7.2", default-features = false }
serde = { version = "1.0.219", default-features = false, optional = true, features = ["derive"] }

[profile.release]
opt-level = 3
debug = false
lto = true

[profile.dev]
opt-level = 3
Expand All @@ -38,5 +39,10 @@ opt-level = 3
opt-level = 3

[build-dependencies]
rand = { version = "0.7.2", default_features = false, features = ["small_rng"] }
failure = "0.1.6"
rand = { version = "0.7.2", default-features = false, features = ["small_rng"] }
serde = { version = "1.0.219", default-features = false, optional = true, features = ["derive"] }

[features]
default = ["std"]
std = ["arrayvec/std", "serde/std"]
serde = ["dep:serde", "arrayvec/serde"]
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License

Copyright (c) 2010-2016 Jordan Bray
Copyright (c) 2010-2025 Jordan Bray

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ Here we iterate over all moves with incremental move generation. The iterator b

// lets iterate over targets.
let targets = board.color_combined(!board.side_to_move());
iterable.set_iterator_mask(targets);
iterable.set_iterator_mask(*targets);

// count the number of targets
let mut count = 0;
Expand Down
98 changes: 51 additions & 47 deletions src/bitboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ use std::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, M
/// assert_eq!(count, 3);
/// ```
///
#[cfg_attr(feature="serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(PartialEq, Eq, PartialOrd, Clone, Copy, Debug, Default, Hash)]
pub struct BitBoard(pub u64);

Expand All @@ -41,7 +42,7 @@ pub const EMPTY: BitBoard = BitBoard(0);
impl BitAnd for BitBoard {
type Output = BitBoard;

#[inline]
#[inline(always)]
fn bitand(self, other: BitBoard) -> BitBoard {
BitBoard(self.0 & other.0)
}
Expand All @@ -50,7 +51,7 @@ impl BitAnd for BitBoard {
impl BitAnd for &BitBoard {
type Output = BitBoard;

#[inline]
#[inline(always)]
fn bitand(self, other: &BitBoard) -> BitBoard {
BitBoard(self.0 & other.0)
}
Expand All @@ -59,7 +60,7 @@ impl BitAnd for &BitBoard {
impl BitAnd<&BitBoard> for BitBoard {
type Output = BitBoard;

#[inline]
#[inline(always)]
fn bitand(self, other: &BitBoard) -> BitBoard {
BitBoard(self.0 & other.0)
}
Expand All @@ -68,7 +69,7 @@ impl BitAnd<&BitBoard> for BitBoard {
impl BitAnd<BitBoard> for &BitBoard {
type Output = BitBoard;

#[inline]
#[inline(always)]
fn bitand(self, other: BitBoard) -> BitBoard {
BitBoard(self.0 & other.0)
}
Expand All @@ -78,7 +79,7 @@ impl BitAnd<BitBoard> for &BitBoard {
impl BitOr for BitBoard {
type Output = BitBoard;

#[inline]
#[inline(always)]
fn bitor(self, other: BitBoard) -> BitBoard {
BitBoard(self.0 | other.0)
}
Expand All @@ -87,7 +88,7 @@ impl BitOr for BitBoard {
impl BitOr for &BitBoard {
type Output = BitBoard;

#[inline]
#[inline(always)]
fn bitor(self, other: &BitBoard) -> BitBoard {
BitBoard(self.0 | other.0)
}
Expand All @@ -96,7 +97,7 @@ impl BitOr for &BitBoard {
impl BitOr<&BitBoard> for BitBoard {
type Output = BitBoard;

#[inline]
#[inline(always)]
fn bitor(self, other: &BitBoard) -> BitBoard {
BitBoard(self.0 | other.0)
}
Expand All @@ -105,7 +106,7 @@ impl BitOr<&BitBoard> for BitBoard {
impl BitOr<BitBoard> for &BitBoard {
type Output = BitBoard;

#[inline]
#[inline(always)]
fn bitor(self, other: BitBoard) -> BitBoard {
BitBoard(self.0 | other.0)
}
Expand All @@ -116,7 +117,7 @@ impl BitOr<BitBoard> for &BitBoard {
impl BitXor for BitBoard {
type Output = BitBoard;

#[inline]
#[inline(always)]
fn bitxor(self, other: BitBoard) -> BitBoard {
BitBoard(self.0 ^ other.0)
}
Expand All @@ -125,7 +126,7 @@ impl BitXor for BitBoard {
impl BitXor for &BitBoard {
type Output = BitBoard;

#[inline]
#[inline(always)]
fn bitxor(self, other: &BitBoard) -> BitBoard {
BitBoard(self.0 ^ other.0)
}
Expand All @@ -134,7 +135,7 @@ impl BitXor for &BitBoard {
impl BitXor<&BitBoard> for BitBoard {
type Output = BitBoard;

#[inline]
#[inline(always)]
fn bitxor(self, other: &BitBoard) -> BitBoard {
BitBoard(self.0 ^ other.0)
}
Expand All @@ -143,7 +144,7 @@ impl BitXor<&BitBoard> for BitBoard {
impl BitXor<BitBoard> for &BitBoard {
type Output = BitBoard;

#[inline]
#[inline(always)]
fn bitxor(self, other: BitBoard) -> BitBoard {
BitBoard(self.0 ^ other.0)
}
Expand All @@ -152,44 +153,44 @@ impl BitXor<BitBoard> for &BitBoard {
// Impl BitAndAssign

impl BitAndAssign for BitBoard {
#[inline]
#[inline(always)]
fn bitand_assign(&mut self, other: BitBoard) {
self.0 &= other.0;
}
}

impl BitAndAssign<&BitBoard> for BitBoard {
#[inline]
#[inline(always)]
fn bitand_assign(&mut self, other: &BitBoard) {
self.0 &= other.0;
}
}

// Impl BitOrAssign
impl BitOrAssign for BitBoard {
#[inline]
#[inline(always)]
fn bitor_assign(&mut self, other: BitBoard) {
self.0 |= other.0;
}
}

impl BitOrAssign<&BitBoard> for BitBoard {
#[inline]
#[inline(always)]
fn bitor_assign(&mut self, other: &BitBoard) {
self.0 |= other.0;
}
}

// Impl BitXor Assign
impl BitXorAssign for BitBoard {
#[inline]
#[inline(always)]
fn bitxor_assign(&mut self, other: BitBoard) {
self.0 ^= other.0;
}
}

impl BitXorAssign<&BitBoard> for BitBoard {
#[inline]
#[inline(always)]
fn bitxor_assign(&mut self, other: &BitBoard) {
self.0 ^= other.0;
}
Expand All @@ -199,7 +200,7 @@ impl BitXorAssign<&BitBoard> for BitBoard {
impl Mul for BitBoard {
type Output = BitBoard;

#[inline]
#[inline(always)]
fn mul(self, other: BitBoard) -> BitBoard {
BitBoard(self.0.wrapping_mul(other.0))
}
Expand All @@ -208,7 +209,7 @@ impl Mul for BitBoard {
impl Mul for &BitBoard {
type Output = BitBoard;

#[inline]
#[inline(always)]
fn mul(self, other: &BitBoard) -> BitBoard {
BitBoard(self.0.wrapping_mul(other.0))
}
Expand All @@ -217,7 +218,7 @@ impl Mul for &BitBoard {
impl Mul<&BitBoard> for BitBoard {
type Output = BitBoard;

#[inline]
#[inline(always)]
fn mul(self, other: &BitBoard) -> BitBoard {
BitBoard(self.0.wrapping_mul(other.0))
}
Expand All @@ -226,7 +227,7 @@ impl Mul<&BitBoard> for BitBoard {
impl Mul<BitBoard> for &BitBoard {
type Output = BitBoard;

#[inline]
#[inline(always)]
fn mul(self, other: BitBoard) -> BitBoard {
BitBoard(self.0.wrapping_mul(other.0))
}
Expand All @@ -236,7 +237,7 @@ impl Mul<BitBoard> for &BitBoard {
impl Not for BitBoard {
type Output = BitBoard;

#[inline]
#[inline(always)]
fn not(self) -> BitBoard {
BitBoard(!self.0)
}
Expand All @@ -245,76 +246,79 @@ impl Not for BitBoard {
impl Not for &BitBoard {
type Output = BitBoard;

#[inline]
#[inline(always)]
fn not(self) -> BitBoard {
BitBoard(!self.0)
}
}

impl fmt::Display for BitBoard {
#[inline]
#[inline(always)]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut s: String = "".to_owned();
for x in 0..64 {
if self.0 & (1u64 << x) == (1u64 << x) {
s.push_str("X ");
write!(f, "X ")?;
} else {
s.push_str(". ");
write!(f, ". ")?;
}
if x % 8 == 7 {
s.push_str("\n");
write!(f, "\n")?;
}
}
write!(f, "{}", s)
Ok(())
}
}

impl BitBoard {
/// Construct a new bitboard from a u64
#[inline]
pub fn new(b: u64) -> BitBoard {
#[inline(always)]
pub const fn new(b: u64) -> BitBoard {
BitBoard(b)
}

/// Construct a new `BitBoard` with a particular `Square` set
#[inline]
pub fn set(rank: Rank, file: File) -> BitBoard {
#[inline(always)]
pub const fn set(rank: Rank, file: File) -> BitBoard {
BitBoard::from_square(Square::make_square(rank, file))
}

/// Construct a new `BitBoard` with a particular `Square` set
#[inline]
pub fn from_square(sq: Square) -> BitBoard {
#[inline(always)]
pub const fn from_square(sq: Square) -> BitBoard {
BitBoard(1u64 << sq.to_int())
}

/// Convert an `Option<Square>` to an `Option<BitBoard>`
#[inline]
#[inline(always)]
#[deprecated(
since = "4.0.0",
note = "Unnecessary shorthand for `square_option.map(BitBoard::from_square)`.",
)]
pub fn from_maybe_square(sq: Option<Square>) -> Option<BitBoard> {
sq.map(|s| BitBoard::from_square(s))
sq.map(BitBoard::from_square)
}

/// Convert a `BitBoard` to a `Square`. This grabs the least-significant `Square`
#[inline]
pub fn to_square(&self) -> Square {
#[inline(always)]
pub const fn to_square(&self) -> Square {
Square::new(self.0.trailing_zeros() as u8)
}

/// Count the number of `Squares` set in this `BitBoard`
#[inline]
pub fn popcnt(&self) -> u32 {
#[inline(always)]
pub const fn popcnt(&self) -> u32 {
self.0.count_ones()
}

/// Reverse this `BitBoard`. Look at it from the opponents perspective.
#[inline]
pub fn reverse_colors(&self) -> BitBoard {
#[inline(always)]
pub const fn reverse_colors(&self) -> BitBoard {
BitBoard(self.0.swap_bytes())
}

/// Convert this `BitBoard` to a `usize` (for table lookups)
#[inline]
pub fn to_size(&self, rightshift: u8) -> usize {
#[inline(always)]
pub const fn to_size(&self, rightshift: u8) -> usize {
(self.0 >> rightshift) as usize
}
}
Expand All @@ -323,7 +327,7 @@ impl BitBoard {
impl Iterator for BitBoard {
type Item = Square;

#[inline]
#[inline(always)]
fn next(&mut self) -> Option<Square> {
if self.0 == 0 {
None
Expand Down
Loading