general code improvements

This commit is contained in:
Simon Gardling 2025-02-10 14:21:06 -05:00
parent cb5f9d075d
commit bd5cc2ea52
Signed by: titaniumtown
GPG Key ID: 9AB28AC10ECE533D
3 changed files with 43 additions and 60 deletions

View File

@ -68,12 +68,10 @@ impl Board {
self self
} }
pub fn possible_moves(&self, color: Piece) -> Box<dyn Iterator<Item = (usize, usize)> + '_> { pub fn possible_moves(&self, color: Piece) -> impl Iterator<Item = (usize, usize)> + use<'_> {
Box::new( (0..BOARD_SIZE)
(0..BOARD_SIZE) .flat_map(|i| (0..BOARD_SIZE).map(move |j| (i, j)))
.flat_map(|i| (0..BOARD_SIZE).map(move |j| (i, j))) .filter(move |(i, j)| self.would_prop(*i, *j, color))
.filter(move |(i, j)| self.would_prop(*i, *j, color)),
)
} }
/// Returns a mutable reference to a place on the [`Board`] /// 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 /// DO NOT USE THIS ALONE, this should be called as a part of
/// [`Board::place`] or [`Board::place_and_prop_unchecked`] /// [`Board::place`] or [`Board::place_and_prop_unchecked`]
// TODO! this function is responsible for approx 64% of the time spent computing moves in `ComplexAgent` // 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 // 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)> { 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 // Create all chains from the piece being propegated from in `i` and `j` coordinates
let (i_chain, j_chain) = ( let (i_chain, j_chain) = (

View File

@ -104,28 +104,27 @@ impl FutureMoves {
board: &Board, board: &Board,
color: Piece, color: Piece,
) -> Vec<usize> { ) -> Vec<usize> {
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 parent_idx = parent;
let start_idx = self.arena.len(); 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<usize> = (start_idx..self.arena.len()).collect(); let new_indices: Vec<usize> = (start_idx..self.arena.len()).collect();
if let Some(parent_idx) = parent_idx { if let Some(parent_idx) = parent_idx {
@ -249,7 +248,7 @@ pub struct ComplexAgent {
impl ComplexAgent { impl ComplexAgent {
pub fn new(color: Piece) -> Self { pub fn new(color: Piece) -> Self {
const MAX_DEPTH: usize = 7; const MAX_DEPTH: usize = 6;
Self { Self {
color, color,
future_moves: FutureMoves::new(color, MAX_DEPTH), future_moves: FutureMoves::new(color, MAX_DEPTH),

View File

@ -6,22 +6,23 @@ where
RangeInclusive<T>: Iterator<Item = T> + DoubleEndedIterator, RangeInclusive<T>: Iterator<Item = T> + DoubleEndedIterator,
Rev<RangeInclusive<T>>: Iterator<Item = T>, Rev<RangeInclusive<T>>: Iterator<Item = T>,
{ {
let mut output = [const { Vec::new() }; 2];
// check that x is in range // check that x is in range
if min > x || x > max { if min > x || x > max {
return output; return [const { Vec::new() }; 2];
} }
if x > min + T::one() { [
let x_lower = x - T::one(); if x > min + T::one() {
output[0] = (min..=x_lower).rev().collect(); (min..=(x - T::one())).rev().collect()
} } else {
Vec::new()
if x + T::one() < max { },
output[1] = ((x + T::one())..=max).collect(); if x + T::one() < max {
} ((x + T::one())..=max).collect()
output } else {
Vec::new()
},
]
} }
pub fn diag<T>(i: T, j: T, min_i: T, min_j: T, max_i: T, max_j: T) -> [Vec<(T, T)>; 4] pub fn diag<T>(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 i_chains = split_from(min_i, max_i, i);
let j_chains = split_from(min_j, max_j, j); let j_chains = split_from(min_j, max_j, j);
[ [(0, 0), (1, 1), (1, 0), (0, 1)].map(|(a, b)| {
i_chains[0] i_chains[a]
.iter() .iter()
.cloned() .cloned()
.zip(j_chains[0].clone()) .zip(j_chains[b].clone())
.collect(), .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(),
]
} }
#[cfg(test)] #[cfg(test)]