Move logic changes

This commit is contained in:
Simon Gardling 2025-02-12 21:50:08 -05:00
parent 351953450a
commit a086d75f42
Signed by: titaniumtown
GPG Key ID: 9AB28AC10ECE533D
2 changed files with 8 additions and 19 deletions

View File

@ -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<Self> {
if self.get(i, j).is_some() { if self.get(i, j).is_some() {
return None; return None;
} }
let mut self_copy = *self; let mut self_copy = *self;
self_copy.place_unchecked(i, j, piece); self_copy.place_unchecked(i, j, piece);
let how_many_prop = self_copy.propegate_from(i, j); let how_many_prop = self_copy.propegate_from(i, j);
if how_many_prop == 0 { if how_many_prop == 0 {
return None; return None;
} }
Some((self_copy, how_many_prop))
Some(self_copy)
} }
pub fn would_prop(&self, i: usize, j: usize, piece: Piece) -> bool { 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> { 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 let Some(what_if_result) = self.what_if(i, j, piece) {
if what_if_result.1 > 0 { *self = what_if_result;
*self = what_if_result.0; return Ok(());
return Ok(());
}
} }
Err("move would not propegate") Err("move would not propegate")
} }
@ -203,9 +203,6 @@ impl Board {
/// Propegate piece captures originating from (i, j) /// Propegate piece captures originating from (i, j)
/// 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`
// 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)> {
// Longest chain is (BOARD_SIZE - 2) as there needs to be the two pieces containing it // 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); let mut fill: Vec<(usize, usize)> = Vec::with_capacity((BOARD_SIZE - 2) * 8);

View File

@ -8,12 +8,6 @@ struct Move {
/// `j` position of move /// `j` position of move
j: usize, 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`] state after move is made
board: Board, 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`] // because we use [`Board::what_if`] later and we want to reduce calls to [`Board::propegate_from_dry`]
Board::all_positions() Board::all_positions()
.flat_map(|(i, j)| board.what_if(i, j, color).map(|x| (i, j, x))) .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, i,
j, j,
captured,
color,
board: new_board, board: new_board,
winner: new_board.game_winner(color), winner: new_board.game_winner(color),
parent, parent,
@ -251,7 +243,7 @@ pub struct ComplexAgent {
impl ComplexAgent { impl ComplexAgent {
pub const fn new(color: Piece) -> Self { pub const fn new(color: Piece) -> Self {
const MAX_DEPTH: usize = 7; const MAX_DEPTH: usize = 8;
Self { Self {
color, color,
future_moves: FutureMoves::new(color, MAX_DEPTH), future_moves: FutureMoves::new(color, MAX_DEPTH),