From fdb714aad16a25cd68121bab6023c910c70c7f69 Mon Sep 17 00:00:00 2001 From: Bruno Mendes Date: Mon, 13 May 2024 00:14:03 +0100 Subject: [PATCH 1/4] Quickly check for check in pseudo legality test --- src/moves/mod.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/moves/mod.rs b/src/moves/mod.rs index 75d66e55..6b492b73 100644 --- a/src/moves/mod.rs +++ b/src/moves/mod.rs @@ -1,6 +1,6 @@ use self::{ attacks::specials::pawn_attacks, - gen::{piece_attacks, MoveDirection}, + gen::{piece_attacks, square_attackers, MoveDirection}, }; use crate::position::{ bitboard::Bitboard, board::Piece, square::Square, CastlingRights, Color, Position, @@ -130,6 +130,18 @@ impl Move { return false; } + // Basic check test for king moves. + if piece == Piece::King + && square_attackers::( + &position.board, + self.to(), + position.side_to_move.opposite(), + ) + .is_not_empty() + { + return false; + } + match self.flag() { MoveFlag::Quiet if piece == Piece::Pawn => { to_color.is_none() && self.to().file() == self.from().file() From 525a57739ba51ddbc0698446cc4a7a93490496dc Mon Sep 17 00:00:00 2001 From: Bruno Mendes Date: Mon, 13 May 2024 14:58:46 +0100 Subject: [PATCH 2/4] Use hash upper bits --- src/search/table.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/search/table.rs b/src/search/table.rs index 8b22c6c5..72d4eacb 100644 --- a/src/search/table.rs +++ b/src/search/table.rs @@ -49,7 +49,7 @@ impl TableEntry { data: (score_type as u32) | ((depth as u32 & 0x3F) << 2) | ((age as u32) << 8) - | ((hash as u32) << 9), + | (hash as u32 & 0xFFFF_FE00), } } @@ -79,8 +79,7 @@ impl TableEntry { } fn same_hash(&self, hash: u64) -> bool { - // We store 23 bits of the hash, so we need to compare the first 23 bits. - (self.data >> 9) == (hash as u32 & 0x7F_FFFF) + self.data & 0xFFFF_FE00 == (hash as u32 & 0xFFFF_FE00) } fn age(&self) -> bool { From 03245264a129c82f9d4214eec2638d9943cd853d Mon Sep 17 00:00:00 2001 From: Bruno Mendes Date: Mon, 13 May 2024 15:30:02 +0100 Subject: [PATCH 3/4] Add SEE bench --- Cargo.toml | 4 ++++ benches/see.rs | 33 +++++++++++++++++++++++++++++++++ src/search/see.rs | 8 ++++---- 3 files changed, 41 insertions(+), 4 deletions(-) create mode 100644 benches/see.rs diff --git a/Cargo.toml b/Cargo.toml index a5600e07..ed1b5886 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,3 +30,7 @@ harness = false [[bench]] name = "eval" harness = false + +[[bench]] +name = "see" +harness = false \ No newline at end of file diff --git a/benches/see.rs b/benches/see.rs new file mode 100644 index 00000000..d3417077 --- /dev/null +++ b/benches/see.rs @@ -0,0 +1,33 @@ +use camel::{ + moves::gen::MoveStage, + position::{fen::FromFen, Position}, + search::see, +}; +use criterion::{criterion_group, criterion_main, Criterion}; + +fn see_1(c: &mut Criterion) { + let position = + Position::from_fen("rnbqkb1r/1p1p1ppp/p3pn2/8/2PNP3/8/PP3PPP/RNBQKB1R w KQkq - 1 6") + .unwrap(); + let moves = position.moves(MoveStage::All); + let mov = moves.iter().find(|mov| mov.to_string() == "d4e6").unwrap(); + + c.bench_function("see_1", |b| { + b.iter(|| see::see::(*mov, &position.board)); + }); +} + +fn see_2(c: &mut Criterion) { + let position = + Position::from_fen("rnbqkb1r/1p1p1ppp/p3p3/8/2PNn3/2N5/PP3PPP/R1BQKB1R w KQkq - 0 7") + .unwrap(); + let moves = position.moves(MoveStage::All); + let mov = moves.iter().find(|mov| mov.to_string() == "c3e4").unwrap(); + + c.bench_function("see_2", |b| { + b.iter(|| see::see::(*mov, &position.board)); + }); +} + +criterion_group!(see, see_1, see_2,); +criterion_main!(see); diff --git a/src/search/see.rs b/src/search/see.rs index 76747d80..59c37cdd 100644 --- a/src/search/see.rs +++ b/src/search/see.rs @@ -25,9 +25,9 @@ pub fn see(mov: Move, board: &Board) -> ValueScore { } // We need an auxiliary board to perform the search. - // We also store the max score when it is our turn. + // We also store a standing pat when it is our turn to move. let mut board = *board; - let mut max_score = ValueScore::MIN; + let mut stand_pat = ValueScore::MIN; // Make our move. let mut on_square = piece; @@ -41,7 +41,7 @@ pub fn see(mov: Move, board: &Board) -> ValueScore { if RETURN_EARLY && score >= 0 { return score; } - max_score = max_score.max(score); + stand_pat = stand_pat.max(score); } else if RETURN_EARLY && score < 0 { return score; } @@ -66,7 +66,7 @@ pub fn see(mov: Move, board: &Board) -> ValueScore { } } - max_score.max(score) + stand_pat.max(score) } #[cfg(test)] From 2ee1c6b33df58b47f55a9166eb57734bb8371504 Mon Sep 17 00:00:00 2001 From: Bruno Mendes Date: Mon, 13 May 2024 15:45:04 +0100 Subject: [PATCH 4/4] Bump version to 1.5.2 --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/search/constraint.rs | 14 ++++++-------- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 150313be..a7e4ee7f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -43,7 +43,7 @@ checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" [[package]] name = "camel" -version = "1.5.1" +version = "1.5.2" dependencies = [ "bitflags", "criterion", diff --git a/Cargo.toml b/Cargo.toml index ed1b5886..84522be9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "camel" -version = "1.5.1" +version = "1.5.2" edition = "2021" [dependencies] diff --git a/src/search/constraint.rs b/src/search/constraint.rs index 997ee03b..845e3ca3 100644 --- a/src/search/constraint.rs +++ b/src/search/constraint.rs @@ -25,13 +25,11 @@ pub struct SearchConstraint { impl SearchConstraint { pub fn should_stop_search(&self) -> bool { - if self.threads_stop.load(std::sync::atomic::Ordering::Acquire) - || self.global_stop.load(std::sync::atomic::Ordering::Acquire) - { + if self.threads_stop.load(Ordering::Acquire) || self.global_stop.load(Ordering::Acquire) { return true; } - if self.ponder_mode.load(std::sync::atomic::Ordering::Acquire) { + if self.ponder_mode.load(Ordering::Acquire) { return false; } @@ -44,7 +42,7 @@ impl SearchConstraint { } pub fn pondering(&self) -> bool { - self.ponder_mode.load(std::sync::atomic::Ordering::Acquire) + self.ponder_mode.load(Ordering::Acquire) } pub fn remaining_time(&self) -> Option { @@ -64,7 +62,7 @@ mod tests { use crate::search::constraint::TimeConstraint; use std::{ sync::{ - atomic::{AtomicBool, AtomicU16}, + atomic::{AtomicBool, AtomicU16, Ordering}, Arc, }, thread, @@ -98,7 +96,7 @@ mod tests { #[test] fn stop_search_external_order() { - let stop_now = std::sync::Arc::new(std::sync::atomic::AtomicBool::new(false)); + let stop_now = std::sync::Arc::new(AtomicBool::new(false)); let constraint = SearchConstraint { time_constraint: Some(TimeConstraint { initial_instant: Instant::now(), @@ -113,7 +111,7 @@ mod tests { assert!(!constraint.should_stop_search()); - stop_now.store(true, std::sync::atomic::Ordering::Release); + stop_now.store(true, Ordering::Release); assert!(constraint.should_stop_search()); assert!(constraint.remaining_time().unwrap() > Duration::from_millis(90));