code improvements

This commit is contained in:
Simon Gardling 2025-02-09 01:11:02 -05:00
parent 19039f550b
commit f1d81ef05e
Signed by: titaniumtown
GPG Key ID: 9AB28AC10ECE533D

View File

@ -7,13 +7,21 @@ pub struct ComplexAgent {
#[derive(Clone)] #[derive(Clone)]
struct Move { struct Move {
/// `i` value of move
i: usize, i: usize,
/// `j` value of move
j: usize, j: usize,
/// how many pieces were captured
captured: usize, captured: usize,
/// Turn
color: Piece, color: Piece,
/// [`Board`] after move is made
board: Board, board: Board,
/// Winner of the match
winner: Option<Piece>, winner: Option<Piece>,
/// Move's parent index in [`FutureMoves`]
parent_index: Option<usize>, parent_index: Option<usize>,
/// Value determined in [`Move::compute_self_value`]
value: i64, value: i64,
} }
@ -37,21 +45,30 @@ impl Move {
} }
} }
impl ComplexAgent { struct FutureMoves {
#[allow(dead_code)] /// Contains a Vector of Vectors, each top-level vector of index `i`
pub const fn new(color: Piece) -> Self { /// represents moves at depth `i` the contents of that vector are the
Self { color } /// possible moves
} inner: Vec<Vec<Move>>,
/// Color w.r.t
color: Piece,
}
fn generate_layers(&self, board: &Board, depth: usize) -> Vec<Vec<Move>> { impl FutureMoves {
let mut layers = Vec::with_capacity(depth); fn from_problem_space(board: &Board, color: Piece, parent_index: Option<usize>) -> Vec<Move> {
let initial_moves: Vec<Move> = problem_space(board, self.color) problem_space(board, color)
.map(|mut m| { .map(|mut m| {
m.parent_index = None; m.parent_index = parent_index;
m.value = 0; m.value = 0;
m m
}) })
.collect(); .collect::<Vec<_>>()
}
pub fn generate(color: Piece, board: &Board, depth: usize) -> Self {
let mut layers = Vec::with_capacity(depth);
let initial_moves: Vec<Move> = Self::from_problem_space(board, color, None);
layers.push(initial_moves); layers.push(initial_moves);
for current_depth in 0..depth { for current_depth in 0..depth {
@ -61,42 +78,43 @@ impl ComplexAgent {
} }
let next_moves: Vec<Move> = current_layer let next_moves: Vec<Move> = current_layer
.par_iter() .into_iter()
.enumerate() .enumerate()
.flat_map(|(parent_idx, parent_move)| { .flat_map(|(parent_idx, parent_move)| {
let opponent_color = !parent_move.color; Self::from_problem_space(
problem_space(&parent_move.board, opponent_color) &parent_move.board,
.map(|mut m| { !parent_move.color,
m.parent_index = Some(parent_idx); Some(parent_idx),
m.value = 0; )
m
})
.collect::<Vec<_>>()
}) })
.collect(); .collect();
layers.push(next_moves); layers.push(next_moves);
} }
self.compute_values(&mut layers); let mut tmp = Self {
layers inner: layers,
color,
};
tmp.compute_values();
tmp
} }
fn compute_values(&self, layers: &mut [Vec<Move>]) { fn compute_values(&mut self) {
let agent_color = self.color; let layers_len = self.inner.len();
let layers_len = layers.len(); for depth in (0..layers_len).rev() {
for depth in (0..layers.len()).rev() {
let layer_depth_1: Vec<Move> = if depth + 1 < layers_len { let layer_depth_1: Vec<Move> = if depth + 1 < layers_len {
layers[depth + 1].clone() self.inner[depth + 1].clone()
} else { } else {
Vec::new() Vec::new()
}; };
let current_layer = &mut layers[depth]; let current_layer = &mut self.inner[depth];
current_layer.par_iter_mut().for_each(|mv| { current_layer.par_iter_mut().for_each(|mv| {
let self_value = mv.compute_self_value(agent_color, depth + 1); let self_value = mv.compute_self_value(self.color, depth + 1);
let children_value = if depth + 1 < layers_len { let children_value = if depth + 1 < layers_len {
// calculate average value of each move
layer_depth_1 layer_depth_1
.iter() .iter()
.filter(|child| child.parent_index == Some(mv.parent_index.unwrap_or(0))) .filter(|child| child.parent_index == Some(mv.parent_index.unwrap_or(0)))
@ -110,14 +128,29 @@ impl ComplexAgent {
}); });
} }
} }
pub fn inner(&self) -> &[Vec<Move>] {
&self.inner
}
}
impl ComplexAgent {
#[allow(dead_code)]
pub const fn new(color: Piece) -> Self {
Self { color }
}
} }
impl Agent for ComplexAgent { impl Agent for ComplexAgent {
fn next_move(&mut self, board: &Board) -> Option<(usize, usize)> { fn next_move(&mut self, board: &Board) -> Option<(usize, usize)> {
const LOOPS: usize = 5; const LOOPS: usize = 5;
let layers = self.generate_layers(board, LOOPS); let layers = FutureMoves::generate(self.color, board, LOOPS);
println!("len: {}", layers.iter().map(Vec::len).sum::<usize>()); println!(
layers[0] "# of moves {} deep: {}",
LOOPS,
layers.inner().iter().map(Vec::len).sum::<usize>()
);
layers.inner()[0]
.par_iter() .par_iter()
.max_by_key(|m| m.value) .max_by_key(|m| m.value)
.map(|m| (m.i, m.j)) .map(|m| (m.i, m.j))