diff --git a/src/search/movepick.rs b/src/search/movepick.rs index 0ecccaf3..9c19ffe6 100644 --- a/src/search/movepick.rs +++ b/src/search/movepick.rs @@ -8,7 +8,6 @@ use rand::{thread_rng, Rng}; use std::sync::Arc; type ScoredVec = Vec<(Move, ValueScore)>; -type PickResult = (Move, ValueScore); const RANDOM_FACTOR: ValueScore = 1000; @@ -40,7 +39,7 @@ impl MovePicker { } impl std::iter::Iterator for MovePicker { - type Item = PickResult; + type Item = Move; fn next(&mut self) -> Option { find_next_max_and_swap(&mut self.moves, &mut self.index) @@ -75,11 +74,11 @@ impl MovePicker { } impl std::iter::Iterator for MovePicker { - type Item = PickResult; + type Item = Move; fn next(&mut self) -> Option { - if let Some((mov, score)) = find_next_max_and_swap(&mut self.moves, &mut self.index) { - return Some((mov, score)); + if let Some(mov) = find_next_max_and_swap(&mut self.moves, &mut self.index) { + return Some(mov); } match self.stage { @@ -121,7 +120,7 @@ where moves.iter().map(|mov| (*mov, f(*mov))).collect() } -fn find_next_max_and_swap(moves: &mut ScoredVec, index: &mut usize) -> Option { +fn find_next_max_and_swap(moves: &mut ScoredVec, index: &mut usize) -> Option { if *index >= moves.len() { return None; } @@ -136,5 +135,5 @@ fn find_next_max_and_swap(moves: &mut ScoredVec, index: &mut usize) -> Opt } *index += 1; - Some((moves[*index - 1].0, moves[*index - 1].1)) + Some(moves[*index - 1].0) } diff --git a/src/search/pvs.rs b/src/search/pvs.rs index 1ae75b64..9f89297b 100644 --- a/src/search/pvs.rs +++ b/src/search/pvs.rs @@ -61,19 +61,19 @@ fn quiesce( let mut count = 1; - for (mov, _) in picker { - // Delta prune move if it cannot improve the score + for mov in picker { if !is_check && mov.flag().is_capture() { + // Delta pruning: if there is no way this capture can improve the score, prune immediately. let captured_piece = position.board.piece_color_at(mov.to()).map_or_else(|| Piece::Pawn, |p| p.0); if static_evaluation + captured_piece.value() + MAX_POSITIONAL_GAIN < alpha { continue; } - } - // Static exchange evaluation: if we lose material, there is no point in searching further. - if see::see(mov, &position.board) < 0 { - continue; + // Static exchange evaluation: if we lose material, there is no point in searching further. + if see::see(mov, &position.board) < 0 { + continue; + } } let (score, nodes) = quiesce(&position.make_move(mov), -beta, -alpha, constraint); @@ -258,14 +258,14 @@ fn pvs( // We need to keep track of the original alpha and best moves, to store // the correct node type and move in the hash table later. let original_alpha = alpha; - let mut best_move = picker.peek().map(|(mov, _)| *mov).unwrap(); + let mut best_move = picker.peek().copied().unwrap(); // Check extension: we are interested in exploring the outcome of this properly. if is_check { depth = depth.saturating_add(1).min(MAX_DEPTH); } - for (i, (mov, _)) in picker.enumerate() { + for (i, mov) in picker.enumerate() { // Extended futility pruning: discard moves without potential if depth <= 2 && i > 0 && !may_be_zug { let move_potential = MAX_POSITIONAL_GAIN * depth as ValueScore diff --git a/src/search/see.rs b/src/search/see.rs index b6cd8849..02c6731d 100644 --- a/src/search/see.rs +++ b/src/search/see.rs @@ -15,6 +15,8 @@ fn least_valuable(bb: Bitboard, board: &Board) -> Option<(Piece, Square)> { } pub fn see(mov: Move, board: &Board) -> ValueScore { + debug_assert!(mov.flag().is_capture()); + let mut board = *board; // Store the "best score" when it is our turn to move.