Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ smallvec = "1.13.2"
crossbeam-deque = "0.8.5"
lockfree = "0.5.1"
once_cell = "1.20.2"
colored = "2.1.0"
#jja = { version = "0.9.1", features = [] }

[dev-dependencies]
Expand All @@ -46,7 +47,7 @@ path = "src/benches/d6.rs"
harness = false

[[bench]]
name = "qs"
name = "qs" # quick search benches, fewer samples
path = "src/benches/quick_search.rs"
harness = false

Expand All @@ -70,4 +71,4 @@ path = "tests/d6.rs"

[[test]]
name = "mate"
path = "tests/mate.rs"
path = "tests/mate.rs"
31 changes: 31 additions & 0 deletions research/games/sandy_release_wins_with_no_tt.pgn
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
[Event "?"]
[Site "?"]
[Date "2024.11.12"]
[Round "?"]
[White "sandy"]
[Black "sandy_release"]
[Result "0-1"]
[ECO "A40"]
[GameDuration "00:02:56"]
[GameEndTime "2024-11-12T16:03:44.673 GMT+7"]
[GameStartTime "2024-11-12T16:00:48.226 GMT+7"]
[Opening "Queen's pawn"]
[PlyCount "44"]
[TimeControl "40/120+1"]

1. d4 {+0.23/4 4.0s} e6 {+0.50/5 4.0s} 2. Bf4 {-0.47/4 4.0s} Nc6 {+0.86/5 4.0s}
3. Be3 {-0.42/4 4.0s} Nf6 {+1.18/5 4.0s} 4. Nc3 {-1.31/4 4.0s}
Ng4 {+0.04/6 4.0s} 5. Bf4 {+0.11/5 4.0s} Nxf2 {+1.49/5 4.0s}
6. Kxf2 {+1.21/5 4.0s} Qh4+ {+0.21/5 4.0s} 7. g3 {+1.66/5 4.0s}
Qf6 {-0.63/6 4.0s} 8. Nb5 {+2.82/5 4.0s} e5 {-1.11/6 4.0s}
9. Nxc7+ {+1.03/6 4.0s} Kd8 {-0.03/7 4.0s} 10. Nxa8 {+2.37/5 4.0s}
exf4 {-0.16/6 4.0s} 11. Nf3 {+2.58/5 4.0s} Nxd4 {-0.05/6 4.0s}
12. Nxd4 {+0.66/6 4.0s} fxg3+ {+0.70/7 4.0s} 13. Kxg3 {+3.42/5 4.0s}
Qe5+ {+0.31/6 4.0s} 14. Kf3 {+0.55/5 4.0s} Qh5+ {+0.12/6 4.0s}
15. Kf2 {+3.76/5 4.0s} Qh4+ {+0.43/7 4.0s} 16. Ke3 {+0.63/6 4.0s}
Bc5 {+0.90/7 4.0s} 17. Kf3 {+2.76/5 4.0s} Bxd4 {+1.18/7 4.0s}
18. Nc7 {+0.12/5 4.0s} Qf2+ {+1.18/7 4.0s} 19. Ke4 {-0.30/5 4.0s}
Kxc7 {+1.26/7 4.0s} 20. Rb1 {-0.69/5 4.0s} d5+ {0.00/8 4.0s}
21. Kxd5 {-320.00/5 4.0s} Be6+ {0.00/8 4.0s} 22. Ke4 {-320.00/5 4.0s}
Qe3# {0.00/7 4.0s, Black mates} 0-1

104 changes: 1 addition & 103 deletions src/engine/debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,112 +47,10 @@ macro_rules! optlog {
}
}
}

}
};
}
}

