From 517e54dade0e7fb6d30007be6f79fb04fd96e095 Mon Sep 17 00:00:00 2001 From: Simon Gardling Date: Sun, 20 Apr 2025 01:43:00 -0400 Subject: [PATCH] simplify move creation and allow switching between value methods --- src/logic/future_moves.rs | 69 ++++++++++++++++++++------------------- src/logic/move.rs | 10 ++++-- 2 files changed, 43 insertions(+), 36 deletions(-) diff --git a/src/logic/future_moves.rs b/src/logic/future_moves.rs index fbb5d8d..6ab50e1 100644 --- a/src/logic/future_moves.rs +++ b/src/logic/future_moves.rs @@ -101,6 +101,8 @@ pub enum ChildrenEvalMethod { /// Best so far? MinMax, + + MinMaxFlat, } impl Default for ChildrenEvalMethod { @@ -225,6 +227,19 @@ impl FutureMoves { false } + fn create_move(&self, coord: MoveCoord, board: Board, color: Piece) -> Move { + Move::new( + coord, + board, + color, + self.agent_color, + !matches!( + self.config.children_eval_method, + ChildrenEvalMethod::MinMaxFlat + ), + ) + } + fn generate_children_raw(&self, parent_idx: usize) -> Vec { let parent = &self.arena[parent_idx]; @@ -241,15 +256,13 @@ impl FutureMoves { .what_if(coord, new_color) .map(move |x| (coord, x)) }) - .map(|(coord, new_board)| { - Move::new(Some(coord), new_board, new_color, self.agent_color) - }) + .map(|(coord, new_board)| self.create_move(Some(coord), new_board, new_color)) .collect(); // if there are no moves to take, making // no move is also an option! if new.is_empty() { - new.push(Move::new(None, parent_board, new_color, self.agent_color)); + new.push(self.create_move(None, parent_board, new_color)); } for m in new.iter_mut() { @@ -334,7 +347,7 @@ impl FutureMoves { } } - ChildrenEvalMethod::MinMax => { + ChildrenEvalMethod::MinMax | ChildrenEvalMethod::MinMaxFlat => { if self.arena[idx].color == self.agent_color { // get best (for the adversary) enemy play // this assumes the adversary is playing optimally @@ -446,7 +459,7 @@ impl FutureMoves { } fn rebuild_from_board(&mut self, board: Board) { - self.arena = vec![Move::new(None, board, !self.agent_color, self.agent_color)]; + self.arena = vec![self.create_move(None, board, !self.agent_color)]; self.current_root = Some(0); self.current_depth = 0; self.board = board; @@ -653,25 +666,21 @@ mod tests { // child 1 futm.arena - .push(Move::new(None, Board::new(), Piece::White, Piece::Black)); + .push(futm.create_move(None, Board::new(), Piece::White)); futm.set_parent_child(0, 1); // dummy (2) - futm.arena.push(Move::new( - Some((9, 9).into()), - Board::new(), - Piece::White, - Piece::Black, - )); + futm.arena + .push(futm.create_move(Some((9, 9).into()), Board::new(), Piece::White)); // 3 futm.arena - .push(Move::new(None, Board::new(), Piece::White, Piece::Black)); + .push(futm.create_move(None, Board::new(), Piece::White)); futm.set_parent_child(0, 3); // 4 futm.arena - .push(Move::new(None, Board::new(), Piece::White, Piece::Black)); + .push(futm.create_move(None, Board::new(), Piece::White)); futm.set_parent_child(0, 4); assert_eq!(futm.arena_len(), 5); @@ -720,20 +729,20 @@ mod tests { // child 1 futm.arena - .push(Move::new(None, Board::new(), Piece::White, Piece::Black)); + .push(futm.create_move(None, Board::new(), Piece::White)); futm.set_parent_child(0, 1); // dummy futm.arena - .push(Move::new(None, Board::new(), Piece::White, Piece::Black)); + .push(futm.create_move(None, Board::new(), Piece::White)); futm.arena - .push(Move::new(None, Board::new(), Piece::White, Piece::Black)); + .push(futm.create_move(None, Board::new(), Piece::White)); futm.set_parent_child(1, 3); futm.arena - .push(Move::new(None, Board::new(), Piece::White, Piece::Black)); + .push(futm.create_move(None, Board::new(), Piece::White)); futm.set_parent_child(0, 4); @@ -748,15 +757,15 @@ mod tests { // child 1 futm.arena - .push(Move::new(None, Board::new(), Piece::White, Piece::Black)); + .push(futm.create_move(None, Board::new(), Piece::White)); futm.set_parent_child(0, 1); // dummy futm.arena - .push(Move::new(None, Board::new(), Piece::White, Piece::Black)); + .push(futm.create_move(None, Board::new(), Piece::White)); futm.arena - .push(Move::new(None, Board::new(), Piece::White, Piece::Black)); + .push(futm.create_move(None, Board::new(), Piece::White)); futm.set_parent_child(1, 3); assert_eq!( @@ -838,12 +847,8 @@ mod tests { b.place((4, 5).into(), Piece::White).unwrap(); - futm.arena.push(Move::new( - Some((4, 5).into()), - b, - Piece::White, - Piece::White, - )); + futm.arena + .push(futm.create_move(Some((4, 5).into()), b, Piece::White)); futm.set_parent_child(0, 1); @@ -855,12 +860,8 @@ mod tests { b.place((5, 3).into(), Piece::Black).unwrap(); - futm.arena.push(Move::new( - Some((5, 3).into()), - b, - Piece::Black, - Piece::White, - )); + futm.arena + .push(futm.create_move(Some((5, 3).into()), b, Piece::Black)); futm.set_parent_child(1, 2); assert_eq!( diff --git a/src/logic/move.rs b/src/logic/move.rs index 5a23f7d..7b87f49 100644 --- a/src/logic/move.rs +++ b/src/logic/move.rs @@ -36,7 +36,13 @@ pub struct Move { } impl Move { - pub fn new(coord: MoveCoord, board: Board, color: Piece, agent_color: Piece) -> Self { + pub fn new( + coord: MoveCoord, + board: Board, + color: Piece, + agent_color: Piece, + use_weighted_bvm: bool, + ) -> Self { let mut m = Move { coord, winner: board.game_winner(), @@ -47,7 +53,7 @@ impl Move { is_trimmed: false, self_value: 0, }; - m.self_value = m.compute_self_value(agent_color, &board, true); + m.self_value = m.compute_self_value(agent_color, &board, use_weighted_bvm); m }