From 52e7ed73868af2949931482b8752aa1eaf9b8554 Mon Sep 17 00:00:00 2001 From: Simon Gardling Date: Fri, 7 Mar 2025 22:21:45 -0500 Subject: [PATCH] fully fix future_moves --- benches/future_children.rs | 2 +- src/complexagent.rs | 1 + src/logic/future_moves.rs | 110 ++++++++++--------------------------- 3 files changed, 31 insertions(+), 82 deletions(-) diff --git a/benches/future_children.rs b/benches/future_children.rs index 03947a3..aa07a76 100644 --- a/benches/future_children.rs +++ b/benches/future_children.rs @@ -16,7 +16,7 @@ fn extend_layers_no_pruning(depth: usize, arena_size: usize) -> usize { children_eval_method: ChildrenEvalMethod::Max, }; let mut fut = FutureMoves::new(Piece::Black, config); - fut.set_root_from_board(Board::new().starting_pos()); + fut.update_from_board(&Board::new().starting_pos()); fut.extend_layers(); fut.arena_len() } diff --git a/src/complexagent.rs b/src/complexagent.rs index 345ab2a..0826cf4 100644 --- a/src/complexagent.rs +++ b/src/complexagent.rs @@ -22,6 +22,7 @@ impl ComplexAgent { impl Agent for ComplexAgent { fn next_move(&mut self, board: &Board) -> Option { self.future_moves.update_from_board(board); + self.future_moves.generate(); self.future_moves .best_move() diff --git a/src/logic/future_moves.rs b/src/logic/future_moves.rs index c4dc283..e6aafde 100644 --- a/src/logic/future_moves.rs +++ b/src/logic/future_moves.rs @@ -366,54 +366,41 @@ impl FutureMoves { // match the agent_color usually root or great-grand child .filter(|&idx| self.depth_of(idx) % 2 == 0) .find(|&idx| { - self.get_board_from_idx(idx).as_ref() == Some(board) - && self.arena[idx].color == !self.agent_color + self.arena[idx].color == !self.agent_color + && self.get_board_from_idx(idx).as_ref() == Some(board) }); if let Some(curr_board_idx) = curr_board { - self.set_root_idx_raw(curr_board_idx); + self.root_from_child_idx_board(curr_board_idx, *board); false } else { if self.config.print && !self.arena.is_empty() { println!("regenerating arena from board"); } - self.set_root_from_board(*board); + self.rebuild_from_board(*board); true } } - /// Clear the arena and create and set a root which contains a Board - pub fn set_root_from_board(&mut self, board: Board) { + pub fn generate(&mut self) { + self.extend_layers(); + self.compute_values(0..self.arena.len()); + } + + fn rebuild_from_board(&mut self, board: Board) { self.arena.clear(); self.arena .push(Move::new(None, board, !self.agent_color, self.agent_color)); - - // because we have to regenerate root from a [`Board`] - // we need to reset the current_depth (fixes `skip_move_recovery`) + self.current_root = Some(0); self.current_depth = 0; - - self.set_root_idx_raw(0); + self.board = board; } - /// Update current root without modifying or pruning the Arena - fn update_root_idx_raw(&mut self, idx: usize) { - self.current_root = Some(idx); + fn root_from_child_idx_board(&mut self, idx: usize, board: Board) { self.current_depth -= self.depth_of(idx); - } - - /// Update current root index while pruning and extending the tree (also recalculate values) - fn set_root_idx_raw(&mut self, idx: usize) { - self.update_root_idx_raw(idx); - + self.current_root = Some(idx); + self.board = board; self.refocus_tree(); - self.extend_layers(); - if self.config.print { - println!("# of moves stored: {}", self.arena_len()); - } - self.compute_values(0..self.arena.len()); - - // check arena's consistancy - debug_assert_eq!(self.check_arena().join("\n"), ""); } pub fn set_parent_child(&mut self, parent: usize, child: usize) { @@ -574,26 +561,14 @@ mod tests { max_arena_size: 100, do_prune: false, print: false, - children_eval_method: ChildrenEvalMethod::Max, + children_eval_method: ChildrenEvalMethod::Average, }; #[test] fn prune_tree_test() { let mut futm = FutureMoves::new(Piece::Black, FUTURE_MOVES_CONFIG); - futm.arena.push(Move { - coord: None, - winner: Winner::None, - parent: None, - children: Vec::new(), - value: None, - self_value: 0, - color: Piece::Black, - is_trimmed: false, - tried_children: false, - }); - - futm.update_root_idx_raw(0); + futm.update_from_board(&Board::new()); // child 1 futm.arena @@ -636,20 +611,17 @@ mod tests { let mut futm = FutureMoves::new(Piece::Black, FUTURE_MOVES_CONFIG); futm.config.max_depth = 1; - futm.arena.push(Move::new( - None, - Board::new().starting_pos(), - Piece::Black, - Piece::Black, - )); - - futm.update_root_idx_raw(0); + futm.update_from_board(&Board::new().starting_pos()); futm.extend_layers(); assert_eq!(futm.arena_len(), 5); // move to a child - futm.update_root_idx_raw(1); + futm.root_from_child_idx_board( + 1, + futm.get_board_from_idx(1) + .expect("unable to get board from child"), + ); futm.refocus_tree(); assert_eq!(futm.arena_len(), 1); @@ -667,19 +639,7 @@ mod tests { fn depth_of_test() { let mut futm = FutureMoves::new(Piece::Black, FUTURE_MOVES_CONFIG); - futm.arena.push(Move { - coord: None, - winner: Winner::None, - parent: None, - children: vec![], - value: None, - self_value: 0, - color: Piece::Black, - is_trimmed: false, - tried_children: false, - }); - - futm.update_root_idx_raw(0); + futm.update_from_board(&Board::new()); // child 1 futm.arena @@ -707,19 +667,7 @@ mod tests { fn by_depth_test() { let mut futm = FutureMoves::new(Piece::Black, FUTURE_MOVES_CONFIG); - futm.arena.push(Move { - coord: None, - winner: Winner::None, - parent: None, - children: vec![1], - value: None, - self_value: 0, - color: Piece::Black, - is_trimmed: false, - tried_children: false, - }); - - futm.update_root_idx_raw(0); + futm.update_from_board(&Board::new()); // child 1 futm.arena @@ -775,6 +723,7 @@ mod tests { // seperate variable because we want it to always be executed let update_result = futm.update_from_board(&board); + futm.generate(); // make sure that the arena should only be // regenerated on the first move @@ -808,9 +757,7 @@ mod tests { let mut futm = FutureMoves::new(Piece::White, FUTURE_MOVES_CONFIG); let mut b = Board::new().starting_pos(); - futm.arena - .push(Move::new(None, b, Piece::Black, Piece::White)); - futm.update_root_idx_raw(0); + futm.update_from_board(&Board::new().starting_pos()); b.place((4, 2).into(), Piece::White).unwrap(); @@ -877,7 +824,8 @@ mod tests { let mut futm = FutureMoves::new(Piece::White, FUTURE_MOVES_CONFIG); futm.update_from_board(&board); - futm.extend_layers(); + futm.generate(); + let best_move = futm.best_move(); if let Some(best_move) = best_move {