// /// Querying the options, shorthand for discreet use in code. don't worry
// about /// this too much, kinda garbage code xd
// impl Opts {
// /// Search [`DebugLevel`] is TRACE
// pub fn st(&self) -> bool {
// self.search == DebugLevel::trace
// }
//
// /// Search [`DebugLevel`] is DEBUG or higher (TRACE)
// pub fn sd(&self) -> bool {
// self.search == DebugLevel::debug || self.st()
// }
//
// /// Search [`DebugLevel`] is INFO or higher (DEBUG, TRACE)
// pub fn si(&self) -> bool {
// self.search == DebugLevel::info || self.sd()
// }
//
// /// Search [`DebugLevel`] is WARN or higher (INFO, DEBUG, TRACE)
// pub fn sw(&self) -> bool {
// self.search == DebugLevel::warn || self.si()
// }
//
// /// Search [`DebugLevel`] is ERROR or higher (WARN, INFO, DEBUG, TRACE)
// pub fn se(&self) -> bool {
// self.search == DebugLevel::error || self.sw()
// }
//
// /// Eval [`DebugLevel`] is TRACE
// pub fn et(&self) -> bool {
// self.eval == DebugLevel::trace
// }
//
// /// Eval [`DebugLevel`] is DEBUG or higher (TRACE)
// pub fn ed(&self) -> bool {
// self.eval == DebugLevel::debug || self.et()
// }
//
// /// Eval [`DebugLevel`] is INFO or higher (DEBUG, TRACE)
// pub fn ei(&self) -> bool {
// self.eval == DebugLevel::info || self.ed()
// }
//
// /// Eval [`DebugLevel`] is WARN or higher (INFO, DEBUG, TRACE)
// pub fn ew(&self) -> bool {
// self.eval == DebugLevel::warn || self.ei()
// }
//
// /// Eval [`DebugLevel`] is ERROR or higher (WARN, INFO, DEBUG, TRACE)
// pub fn ee(&self) -> bool {
// self.eval == DebugLevel::error || self.ew()
// }
//
// /// Comm [`DebugLevel`] is TRACE
// pub fn ct(&self) -> bool {
// self.comm == DebugLevel::trace
// }
//
// /// Comm [`DebugLevel`] is DEBUG or higher (TRACE)
// pub fn cd(&self) -> bool {
// self.comm == DebugLevel::debug || self.ct()
// }
//
// /// Comm [`DebugLevel`] is INFO or higher (DEBUG, TRACE)
// pub fn ci(&self) -> bool {
// self.comm == DebugLevel::info || self.cd()
// }
//
// /// Comm [`DebugLevel`] is WARN or higher (INFO, DEBUG, TRACE)
// pub fn cw(&self) -> bool {
// self.comm == DebugLevel::warn || self.ci()
// }
//
// /// Comm [`DebugLevel`] is ERROR or higher (WARN, INFO, DEBUG, TRACE)
// pub fn ce(&self) -> bool {
// self.comm == DebugLevel::error || self.cw()
// }
//
// /// if debug level, print the message
// pub fn edp(&self, msg: &str) {
// if self.ed() {
// println!("{}", msg);
// }
// }
//
// /// if trace level, print the message
// pub fn stp(&self, msg: &str) {
// if self.st() {
// println!("{}", msg);
// }
// }
//
// pub fn ut(&self) -> bool {
// self.uci == DebugLevel::trace
// }
//
// pub fn ud(&self) -> bool {
// self.uci == DebugLevel::debug || self.ut()
// }
// }

