make complexagent so much better

This commit is contained in:
2025-02-06 22:47:29 -05:00
parent 3681fd7e41
commit 669af2a56e
2 changed files with 64 additions and 19 deletions

View File

@@ -6,7 +6,7 @@ use std::{cmp::Ordering, fmt};
pub const BOARD_SIZE: usize = 8;
#[derive(Copy, Clone)]
#[derive(Copy, Clone, PartialEq, Eq)]
pub struct Board {
board: [[Option<Piece>; BOARD_SIZE]; BOARD_SIZE],
}
@@ -78,7 +78,7 @@ impl Board {
Box::new(
(0..BOARD_SIZE)
.flat_map(|i| (0..BOARD_SIZE).map(move |j| (i, j)))
.filter(move |(i, j)| self.what_if(*i, *j, color).is_some()),
.filter(move |(i, j)| self.would_prop(*i, *j, color)),
)
}
@@ -111,6 +111,10 @@ impl Board {
Some((self_copy, how_many_prop))
}
pub fn would_prop(&self, i: usize, j: usize, piece: Piece) -> bool {
!self.propegate_from_dry(i, j, piece).is_empty()
}
pub fn place(&mut self, i: usize, j: usize, piece: Piece) -> Result<(), String> {
if let Some(what_if_result) = self.what_if(i, j, piece) {
if what_if_result.1 > 0 {
@@ -121,15 +125,24 @@ impl Board {
Err("move would not propegate".to_string())
}
/// 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`]
fn propegate_from(&mut self, i: usize, j: usize) -> usize {
// returns if that place is empty
let Some(starting_color) = *self.get(i, j) else {
return 0;
};
let pos_s = self.propegate_from_dry(i, j, starting_color);
let pos_len = pos_s.len();
for (i, j) in pos_s {
self.place_unchecked(i, j, starting_color);
}
pos_len
}
/// 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`]
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) = (
split_from(0, BOARD_SIZE - 1, i),
@@ -152,7 +165,7 @@ impl Board {
// handle diagonals
chains.extend(diag(i, j, 0, 0, BOARD_SIZE - 1, BOARD_SIZE - 1));
let mut captured: usize = 0;
let mut fill: Vec<(usize, usize)> = Vec::new();
for chain in chains {
for (chain_length, &(new_i, new_j)) in chain.iter().enumerate() {
@@ -166,11 +179,10 @@ impl Board {
let Some(history) = chain.get(..chain_length) else {
break;
};
captured += history.len();
// fill all opposite colors with this color
for &(i_o, j_o) in history {
self.place_unchecked(i_o, j_o, starting_color);
fill.push((i_o, j_o));
}
// either the other pieces were replaced, or this was an invalid chain,
// in both cases, the loop needs to be breaked
@@ -178,7 +190,7 @@ impl Board {
}
}
}
captured
fill
}
/// Returns (White score, Black score)