diff --git a/src/board.rs b/src/board.rs index e66eb0b..cbefd62 100644 --- a/src/board.rs +++ b/src/board.rs @@ -159,17 +159,19 @@ impl Board { } } - pub fn what_if(&self, i: usize, j: usize, piece: Piece) -> Option<(Self, usize)> { + pub fn what_if(&self, i: usize, j: usize, piece: Piece) -> Option { if self.get(i, j).is_some() { return None; } + let mut self_copy = *self; self_copy.place_unchecked(i, j, piece); let how_many_prop = self_copy.propegate_from(i, j); if how_many_prop == 0 { return None; } - Some((self_copy, how_many_prop)) + + Some(self_copy) } pub fn would_prop(&self, i: usize, j: usize, piece: Piece) -> bool { @@ -178,10 +180,8 @@ impl Board { pub fn place(&mut self, i: usize, j: usize, piece: Piece) -> Result<(), &'static str> { if let Some(what_if_result) = self.what_if(i, j, piece) { - if what_if_result.1 > 0 { - *self = what_if_result.0; - return Ok(()); - } + *self = what_if_result; + return Ok(()); } Err("move would not propegate") } @@ -203,9 +203,6 @@ impl Board { /// Propegate piece captures originating from (i, j) /// DO NOT USE THIS ALONE, this should be called as a part of /// [`Board::place`] or [`Board::place_and_prop_unchecked`] - // TODO! this function is responsible for approx 64% of the time spent computing moves in `ComplexAgent` - // NOTE! got it down to 24.86% (61.1% decrease) with allocator optimizations - // IDEAS: early-exit from each chain so we don't have to call `diag` (which allocs a lot and uses a lot of cycles) fn propegate_from_dry(&self, i: usize, j: usize, starting_color: Piece) -> Vec<(usize, usize)> { // Longest chain is (BOARD_SIZE - 2) as there needs to be the two pieces containing it let mut fill: Vec<(usize, usize)> = Vec::with_capacity((BOARD_SIZE - 2) * 8); diff --git a/src/complexagent.rs b/src/complexagent.rs index 12aaabb..1132f8d 100644 --- a/src/complexagent.rs +++ b/src/complexagent.rs @@ -8,12 +8,6 @@ struct Move { /// `j` position of move j: usize, - /// how many pieces are captured by this move - captured: usize, - - /// Turn this move was made on - color: Piece, - /// [`Board`] state after move is made board: Board, @@ -116,11 +110,9 @@ impl FutureMoves { // because we use [`Board::what_if`] later and we want to reduce calls to [`Board::propegate_from_dry`] Board::all_positions() .flat_map(|(i, j)| board.what_if(i, j, color).map(|x| (i, j, x))) - .map(|(i, j, (new_board, captured))| Move { + .map(|(i, j, new_board)| Move { i, j, - captured, - color, board: new_board, winner: new_board.game_winner(color), parent, @@ -251,7 +243,7 @@ pub struct ComplexAgent { impl ComplexAgent { pub const fn new(color: Piece) -> Self { - const MAX_DEPTH: usize = 7; + const MAX_DEPTH: usize = 8; Self { color, future_moves: FutureMoves::new(color, MAX_DEPTH),