add ChildrenEvalMethod

This commit is contained in:
Simon Gardling 2025-03-04 09:50:12 -05:00
parent 4300598b38
commit f28027f93e
Signed by: titaniumtown
GPG Key ID: 9AB28AC10ECE533D
5 changed files with 67 additions and 82 deletions

View File

@ -1,6 +1,6 @@
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion, Throughput}; use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion, Throughput};
use othello::{ use othello::{
logic::{FutureMoveConfig, FutureMoves}, logic::{ChildrenEvalMethod, FutureMoveConfig, FutureMoves},
repr::{Board, Piece}, repr::{Board, Piece},
}; };
@ -13,6 +13,7 @@ fn extend_layers_no_pruning(depth: usize, arena_size: usize) -> usize {
max_arena_size: arena_size, max_arena_size: arena_size,
do_not_prune: true, do_not_prune: true,
print: false, print: false,
children_eval_method: ChildrenEvalMethod::Max,
}; };
let mut fut = FutureMoves::new(Piece::Black, config); let mut fut = FutureMoves::new(Piece::Black, config);
fut.set_root_from_board(Board::new().starting_pos()); fut.set_root_from_board(Board::new().starting_pos());

View File

@ -2,7 +2,7 @@ use crate::{
agent::Agent, agent::Agent,
complexagent::ComplexAgent, complexagent::ComplexAgent,
game_inner::GameInner, game_inner::GameInner,
logic::FutureMoveConfig, logic::{ChildrenEvalMethod, FutureMoveConfig},
repr::{Board, Piece, Winner}, repr::{Board, Piece, Winner},
}; };
use rayon::iter::{IntoParallelIterator, ParallelIterator}; use rayon::iter::{IntoParallelIterator, ParallelIterator};
@ -20,70 +20,36 @@ pub fn run() {
max_arena_size: 1_000_000, max_arena_size: 1_000_000,
do_not_prune: true, do_not_prune: true,
print: false, print: false,
children_eval_method: ChildrenEvalMethod::Max,
}; };
let mut arena = PlayerArena::new(vec![ let vec: Vec<(String, Box<dyn Fn(Piece) -> Box<dyn Agent>>)> = (1..8)
( .flat_map(|d| {
"ComplexAgentD1".into(), [
Box::new(|piece| { ChildrenEvalMethod::Average,
Box::new(ComplexAgent::new( ChildrenEvalMethod::Max,
piece, ChildrenEvalMethod::Min,
FutureMoveConfig { ]
max_depth: 1, .into_iter()
..FMV_BASE .map(move |m| -> (String, Box<dyn Fn(Piece) -> Box<dyn Agent>>) {
}, (
)) format!("ComplexAgentD{}{:?}", d, m),
}), Box::new(move |piece| {
), Box::new(ComplexAgent::new(
( piece,
"ComplexAgentD2".into(), FutureMoveConfig {
Box::new(|piece| { max_depth: d,
Box::new(ComplexAgent::new( children_eval_method: m,
piece, ..FMV_BASE
FutureMoveConfig { },
max_depth: 2, ))
..FMV_BASE }),
}, )
)) })
}), })
), .collect();
(
"ComplexAgentD3".into(), let mut arena = PlayerArena::new(vec);
Box::new(|piece| {
Box::new(ComplexAgent::new(
piece,
FutureMoveConfig {
max_depth: 3,
..FMV_BASE
},
))
}),
),
(
"ComplexAgentD4".into(),
Box::new(|piece| {
Box::new(ComplexAgent::new(
piece,
FutureMoveConfig {
max_depth: 4,
..FMV_BASE
},
))
}),
),
// (
// "ComplexAgentD8".into(),
// Box::new(|piece| {
// Box::new(ComplexAgent::new(
// piece,
// FutureMoveConfig {
// max_depth: 8,
// ..FMV_BASE
// },
// ))
// }),
// ),
]);
arena.prop_arena(1000); arena.prop_arena(1000);

View File

