diff --git a/src/board.rs b/src/board.rs index f69baa7..1ce912f 100644 --- a/src/board.rs +++ b/src/board.rs @@ -68,12 +68,10 @@ impl Board { self } - pub fn possible_moves(&self, color: Piece) -> Box + '_> { - Box::new( - (0..BOARD_SIZE) - .flat_map(|i| (0..BOARD_SIZE).map(move |j| (i, j))) - .filter(move |(i, j)| self.would_prop(*i, *j, color)), - ) + pub fn possible_moves(&self, color: Piece) -> impl Iterator + use<'_> { + (0..BOARD_SIZE) + .flat_map(|i| (0..BOARD_SIZE).map(move |j| (i, j))) + .filter(move |(i, j)| self.would_prop(*i, *j, color)) } /// Returns a mutable reference to a place on the [`Board`] @@ -137,8 +135,8 @@ impl Board { /// 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` - // IDEAS: early-exit from each chain so we don't have to call `diag` (which allocs a lot and uses a lot of cycles) // 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)> { // Create all chains from the piece being propegated from in `i` and `j` coordinates let (i_chain, j_chain) = ( diff --git a/src/complexagent.rs b/src/complexagent.rs index db63410..9803a98 100644 --- a/src/complexagent.rs +++ b/src/complexagent.rs @@ -104,28 +104,27 @@ impl FutureMoves { board: &Board, color: Piece, ) -> Vec { - let children: Vec<_> = board - .possible_moves(color) - .flat_map(|(i, j)| board.what_if(i, j, color).map(|x| (i, j, x))) - .map(|(i, j, (new_board, captured))| { - let winner = new_board.game_winner(color); - Move { - i, - j, - captured, - color, - board: new_board, - winner, - parent, - children: Vec::new(), - value: 0, - } - }) - .collect(); - let parent_idx = parent; let start_idx = self.arena.len(); - self.arena.extend(children); + self.arena.extend( + board + .possible_moves(color) + .flat_map(|(i, j)| board.what_if(i, j, color).map(|x| (i, j, x))) + .map(|(i, j, (new_board, captured))| { + let winner = new_board.game_winner(color); + Move { + i, + j, + captured, + color, + board: new_board, + winner, + parent, + children: Vec::new(), + value: 0, + } + }), + ); let new_indices: Vec = (start_idx..self.arena.len()).collect(); if let Some(parent_idx) = parent_idx { @@ -249,7 +248,7 @@ pub struct ComplexAgent { impl ComplexAgent { pub fn new(color: Piece) -> Self { - const MAX_DEPTH: usize = 7; + const MAX_DEPTH: usize = 6; Self { color, future_moves: FutureMoves::new(color, MAX_DEPTH), diff --git a/src/misc.rs b/src/misc.rs index f998bbd..3f6cbe7 100644 --- a/src/misc.rs +++ b/src/misc.rs @@ -6,22 +6,23 @@ where RangeInclusive: Iterator + DoubleEndedIterator, Rev>: Iterator, { - let mut output = [const { Vec::new() }; 2]; - // check that x is in range if min > x || x > max { - return output; + return [const { Vec::new() }; 2]; } - if x > min + T::one() { - let x_lower = x - T::one(); - output[0] = (min..=x_lower).rev().collect(); - } - - if x + T::one() < max { - output[1] = ((x + T::one())..=max).collect(); - } - output + [ + if x > min + T::one() { + (min..=(x - T::one())).rev().collect() + } else { + Vec::new() + }, + if x + T::one() < max { + ((x + T::one())..=max).collect() + } else { + Vec::new() + }, + ] } pub fn diag(i: T, j: T, min_i: T, min_j: T, max_i: T, max_j: T) -> [Vec<(T, T)>; 4] @@ -33,28 +34,13 @@ where let i_chains = split_from(min_i, max_i, i); let j_chains = split_from(min_j, max_j, j); - [ - i_chains[0] + [(0, 0), (1, 1), (1, 0), (0, 1)].map(|(a, b)| { + i_chains[a] .iter() .cloned() - .zip(j_chains[0].clone()) - .collect(), - i_chains[1] - .iter() - .cloned() - .zip(j_chains[1].clone()) - .collect(), - i_chains[1] - .iter() - .cloned() - .zip(j_chains[0].clone()) - .collect(), - i_chains[0] - .iter() - .cloned() - .zip(j_chains[1].clone()) - .collect(), - ] + .zip(j_chains[b].clone()) + .collect() + }) } #[cfg(test)]