impl DebugLevel {
/// This [`DebugLevel`] is TRACE
#[inline(always)]
Expand Down
17 changes: 15 additions & 2 deletions src/engine/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ pub mod uci;
pub mod util;

use std::sync::atomic::Ordering;
use std::sync::RwLock;
use std::thread;
use std::time::Duration;
use std::time::Instant;
Expand All @@ -32,18 +33,25 @@ use crate::search::SEARCHING;
use crate::search::SEARCH_TO;
use crate::search::SEARCH_UNTIL;
use crate::setup::depth::Depth;
use crate::transposition_table::TranspositionTable;
use crate::transposition_table::TT;
use crate::transposition_table::TT_INITIALISED;

#[derive(Debug)]
pub struct Engine {
pub board: Board,
pub created_at: Instant,
}

impl Engine {
pub fn new() -> Result<Self> {
info!("creating engine at version {}", env!("CARGO_PKG_VERSION"));
Ok(Self {
let mut s = Self {
board: Board::default(),
})
created_at: Instant::now(),
};
s.setup()?;
Ok(s)
}

pub fn set_search(&self, x: bool) {
Expand Down Expand Up @@ -77,6 +85,11 @@ impl Engine {
/// 4. ...
pub fn setup(&mut self) -> Result<()> {
// ...
unsafe {
TT.write(RwLock::new(TranspositionTable::new()?));
}
TT_INITIALISED.store(true, Ordering::Relaxed);

Ok(())
}

Expand Down
9 changes: 8 additions & 1 deletion src/engine/search/main_search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ impl Engine {

let mut target_depth = Depth(0);
let mut total_nodes = 0;
let mut table_hits = 0;
let start_time = Instant::now();

while !exit_condition() && target_depth < search_to() {
Expand Down Expand Up @@ -89,6 +90,9 @@ impl Engine {
// add up all the recursively searched nodes, and the one the search begun from
total_nodes += search_result.nodes_searched + 1;

// add up all the transposition table hits
table_hits += search_result.tt_hits;

// we found a better match, update:
// * best available value for a next position
// * best move to get to that position
Expand Down Expand Up @@ -131,6 +135,7 @@ impl Engine {
target_depth,
best_value,
total_nodes,
table_hits,
start_time.elapsed(),
&root.pv,
);
Expand All @@ -139,7 +144,7 @@ impl Engine {
send(&mut publisher, Message::BestMove(MV(mv, best_value)));
}
if let Some(ponder) = root.pv.get(1) {
send(&mut publisher, Message::Ponder(ponder.clone()));
send(&mut publisher, Message::Ponder(*ponder));
}
}

Expand All @@ -150,6 +155,8 @@ impl Engine {
send(&mut publisher, Message::BestMove(MV(mv, best_value)))
}

// looks sketchy, but it's to prevent dropping the sender before the receiver
// has gotten the best move.
thread::sleep(Duration::from_millis(
(SEARCH_THREADS * 2 * UCI_LISTENING_FREQUENCY) as u64,
));
Expand Down
20 changes: 14 additions & 6 deletions src/engine/search/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub static SEARCH_TO: AtomicU16 = AtomicU16::new(0);
pub static SEARCHING: AtomicBool = AtomicBool::new(false);
pub static EXIT: AtomicBool = AtomicBool::new(false);

#[derive(Debug, Clone)]
#[derive(Debug, Clone, Copy)]
pub struct MV(pub ChessMove, pub Value);

pub struct RootNode {
Expand All @@ -37,10 +37,12 @@ pub struct RootNode {
pub previous_eval: Value,
}

#[derive(Debug, Clone)]
pub struct SearchResult {
pub pv: Vec<MV>,
pub next_position_value: Value,
pub nodes_searched: usize,
pub nodes_searched: u32,
pub tt_hits: u32,
}

#[derive(Debug)]
Expand All @@ -55,9 +57,10 @@ pub enum Message {
pub struct SearchInfo {
pub depth: Depth,
pub score: Value,
pub nodes: usize,
pub nodes: u32,
pub time: Duration,
pub pv: Vec<MV>,
pub tt_hits: u32,
}

pub fn exit_condition() -> bool {
Expand All @@ -79,7 +82,8 @@ fn info(
publisher: &mut Sender<Message>,
target_depth: Depth,
best_value: Value,
total_nodes: usize,
total_nodes: u32,
tt_hits: u32,
el: Duration,
pv: &[MV],
) {
Expand All @@ -89,6 +93,7 @@ fn info(
nodes: total_nodes,
time: el,
pv: pv.to_vec(),
tt_hits,
})) {
debug!("error sending info message: {:?}", e);
}
Expand All @@ -104,10 +109,13 @@ impl SearchResult {
pub fn new_eval(&mut self, ev: Value) {
self.next_position_value = ev;
}
pub fn add_nodes(&mut self, nodes: usize) {
pub fn add_nodes(&mut self, nodes: u32) {
self.nodes_searched += nodes;
}
pub fn set_nodes(&mut self, nodes: usize) {
pub fn add_tt_hits(&mut self, nodes: u32) {
self.tt_hits += nodes;
}
pub fn set_nodes(&mut self, nodes: u32) {
self.nodes_searched = nodes;
}
}
Expand Down
Loading