From 201d5b3853a9ae5eee490975df844bffa7a9e0e2 Mon Sep 17 00:00:00 2001 From: Kyle Krowpman Date: Sat, 16 Nov 2024 18:30:44 -0800 Subject: [PATCH] use options in for moves --- src/bitboard.rs | 2 +- src/board.rs | 46 ++++++++++++++++++----------------- src/moov.rs | 18 ++++---------- src/move_list.rs | 27 +++++++++++---------- src/move_sorter.rs | 46 ++++++++++++++++++++++++----------- src/piece.rs | 21 +++++++--------- src/search.rs | 57 +++++++++++++++++++++----------------------- src/search_master.rs | 2 +- src/timer.rs | 13 ++++++---- src/tt.rs | 29 +++++++++++++++------- src/uci.rs | 2 +- 11 files changed, 141 insertions(+), 122 deletions(-) diff --git a/src/bitboard.rs b/src/bitboard.rs index 15c3c2c..c92698c 100644 --- a/src/bitboard.rs +++ b/src/bitboard.rs @@ -271,7 +271,7 @@ impl fmt::Debug for Bitboard { let mut result = String::new(); for i in (0..=56).rev().step_by(8) { for j in 0..8 { - result.push_str(format!("{} ", self.0 >> (i + j) & 1).as_ref()); + result.push_str(format!("{} ", self.0 >> (i + j) & 1).as_str()); } result.push('\n'); } diff --git a/src/board.rs b/src/board.rs index f096fd2..b0fd733 100644 --- a/src/board.rs +++ b/src/board.rs @@ -185,7 +185,7 @@ impl Board { self.is_attacked(self.bitboard_of(self.ctm, PieceType::King).lsb()) } - pub fn peek(&self) -> Move { + pub fn peek(&self) -> Option { self.history[self.ply].moov() } @@ -233,7 +233,6 @@ impl Board { self.history[self.ply] = HistoryEntry::default() .with_entry(self.history[self.ply - 1].entry()) - .with_moov(Move::NULL) .with_half_move_counter(self.history[self.ply - 1].half_move_counter() + 1) .with_plies_from_null(0) .with_material_hash(self.history[self.ply - 1].material_hash()); @@ -311,7 +310,7 @@ impl Board { }; self.history[self.ply] = HistoryEntry::default() .with_entry(self.history[self.ply - 1].entry() | m.to_sq().bb() | m.from_sq().bb()) - .with_moov(m) + .with_moov(Some(m)) .with_half_move_counter(half_move_counter) .with_plies_from_null(self.history[self.ply - 1].plies_from_null() + 1) .with_captured(captured) @@ -321,11 +320,11 @@ impl Board { self.hasher.update_color(); } - pub fn pop(&mut self) -> Move { + pub fn pop(&mut self) -> Option { self.ctm = !self.ctm; self.hasher.update_color(); - let m = self.history[self.ply].moov(); + let m = self.history[self.ply].moov()?; match m.flags() { MoveFlags::Quiet => { self.move_piece_quiet(m.to_sq(), m.from_sq()); @@ -361,7 +360,7 @@ impl Board { self.set_piece_at( self.history[self.ply] .captured() - .expect("Tried to revert a capture move with no capture"), + .expect("Tried to revert a capture move with no capture."), m.to_sq(), ); } @@ -370,13 +369,13 @@ impl Board { self.set_piece_at( self.history[self.ply] .captured() - .expect("Tried to revert a capture move with no capture"), + .expect("Tried to revert a capture move with no capture."), m.to_sq(), ); } } self.ply -= 1; - m + Some(m) } pub fn generate_legal_moves(&self, moves: &mut MoveList) { @@ -490,21 +489,22 @@ impl Board { } 1 => { let checker_square = checkers.lsb(); - let pt = self.piece_type_at(checker_square).unwrap(); + let pt = self + .piece_type_at(checker_square) + .expect(format!("No checker at {}", checker_square).as_str()); match pt { PieceType::Pawn | PieceType::Knight => { /////////////////////////////////////////////////////////////////// // If the checkers is a pawn, we have to look out for ep moves // that can capture it. /////////////////////////////////////////////////////////////////// + let epsq = self.history[self.ply].epsq(); if pt == PieceType::Pawn - && checkers - == self.history[self.ply] - .epsq() - .map_or(Bitboard::ZERO, |sq| sq.bb()) - .shift(Direction::South.relative(us)) + && epsq.is_some_and(|epsq| { + checkers == epsq.bb().shift(Direction::South.relative(us)) + }) { - let epsq = self.history[self.ply].epsq().unwrap(); + let epsq = epsq.expect("No epsq found for checker."); let pawns = attacks::pawn_attacks_sq(epsq, them) & self.bitboard_of(us, PieceType::Pawn) & not_pinned; @@ -630,7 +630,9 @@ impl Board { /////////////////////////////////////////////////////////////////// let pinned_pieces = !(not_pinned | self.bitboard_of(us, PieceType::Knight)); for sq in pinned_pieces { - let pt = self.piece_type_at(sq).unwrap(); + let pt = self.piece_type_at(sq).expect( + format!("Unexpected None for piece type at square {}.", sq).as_str(), + ); let attacks_along_pin = attacks::attacks(pt, sq, all) & Bitboard::line(our_king, sq); if QUIET { @@ -1075,10 +1077,10 @@ impl fmt::Display for Board { match self.board[sq.index()] { Some(pc) => { if empty_squares != 0 { - board_str.push_str(empty_squares.to_string().as_ref()); + board_str.push_str(empty_squares.to_string().as_str()); empty_squares = 0; } - board_str.push_str(pc.to_string().as_ref()); + board_str.push_str(pc.to_string().as_str()); } None => { empty_squares += 1; @@ -1086,7 +1088,7 @@ impl fmt::Display for Board { } } if empty_squares != 0 { - board_str.push_str(empty_squares.to_string().as_ref()); + board_str.push_str(empty_squares.to_string().as_str()); } if rank != Rank::One { board_str.push('/'); @@ -1159,7 +1161,7 @@ pub struct HistoryEntry { entry: Bitboard, captured: Option, epsq: Option, - moov: Move, + moov: Option, material_hash: Hash, half_move_counter: u16, plies_from_null: u16, @@ -1170,7 +1172,7 @@ impl HistoryEntry { self.entry } - pub fn moov(&self) -> Move { + pub fn moov(&self) -> Option { self.moov } @@ -1199,7 +1201,7 @@ impl HistoryEntry { *self } - pub fn with_moov(&mut self, moov: Move) -> Self { + pub fn with_moov(&mut self, moov: Option) -> Self { self.moov = moov; *self } diff --git a/src/moov.rs b/src/moov.rs index 36293a8..1da9861 100644 --- a/src/moov.rs +++ b/src/moov.rs @@ -24,6 +24,10 @@ impl Move { MoveFlags::from(((self.0 >> 12) & 0xf) as u8) } + pub fn move_int(&self) -> MoveInt { + self.0 + } + pub fn is_quiet(&self) -> bool { (self.0 >> 12) & 0b1100 == 0 } @@ -49,10 +53,6 @@ impl Move { pub fn is_castling(&self) -> bool { matches!(self.flags(), MoveFlags::OO | MoveFlags::OOO) } - - pub fn is_null(&self) -> bool { - *self == Move::NULL - } } impl From for Move { @@ -73,10 +73,6 @@ impl fmt::Display for Move { } } -impl Move { - pub const NULL: Self = Self(0); -} - #[derive(Debug, PartialEq, Eq)] pub enum MoveFlags { Quiet = 0b0000, @@ -95,12 +91,6 @@ pub enum MoveFlags { PcQueen = 0b1111, } -impl Default for MoveFlags { - fn default() -> Self { - MoveFlags::Quiet - } -} - impl From for MoveFlags { fn from(n: u8) -> Self { unsafe { std::mem::transmute::(n) } diff --git a/src/move_list.rs b/src/move_list.rs index d1aae8f..9dd8a6f 100644 --- a/src/move_list.rs +++ b/src/move_list.rs @@ -21,7 +21,7 @@ const MAX_MOVES: usize = 254; const MAX_MOVES: usize = 255; pub struct MoveList { - moves: [Move; MAX_MOVES], + moves: [Option; MAX_MOVES], pub scores: [Value; MAX_MOVES], idx: usize, len: usize, @@ -30,7 +30,7 @@ pub struct MoveList { impl MoveList { pub fn new() -> Self { Self { - moves: [Move::NULL; MAX_MOVES], + moves: [None; MAX_MOVES], scores: [0; MAX_MOVES], idx: 0, len: 0, @@ -54,31 +54,31 @@ impl MoveList { } pub fn contains(&self, m: Move) -> bool { - self.moves[..self.len].contains(&m) + self.moves[..self.len].contains(&Some(m)) } pub fn push(&mut self, m: Move) { - self.moves[self.len] = m; + self.moves[self.len] = Some(m); self.len += 1; } pub fn make_q(&mut self, from_sq: SQ, to: Bitboard) { for to_sq in to { - self.moves[self.len] = Move::new(from_sq, to_sq, MoveFlags::Quiet); + self.moves[self.len] = Some(Move::new(from_sq, to_sq, MoveFlags::Quiet)); self.len += 1; } } pub fn make_c(&mut self, from_sq: SQ, to: Bitboard) { for to_sq in to { - self.moves[self.len] = Move::new(from_sq, to_sq, MoveFlags::Capture); + self.moves[self.len] = Some(Move::new(from_sq, to_sq, MoveFlags::Capture)); self.len += 1; } } pub fn make_dp(&mut self, from_sq: SQ, to: Bitboard) { for to_sq in to { - self.moves[self.len] = Move::new(from_sq, to_sq, MoveFlags::DoublePush); + self.moves[self.len] = Some(Move::new(from_sq, to_sq, MoveFlags::DoublePush)); self.len += 1; } } @@ -91,7 +91,7 @@ impl MoveList { MoveFlags::PcRook, MoveFlags::PcBishop, ] { - self.moves[self.len] = Move::new(from_sq, to_sq, flag); + self.moves[self.len] = Some(Move::new(from_sq, to_sq, flag)); self.len += 1; } } @@ -117,7 +117,7 @@ impl MoveList { let idx = self.idx; self.idx += 1; - Some(self.moves[idx]) + self.moves[idx] } } @@ -132,7 +132,7 @@ impl Iterator for MoveList { let idx = self.idx; self.idx += 1; - Some(self.moves[idx]) + self.moves[idx] } } @@ -140,7 +140,9 @@ impl Index for MoveList { type Output = Move; fn index(&self, i: usize) -> &Self::Output { - &self.moves[i] + self.moves[i] + .as_ref() + .expect("Tried to access an empty slot in MoveList") } } @@ -148,7 +150,8 @@ impl fmt::Debug for MoveList { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let mut result = String::from('['); for i in 0..self.len { - result.push_str(format!("{}, ", self.moves[i]).as_ref()); + let m = self.moves[i].expect("None found in MoveList"); + result.push_str(format!("{}, ", m).as_str()); } result.push(']'); write!(f, "{}", result) diff --git a/src/move_sorter.rs b/src/move_sorter.rs index de8ef16..f02aa67 100644 --- a/src/move_sorter.rs +++ b/src/move_sorter.rs @@ -9,26 +9,32 @@ use super::square::*; use super::types::*; pub struct MoveSorter { - killer_moves: [[[Move; Self::N_KILLERS]; MAX_MOVES]; Color::N_COLORS], + killer_moves: [[[Option; Self::N_KILLERS]; MAX_MOVES]; Color::N_COLORS], history_scores: [[Value; SQ::N_SQUARES]; SQ::N_SQUARES], } impl MoveSorter { pub fn new() -> Self { Self { - killer_moves: [[[Move::NULL; Self::N_KILLERS]; MAX_MOVES]; Color::N_COLORS], + killer_moves: [[[None; Self::N_KILLERS]; MAX_MOVES]; Color::N_COLORS], history_scores: [[0; SQ::N_SQUARES]; SQ::N_SQUARES], } } - pub fn score_moves(&self, moves: &mut MoveList, board: &Board, ply: Ply, hash_move: Move) { + pub fn score_moves( + &self, + moves: &mut MoveList, + board: &Board, + ply: Ply, + hash_move: Option, + ) { for idx in 0..moves.len() { moves.scores[idx] = self.score_move(moves[idx], board, ply, hash_move); } } - fn score_move(&self, m: Move, board: &Board, ply: Ply, hash_move: Move) -> Value { - if m == hash_move { + fn score_move(&self, m: Move, board: &Board, ply: Ply, hash_move: Option) -> Value { + if Some(m) == hash_move { return Self::HASH_MOVE_SCORE; } @@ -70,9 +76,15 @@ impl MoveSorter { } fn mvv_lva_score(board: &Board, m: Move) -> Value { - Self::MVV_LVA_SCORES[board.piece_type_at(m.to_sq()).unwrap().index() + Self::MVV_LVA_SCORES[board + .piece_type_at(m.to_sq()) + .expect("No captured in MVVLVA.") + .index() * PieceType::N_PIECE_TYPES - + board.piece_type_at(m.from_sq()).unwrap().index()] + + board + .piece_type_at(m.from_sq()) + .expect("No attacker in MVVLVA.") + .index()] } pub fn add_killer(&mut self, board: &Board, m: Move, ply: Ply) { @@ -80,7 +92,7 @@ impl MoveSorter { let killer_moves = &mut self.killer_moves[color][ply]; killer_moves.rotate_right(1); - killer_moves[0] = m; + killer_moves[0] = Some(m); } pub fn add_history(&mut self, m: Move, depth: Depth) { @@ -98,7 +110,7 @@ impl MoveSorter { } fn is_killer(&self, board: &Board, m: Move, ply: usize) -> bool { - self.killer_moves[board.ctm().index()][ply].contains(&m) + self.killer_moves[board.ctm().index()][ply].contains(&Some(m)) } fn history_score(&self, m: Move) -> Value { @@ -113,8 +125,9 @@ impl MoveSorter { let from_sq = m.from_sq(); let to_sq = m.to_sq(); - // We know we're dealing with a capture at this point, so just unwrap. - let mut captured_pt = board.piece_type_at(to_sq).unwrap(); + let Some(captured_pt) = board.piece_type_at(to_sq) else { + return false; + }; let mut value = Self::SEE_PIECE_TYPE[captured_pt.index()]; @@ -122,7 +135,9 @@ impl MoveSorter { return false; } - let mut attacking_pt = board.piece_type_at(from_sq).unwrap(); + let Some(mut attacking_pt) = board.piece_type_at(from_sq) else { + return false; + }; value -= Self::SEE_PIECE_TYPE[attacking_pt.index()]; @@ -148,7 +163,7 @@ impl MoveSorter { // We know at this point that there must be a piece, so find the least valuable attacker. attacking_pt = PieceType::iter(PieceType::Pawn, PieceType::King) .find(|&pt| stm_attackers & board.bitboard_of_pt(pt) != Bitboard::ZERO) - .unwrap(); + .expect("No attacking pt found."); ctm = !ctm; @@ -179,7 +194,10 @@ impl MoveSorter { } } - ctm != board.piece_at(from_sq).unwrap().color_of() + ctm != board + .piece_at(from_sq) + .expect("No piece at original attacking square.") + .color_of() } } diff --git a/src/piece.rs b/src/piece.rs index 34ecf61..c39abb9 100644 --- a/src/piece.rs +++ b/src/piece.rs @@ -61,12 +61,11 @@ impl TryFrom for Piece { type Error = &'static str; fn try_from(value: char) -> Result { - if Self::PIECE_STR.contains(value) { - return Ok(Self::from( - Self::PIECE_STR.chars().position(|c| c == value).unwrap() as u8, - )); - } - Err("Piece symbols should be one of \"KQRBNPkqrbnp\"") + Self::PIECE_STR + .chars() + .position(|c| c == value) + .map(|x| Self::from(x as u8)) + .ok_or("Piece symbols should be one of \"KQRBNPkqrbnp\"") } } @@ -78,9 +77,7 @@ impl fmt::Display for Piece { Self::PIECE_STR .chars() .nth(*self as usize) - .unwrap() - .to_string() - .replace(" ", "") + .expect("Piece symbol should be valid.") ) } } @@ -124,14 +121,12 @@ impl fmt::Display for PieceType { Self::PIECE_TYPE_STR .chars() .nth(*self as usize) - .unwrap() - .to_string() - .replace(" ", "") + .expect("PieceType symbol should be valid.") ) } } impl PieceType { pub const N_PIECE_TYPES: usize = 6; - pub const PIECE_TYPE_STR: &'static str = "pnbrqk "; + pub const PIECE_TYPE_STR: &'static str = "pnbrqk"; } diff --git a/src/search.rs b/src/search.rs index b7761da..d61105b 100644 --- a/src/search.rs +++ b/src/search.rs @@ -37,7 +37,7 @@ impl<'a> Search<'a> { /////////////////////////////////////////////////////////////////// let mut alpha = -Self::MATE; let mut beta = Self::MATE; - let mut best_move = Move::NULL; + let mut best_move = None; let mut value = 0; let mut depth = 1; @@ -79,8 +79,10 @@ impl<'a> Search<'a> { beta = Self::MATE; } else { // Only print info if we're in the main thread - if self.id == 0 && !best_move.is_null() && !self.stop { - self.print_info(&mut board, depth, best_move, value); + if self.id == 0 && !self.stop { + if let Some(best_move) = best_move { + self.print_info(&mut board, depth, best_move, value); + } } alpha = value - Self::ASPIRATION_WINDOW; beta = value + Self::ASPIRATION_WINDOW; @@ -93,7 +95,7 @@ impl<'a> Search<'a> { self.timer.stop(); } - Some(best_move) + best_move } fn search_root( @@ -102,7 +104,7 @@ impl<'a> Search<'a> { mut depth: Depth, mut alpha: Value, beta: Value, - ) -> (Move, Value) { + ) -> (Option, Value) { /////////////////////////////////////////////////////////////////// // Check extension. /////////////////////////////////////////////////////////////////// @@ -114,17 +116,14 @@ impl<'a> Search<'a> { // Check the hash table for the current // position, primarily for move ordering. /////////////////////////////////////////////////////////////////// - let mut hash_move = Move::NULL; - if let Some(tt_entry) = self.tt.probe(board) { - hash_move = tt_entry.best_move(); - } + let hash_move = self.tt.probe(board).and_then(|entry| entry.best_move()); /////////////////////////////////////////////////////////////////// // Score moves and begin searching recursively. /////////////////////////////////////////////////////////////////// let ply = 0; let mut value = -Self::MATE; - let mut best_move = Move::NULL; + let mut best_move = None; let mut idx = 0; let mut moves = MoveList::from(board); @@ -147,7 +146,7 @@ impl<'a> Search<'a> { } if value > alpha { - best_move = m; + best_move = Some(m); if value >= beta { self.tt.insert(board, depth, beta, best_move, Bound::Lower); return (best_move, beta); @@ -158,8 +157,8 @@ impl<'a> Search<'a> { idx += 1; } - if best_move.is_null() && moves.len() > 0 { - best_move = moves[0]; + if best_move.is_none() && moves.len() > 0 { + best_move = Some(moves[0]); } if !self.stop { @@ -245,11 +244,8 @@ impl<'a> Search<'a> { // Reverse Futility Pruning /////////////////////////////////////////////////////////////////// if Self::can_apply_rfp(depth, in_check, is_pv, beta) { - let eval = if let Some(tt_entry) = tt_entry { - tt_entry.value() - } else { - board.eval() - }; + let eval = tt_entry.map_or(board.eval(), |entry| entry.value()); + if eval - Self::rfp_margin(depth) >= beta { return eval; } @@ -276,7 +272,7 @@ impl<'a> Search<'a> { // recursively. /////////////////////////////////////////////////////////////////// let mut tt_flag = Bound::Upper; - let mut best_move = Move::NULL; + let mut best_move = None; let mut idx = 0; let mut moves = MoveList::from(board); @@ -284,7 +280,7 @@ impl<'a> Search<'a> { &mut moves, board, ply, - tt_entry.map_or(Move::NULL, |entry| entry.best_move()), + tt_entry.and_then(|entry| entry.best_move()), ); while let Some(m) = moves.next_best() { @@ -338,7 +334,7 @@ impl<'a> Search<'a> { // Re-bound, check for cutoffs, and add killers and history. /////////////////////////////////////////////////////////////////// if value > alpha { - best_move = m; + best_move = Some(m); if value >= beta { if m.is_quiet() { self.move_sorter.add_killer(board, m, ply); @@ -365,8 +361,8 @@ impl<'a> Search<'a> { } } - if best_move.is_null() && moves.len() > 0 { - best_move = moves[0]; + if best_move.is_none() && moves.len() > 0 { + best_move = Some(moves[0]); } if !self.stop { @@ -402,7 +398,7 @@ impl<'a> Search<'a> { } alpha = alpha.max(eval); - let mut hash_move = Move::NULL; + let mut hash_move = None; if let Some(tt_entry) = self.tt.probe(board) { match tt_entry.flag() { Bound::Exact => return tt_entry.value(), @@ -458,7 +454,7 @@ impl<'a> Search<'a> { ) -> bool { !is_pv && !in_check - && board.peek() != Move::NULL + && board.peek().is_some() && depth >= Self::NULL_MIN_DEPTH && board.has_non_pawn_material() && board.eval() >= beta @@ -502,11 +498,12 @@ impl<'a> Search<'a> { if let Some(tt_entry) = self.tt.probe(board) { let mut pv = String::new(); - let hash_move = tt_entry.best_move(); - if MoveList::from(board).contains(hash_move) { - board.push(hash_move); - pv = format!("{} {}", hash_move, self.get_pv(board, depth - 1)); - board.pop(); + if let Some(hash_move) = tt_entry.best_move() { + if MoveList::from(board).contains(hash_move) { + board.push(hash_move); + pv = format!("{} {}", hash_move, self.get_pv(board, depth - 1)); + board.pop(); + } } return pv; } diff --git a/src/search_master.rs b/src/search_master.rs index 5c27c8a..390ff6c 100644 --- a/src/search_master.rs +++ b/src/search_master.rs @@ -130,7 +130,7 @@ impl SearchMaster { } fn set_option(&mut self, name: String, value: String) { - let result = match (name.as_ref(), value.parse::()) { + let result = match (name.as_str(), value.parse::()) { ("Hash", Ok(parsed_value)) => { self.tt = TT::new(parsed_value as usize); format!("Hash to {}MB", self.tt.mb_size()) diff --git a/src/timer.rs b/src/timer.rs index 5339610..a5a93b4 100644 --- a/src/timer.rs +++ b/src/timer.rs @@ -95,7 +95,7 @@ pub struct Timer { time_target: Duration, time_maximum: Duration, overhead: Duration, - best_move: Move, + last_best_move: Option, } impl Timer { @@ -140,7 +140,7 @@ impl Timer { overhead, time_target, time_maximum, - best_move: Move::NULL, + last_best_move: None, times_checked: 0, } } @@ -212,12 +212,15 @@ impl Timer { self.start_time.elapsed() } - pub fn update(&mut self, best_move: Move) { - if !self.best_move.is_null() && best_move != self.best_move { + pub fn update(&mut self, best_move: Option) { + if self + .last_best_move + .is_some_and(|last_move| Some(last_move) != best_move) + { self.time_target = self.time_maximum.min(self.time_target * 3 / 2); } - self.best_move = best_move; + self.last_best_move = best_move; } } diff --git a/src/tt.rs b/src/tt.rs index 27579fc..583889e 100644 --- a/src/tt.rs +++ b/src/tt.rs @@ -14,23 +14,27 @@ use super::types::*; #[derive(Eq, PartialEq, Copy, Clone)] pub struct TTEntry { value: Value, - best_move: Move, + best_move: MoveInt, depth: Depth, flag: Bound, } impl TTEntry { - pub fn new(value: Value, best_move: Move, depth: Depth, flag: Bound) -> Self { + pub fn new(value: Value, best_move: Option, depth: Depth, flag: Bound) -> Self { TTEntry { - best_move, + best_move: best_move.map(|m| m.move_int()).unwrap_or(0), depth, value, flag, } } - pub fn best_move(&self) -> Move { - self.best_move + pub fn best_move(&self) -> Option { + if self.best_move > 0 { + Some(Move::from(self.best_move)) + } else { + None + } } pub fn depth(&self) -> Depth { @@ -49,7 +53,7 @@ impl TTEntry { impl Default for TTEntry { fn default() -> Self { Self { - best_move: Move::NULL, + best_move: 0, depth: 0, value: 0, flag: Bound::Exact, @@ -80,8 +84,8 @@ pub struct TT { impl TT { pub fn new(mb_size: usize) -> Self { - assert_eq!(std::mem::size_of::(), 8); - let upper_limit = mb_size * 1024 * 1024 / std::mem::size_of::() + 1; + assert_eq!(size_of::(), 8); + let upper_limit = mb_size * 1024 * 1024 / size_of::() + 1; let count = upper_limit.next_power_of_two() / 2; let mut table = Vec::with_capacity(count); @@ -95,7 +99,14 @@ impl TT { } } - pub fn insert(&self, board: &Board, depth: Depth, value: Value, best_move: Move, flag: Bound) { + pub fn insert( + &self, + board: &Board, + depth: Depth, + value: Value, + best_move: Option, + flag: Bound, + ) { unsafe { self.table .get_unchecked(self.index(board)) diff --git a/src/uci.rs b/src/uci.rs index dc41adc..4e95194 100644 --- a/src/uci.rs +++ b/src/uci.rs @@ -35,7 +35,7 @@ impl UCI { .lines() .map(|line| line.expect("Unable to parse line.")) { - match UCICommand::try_from(line.as_ref()) { + match UCICommand::try_from(line.as_str()) { Ok(cmd) => match cmd { UCICommand::Quit => return, UCICommand::Stop => self.stop.store(true, sync::atomic::Ordering::SeqCst),