@ -21,7 +21,6 @@ pub struct FutureMoves {
config: FutureMoveConfig, config: FutureMoveConfig,
} }
#[derive(Default)]
pub struct FutureMoveConfig { pub struct FutureMoveConfig {
/// Max depth of that we should try and traverse /// Max depth of that we should try and traverse
pub max_depth: usize, pub max_depth: usize,
@ -43,6 +42,15 @@ pub struct FutureMoveConfig {
pub do_not_prune: bool, pub do_not_prune: bool,
pub print: bool, pub print: bool,
pub children_eval_method: ChildrenEvalMethod,
}
#[derive(Debug, Clone, Copy)]
pub enum ChildrenEvalMethod {
Average,
Max,
Min,
} }
impl FutureMoves { impl FutureMoves {
@ -126,21 +134,21 @@ impl FutureMoves {
if cf.is_break() { if cf.is_break() {
// pruning unfinished level // pruning unfinished level
let by_depth = self.by_depth(0..self.arena.len()); // let by_depth = self.by_depth(0..self.arena.len());
let mut bdh = HashMap::new(); // let mut bdh = HashMap::new();
for (a, b) in by_depth { // for (a, b) in by_depth {
bdh.insert(a, b); // bdh.insert(a, b);
} // }
for &i in bdh.get(&(self.current_depth + 1)).unwrap_or(&Vec::new()) { // for &i in bdh.get(&(self.current_depth + 1)).unwrap_or(&Vec::new()) {
self.remove(i); // self.remove(i);
} // }
for &i in bdh.get(&self.current_depth).unwrap_or(&Vec::new()) { // for &i in bdh.get(&self.current_depth).unwrap_or(&Vec::new()) {
self.arena[i].tried_children = false; // self.arena[i].tried_children = false;
} // }
self.refocus_tree(); // self.refocus_tree();
return; return;
} }
@ -251,12 +259,21 @@ impl FutureMoves {
// reversed so we build up the value of the closest (in time) moves from the future // reversed so we build up the value of the closest (in time) moves from the future
for (_, nodes) in by_depth_vec.into_iter().rev() { for (_, nodes) in by_depth_vec.into_iter().rev() {
for idx in nodes { for idx in nodes {
let children_value = self.arena[idx] let children_values = self.arena[idx]
.children .children
.iter() .iter()
.flat_map(|&child| self.arena[child].value) .flat_map(|&child| self.arena[child].value)
.max() .collect::<Vec<_>>();
.unwrap_or(0);
let children_value = match self.config.children_eval_method {
ChildrenEvalMethod::Average => children_values
.into_iter()
.sum::<i128>()
.checked_div(self.arena[idx].children.len() as i128),
ChildrenEvalMethod::Max => children_values.into_iter().max(),
ChildrenEvalMethod::Min => children_values.into_iter().min(),
}
.unwrap_or(0);
// we use `depth` and divided `self_value` by it, idk if this is worth it // we use `depth` and divided `self_value` by it, idk if this is worth it
// we should really setup some sort of ELO rating for each commit, playing them against // we should really setup some sort of ELO rating for each commit, playing them against

View File

@ -1,4 +1,4 @@
mod board_value; mod board_value;
mod future_moves; mod future_moves;
mod r#move; mod r#move;
pub use future_moves::{FutureMoveConfig, FutureMoves}; pub use future_moves::{ChildrenEvalMethod, FutureMoveConfig, FutureMoves};

View File

@ -1,6 +1,6 @@
use elo::run; use elo::run;
use game::Game; use game::Game;
use logic::FutureMoveConfig; use logic::{ChildrenEvalMethod, FutureMoveConfig};
use repr::Piece; use repr::Piece;
mod agent; mod agent;
@ -25,6 +25,7 @@ fn main() {
max_arena_size: 50_000_000, max_arena_size: 50_000_000,
do_not_prune: false, do_not_prune: false,
print: true, print: true,
children_eval_method: ChildrenEvalMethod::Max,
}, },
); );
// let player2 = complexagent::ComplexAgent::new( // let player2 = complexagent::ComplexAgent::new(