From 0adb59dc7fdfe40aa8c813bbe08b6a3a9ac436e1 Mon Sep 17 00:00:00 2001 From: Simon Gardling Date: Tue, 25 Feb 2025 11:23:14 -0500 Subject: [PATCH] initial rewrite of lazy_children logic --- src/complexagent.rs | 4 ++-- src/logic/future_moves.rs | 37 ++++++++++++------------------------- src/logic/move.rs | 7 +++++++ 3 files changed, 21 insertions(+), 27 deletions(-) diff --git a/src/complexagent.rs b/src/complexagent.rs index ca680a8..dc3d4b4 100644 --- a/src/complexagent.rs +++ b/src/complexagent.rs @@ -12,8 +12,8 @@ pub struct ComplexAgent { #[allow(dead_code)] impl ComplexAgent { pub const fn new(color: Piece) -> Self { - const MAX_DEPTH: usize = 9; - const NON_LAZY_DEPTH: usize = 9; + const MAX_DEPTH: usize = 18; + const NON_LAZY_DEPTH: usize = 5; Self { color, future_moves: FutureMoves::new(color, MAX_DEPTH, NON_LAZY_DEPTH), diff --git a/src/logic/future_moves.rs b/src/logic/future_moves.rs index e548b6a..1fdcbda 100644 --- a/src/logic/future_moves.rs +++ b/src/logic/future_moves.rs @@ -113,7 +113,7 @@ impl FutureMoves { // use [`Board::all_positions`] here instead of [`Board::possible_moves`] // because we use [`Board::what_if`] later and we want to reduce calls to [`Board::propegate_from_dry`] - let mut new: Vec = Board::all_positions() + let new: Vec = Board::all_positions() .flat_map(|(i, j)| { parent .board @@ -133,37 +133,24 @@ impl FutureMoves { }) .collect(); - // negative, because we want the max value to be at the first index - // abs because we want the most EXTREME possible outcome (win or lose for example) - new.sort_by_key(|x| -x.self_value.abs()); - // keep the TOP_K children of their magnitude - const TOP_K_CHILDREN: usize = 2; - - // we want to keep only the greatest magnitude moves - if lazy_children && new.len() > TOP_K_CHILDREN { - new.drain(TOP_K_CHILDREN..); - } + const TOP_K_CHILDREN: usize = 10; let start_idx = self.arena.len(); - if parent.lazy_children && !lazy_children { - self.arena[parent_idx].lazy_children = false; - // this move's children are being regenerated after lazy child expiration, don't append first node - if new.len() > TOP_K_CHILDREN { - self.arena.extend(new.drain(TOP_K_CHILDREN..)); - } else { - // nothing will be appended - // even though it was sorted the first time around - // there's still no more than one element (which is already in the arena) - return None; - } - } else { - self.arena.extend(new); - } + self.arena.extend(new); let new_indices = start_idx..self.arena.len(); self.arena[parent_idx].children.extend(new_indices.clone()); + let mut parent_copy = self.arena[parent_idx].clone(); + parent_copy.sort_children(self.arena.as_mut_slice()); + self.arena[parent_idx] = parent_copy; + + if lazy_children && new_indices.clone().count() > TOP_K_CHILDREN { + for i in new_indices.clone().skip(TOP_K_CHILDREN) { + self.arena[i].lazy_children = true; + } + } Some(new_indices) } diff --git a/src/logic/move.rs b/src/logic/move.rs index c532f04..9e8979d 100644 --- a/src/logic/move.rs +++ b/src/logic/move.rs @@ -86,4 +86,11 @@ impl Move { BVM.board_value(&self.board, agent_color) } + + /// Sort children of the [`Move`] by their self_value in `arena` + pub fn sort_children(&mut self, arena: &[Move]) { + // negative, because we want the max value to be at the first index + // abs because we want the most EXTREME possible outcome (win or lose for example) + self.children.sort_by_key(|&i| -arena[i].self_value.abs()); + } }