diff --git a/src/complexagent.rs b/src/complexagent.rs index e8e2de4..3ae4a1e 100644 --- a/src/complexagent.rs +++ b/src/complexagent.rs @@ -183,24 +183,23 @@ impl FutureMoves { } fn compute_values(&mut self) { - // PERF! doing this filtering here previously visited moves reduces time - // spent in `depth_of` from 27.79% -> 2.9% - let mut visited = vec![false; self.arena.len()]; + // PERF! pre-organize all indexes based on what depth they're at + // previously, I did a lookup map based on if a node was visited, still resulted in a full + // O(n) iteration each depth + let mut by_depth: Vec> = (0..=self.max_depth + 2).map(|_| Vec::new()).collect(); + for idx in 0..self.arena.len() { + let depth = self.depth_of(idx); + // -1 because `depth_of` is zero-indexed + by_depth[depth - 1].push(idx); + } - for depth in (0..=self.current_depth).rev() { - for (idx, was_visited) in visited.iter_mut().enumerate() { - if *was_visited { - continue; - } else { - *was_visited = true; - } + for (depth, nodes) in by_depth.into_iter().enumerate().rev() { + // because enum is 0-index, inc depth + let depth = depth + 1; - if self.depth_of(idx) != depth as usize { - continue; - } - - let self_value = self.arena[idx].compute_self_value(self.agent_color) - / (self.current_depth - depth + 1) as i64; + for idx in nodes { + let self_value = + self.arena[idx].compute_self_value(self.agent_color) / (depth as isize) as i64; let children_value = self.arena[idx] .children @@ -263,6 +262,9 @@ impl FutureMoves { } } + /// Update the root based on the coordinate of the move + /// Returns a boolean, `true` if the operation was successful, false if not + #[must_use = "You must check if the root was properly set"] pub fn update_root_coord(&mut self, i: usize, j: usize) -> bool { self.arena .iter() @@ -317,6 +319,9 @@ impl FutureMoves { if let Some(parent) = node.parent.as_mut() { if let Some(new_parent) = index_map[*parent] { *parent = new_parent; + } else { + // make sure we don't have dangling parents + node.parent = None; } } @@ -344,7 +349,7 @@ pub struct ComplexAgent { impl ComplexAgent { pub const fn new(color: Piece) -> Self { - const MAX_DEPTH: usize = 15; + const MAX_DEPTH: usize = 17; Self { color, future_moves: FutureMoves::new(color, MAX_DEPTH),