optimize compute_values a TON (reduce depth_of calls)... and other stuff

This commit is contained in:
Simon Gardling 2025-02-13 00:01:20 -05:00
parent ad3d31e24a
commit 9a8b674720
Signed by: titaniumtown
GPG Key ID: 9AB28AC10ECE533D

View File

@ -1,3 +1,5 @@
use either::Either;
use crate::{agent::Agent, board::Board, piece::Piece};
#[derive(Clone)]
@ -137,8 +139,20 @@ 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()];
for depth in (0..=self.current_depth).rev() {
let nodes_at_depth: Vec<usize> = (0..self.arena.len())
.filter(|&idx| {
if visited[idx] {
false
} else {
visited[idx] = true;
true
}
})
.filter(|&idx| self.depth_of(idx) == depth)
.collect();
@ -171,18 +185,15 @@ impl FutureMoves {
}
pub fn best_move(&self) -> Option<(usize, usize)> {
let root_nodes = match self.current_root {
Some(root) => vec![root],
None => self
.arena
(match self.current_root {
Some(root) => Either::Left(vec![root].into_iter()),
None => Either::Right(
self.arena
.iter()
.enumerate()
.filter_map(|(idx, node)| node.parent.is_none().then_some(idx))
.collect(),
};
root_nodes
.into_iter()
.filter_map(|(idx, node)| node.parent.is_none().then_some(idx)),
),
})
.map(|idx| &self.arena[idx])
.max_by_key(|x| x.value)
.map(|x| (x.i, x.j))
@ -209,7 +220,12 @@ impl FutureMoves {
};
let mut retain = vec![false; self.arena.len()];
let mut stack = vec![root];
// stack is going to be AT MAXIMUM, the size of the array,
// so lets just pre-allocate it
let mut stack = Vec::with_capacity(self.arena.len());
stack.push(root);
// traverse children of the current root
while let Some(idx) = stack.pop() {
retain[idx] = true;