diff --git a/src/gamemanager/legal_moves/search.rs b/src/gamemanager/legal_moves/search.rs index 6202572..399e242 100644 --- a/src/gamemanager/legal_moves/search.rs +++ b/src/gamemanager/legal_moves/search.rs @@ -1,3 +1,8 @@ +use std::sync::{ + atomic::{AtomicBool, Ordering}, + Arc, +}; + use rayon::prelude::*; use crate::types::{Move, MoveType, PieceType, Square}; @@ -5,7 +10,12 @@ use crate::types::{Move, MoveType, PieceType, Square}; use super::{GameManager, MoveTable, NoArc}; /// A Negamax search routine that runs in parallel. -pub fn root_negamax(depth: u16, gm: GameManager, tbl: &NoArc) -> (Move, GameManager) { +pub fn root_negamax( + depth: u16, + gm: &GameManager, + tbl: &NoArc, + flag: Arc, +) -> (Move, GameManager) { let moves = gm.legal_moves(tbl); if moves.len() == 0 { @@ -19,7 +29,7 @@ pub fn root_negamax(depth: u16, gm: GameManager, tbl: &NoArc) -> (Mov .into_par_iter() .map(|mv| { ( - -negamax(depth, -beta, -alpha, mv.3, &mv.4, tbl), + -negamax(depth, -beta, -alpha, mv.3, &mv.4, tbl, flag.clone()), ((mv.0, mv.1, mv.2, mv.3), mv.4), ) }) @@ -53,8 +63,13 @@ fn negamax( movetype: MoveType, gm: &GameManager, tbl: &NoArc, + flag: Arc, ) -> i32 { - if depth == 0 { + if flag.load(Ordering::Relaxed) == false || depth == 0 { + // NOTE: Call quiesence search on the current position regardless of + // depth if the flag "continue searching" is false. We can't stop + // immediately without throwing out the work at this depth entirely, + // and I'm not that good at concurrent programs to make that work. capture_search(alpha, beta, movetype, gm, tbl) } else { let moves = gm.legal_moves(tbl); @@ -66,7 +81,15 @@ fn negamax( let mut score = i32::MIN + 1; for mv in moves { // Call negamax and negate it's return value. Enemy's alpha is our -beta & v.v. - score = score.max(-negamax(depth - 1, -beta, -alpha, mv.3, &mv.4, tbl)); + score = score.max(-negamax( + depth - 1, + -beta, + -alpha, + mv.3, + &mv.4, + tbl, + flag.clone(), + )); alpha = alpha.max(score); if alpha >= beta { break; diff --git a/src/main.rs b/src/main.rs index 732d2cb..ad0dc4c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,5 @@ #![allow(dead_code)] -use gamemanager::{legal_moves::search::root_negamax, GameManager}; -use movetable::{noarc, MoveTable}; mod bitboard; mod enginemanager; mod gamemanager; @@ -10,13 +8,6 @@ mod types; mod ucimanager; fn main() { - let tbl = noarc::NoArc::new(MoveTable::default()); - - let gm = - GameManager::from_fen_str("rn1b1k1r/p4ppp/1pp5/8/2B5/3n4/PPP1N1PP/RNBQ1K1R w - - 0 11"); - let bestmove = root_negamax(4, gm, &tbl).0; - println!("Best move: {}{}", bestmove.1.to_str(), bestmove.2.to_str()); - ucimanager::communicate(); } diff --git a/src/ucimanager.rs b/src/ucimanager.rs index 74fea06..5bbbcba 100644 --- a/src/ucimanager.rs +++ b/src/ucimanager.rs @@ -1,3 +1,4 @@ +use crate::gamemanager::legal_moves::search::root_negamax; use crate::types::{MoveType, Square}; use crate::{ enginemanager::Engine, @@ -62,15 +63,26 @@ pub fn communicate() { //e.set_new_game = false; } UciMessage::Go { - time_control: _, - search_control: _, + time_control, + search_control, } => { start_search_flag.store(true, Ordering::Relaxed); - let clone_flag = start_search_flag.clone(); + let flag = start_search_flag.clone(); - thread::spawn(move || { - //search() - pass in clone_flag to check whether search termination was ordered - }); + if let Some(timectl) = time_control { + match timectl { + vampirc_uci::UciTimeControl::Infinite => { + for depth in 0..20 + /* or any big number */ + { + root_negamax(depth, &e.board, &e.tbl, flag.clone()); + } + } + vampirc_uci::UciTimeControl::MoveTime(time) => {} + vampirc_uci::UciTimeControl::Ponder => unimplemented!(), + vampirc_uci::UciTimeControl::TimeLeft { .. } => unimplemented!(), + } + } } UciMessage::Stop => { start_search_flag.store(false, Ordering::Relaxed); @@ -86,7 +98,7 @@ pub fn communicate() { } } -fn make_move(board: &GameManager, tbl: &NoArc, m: UciMove) -> GameManager{ +fn make_move(board: &GameManager, tbl: &NoArc, m: UciMove) -> GameManager { let h_from = Square::from_str(&m.from.to_string()).unwrap(); let h_to = Square::from_str(&m.to.to_string()).unwrap(); let legal_moves = board.legal_moves(tbl);