rewrite basically done

This commit is contained in:
2025-02-17 15:02:15 -05:00
parent 87f58e5e40
commit 7049039a77
4 changed files with 54 additions and 43 deletions

View File

@@ -1,9 +1,9 @@
use std::num::NonZero;
use crate::{agent::Agent, board::Board, piece::Piece};
use either::Either;
use crate::{
agent::Agent,
board::{Board, Winner},
piece::Piece,
};
use indicatif::{ProgressBar, ProgressIterator, ProgressStyle};
use num::Integer;
#[derive(Clone, Debug)]
struct Move {
@@ -17,7 +17,7 @@ struct Move {
board: Board,
/// Current winner of the match
winner: Option<Piece>,
winner: Winner,
/// Index of this move's parent
parent: Option<usize>,
@@ -35,15 +35,16 @@ impl Move {
fn compute_self_value(&self, agent_color: Piece, depth: i64) -> i64 {
let mut self_value = self.value;
if self.winner == Some(!agent_color) {
if self.winner == Winner::Player(!agent_color) {
// if this board results in the opponent winning, MAJORLY negatively weigh this move
// NOTE! this branch isn't completely deleted because if so, the bot wouldn't make a move.
// We shouldn't prune branches because we still need to always react to the opponent's moves
self_value = i64::MIN;
} else if self.winner == Some(agent_color) {
} else if self.winner == Winner::Player(agent_color) {
// results in a win for the agent
self_value = i64::MAX;
}
// TODO! handle ties... what should they be valued as? maybe `i64::MAX / 2`?
self_value / depth
}
@@ -78,11 +79,11 @@ impl FutureMoves {
.collect();
for _ in self.current_depth..=(self.max_depth as isize) {
let arena_len = self.arena.len();
let prog_len = next_nodes.len();
next_nodes = next_nodes
.into_iter()
.progress_with(
ProgressBar::new(arena_len as u64).with_style(
ProgressBar::new(prog_len as u64).with_style(
ProgressStyle::with_template(
"Generating children: ({pos}/{len}) {per_sec}",
)
@@ -128,7 +129,8 @@ impl FutureMoves {
// we want to keep only the best move of the agent
if color == self.agent_color {
if new.len() > 1 {
new.sort_by_key(|x| x.compute_self_value(self.agent_color, 1));
// negative, because we want the max value to be at the first index
new.sort_by_key(|x| -x.compute_self_value(self.agent_color, 1));
new.drain(1..);
}
}
@@ -145,7 +147,7 @@ impl FutureMoves {
}
/// Given an index from `self.arena`, what depth is it at? 1-indexed (ROOT IS AT INDEX 1)
fn depth_of(&self, node_idx: usize) -> NonZero<usize> {
fn depth_of(&self, node_idx: usize) -> usize {
let mut depth = 0;
let mut current = Some(node_idx);
while let Some(parent_idx) = current {
@@ -153,8 +155,7 @@ impl FutureMoves {
current = self.arena[parent_idx].parent;
}
// SAFETY! because `node_idx` is of type `usize`, depth will never be 0
unsafe { NonZero::new_unchecked(depth) }
depth
}
fn compute_values(&mut self) {
@@ -163,19 +164,16 @@ impl FutureMoves {
let mut visited = vec![false; self.arena.len()];
for depth in (0..=self.current_depth).rev() {
let nodes_at_depth: Vec<usize> = (0..self.arena.len())
.filter(|&idx| {
if visited[idx] {
false
} else {
visited[idx] = true;
true
}
})
.filter(|&idx| self.depth_of(idx).get() == depth as usize)
.collect();
for idx in 0..self.arena.len() {
if visited[idx] {
continue;
} else {
visited[idx] = true;
}
if self.depth_of(idx) != depth as usize {
continue;
}
for idx in nodes_at_depth {
let self_value = self.arena[idx]
.compute_self_value(self.agent_color, (self.current_depth - depth + 1) as i64);
@@ -230,7 +228,7 @@ impl FutureMoves {
i: 0,
j: 0,
board: *board,
winner: None,
winner: Winner::None,
parent: None,
children: Vec::new(),
value: 0,
@@ -253,7 +251,7 @@ impl FutureMoves {
fn update_root_idx(&mut self, idx: usize) {
self.current_root = Some(idx);
self.current_depth -= self.depth_of(idx).get() as isize;
self.current_depth -= self.depth_of(idx) as isize - 1;
self.prune_unrelated();
self.extend_layers();
self.compute_values();
@@ -264,6 +262,9 @@ impl FutureMoves {
return;
};
// make sure `root` doesn't reference another node
self.arena[root].parent = None;
let mut retain = vec![false; self.arena.len()];
// stack is going to be AT MAXIMUM, the size of the array,
@@ -314,7 +315,7 @@ pub struct ComplexAgent {
impl ComplexAgent {
pub const fn new(color: Piece) -> Self {
const MAX_DEPTH: usize = 10;
const MAX_DEPTH: usize = 17;
Self {
color,
future_moves: FutureMoves::new(color, MAX_DEPTH),