diff --git a/benches/future_children.rs b/benches/future_children.rs index b2e2ad6..57a263c 100644 --- a/benches/future_children.rs +++ b/benches/future_children.rs @@ -1,6 +1,6 @@ use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion, Throughput}; use othello::{ - logic::{FutureMoveConfig, FutureMoves}, + logic::{ChildrenEvalMethod, FutureMoveConfig, FutureMoves}, repr::{Board, Piece}, }; @@ -13,6 +13,7 @@ fn extend_layers_no_pruning(depth: usize, arena_size: usize) -> usize { max_arena_size: arena_size, do_not_prune: true, print: false, + children_eval_method: ChildrenEvalMethod::Max, }; let mut fut = FutureMoves::new(Piece::Black, config); fut.set_root_from_board(Board::new().starting_pos()); diff --git a/src/elo.rs b/src/elo.rs index 4c2d2ab..5ec8224 100644 --- a/src/elo.rs +++ b/src/elo.rs @@ -2,7 +2,7 @@ use crate::{ agent::Agent, complexagent::ComplexAgent, game_inner::GameInner, - logic::FutureMoveConfig, + logic::{ChildrenEvalMethod, FutureMoveConfig}, repr::{Board, Piece, Winner}, }; use rayon::iter::{IntoParallelIterator, ParallelIterator}; @@ -20,70 +20,36 @@ pub fn run() { max_arena_size: 1_000_000, do_not_prune: true, print: false, + children_eval_method: ChildrenEvalMethod::Max, }; - let mut arena = PlayerArena::new(vec![ - ( - "ComplexAgentD1".into(), - Box::new(|piece| { - Box::new(ComplexAgent::new( - piece, - FutureMoveConfig { - max_depth: 1, - ..FMV_BASE - }, - )) - }), - ), - ( - "ComplexAgentD2".into(), - Box::new(|piece| { - Box::new(ComplexAgent::new( - piece, - FutureMoveConfig { - max_depth: 2, - ..FMV_BASE - }, - )) - }), - ), - ( - "ComplexAgentD3".into(), - 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 - // }, - // )) - // }), - // ), - ]); + let vec: Vec<(String, Box Box>)> = (1..8) + .flat_map(|d| { + [ + ChildrenEvalMethod::Average, + ChildrenEvalMethod::Max, + ChildrenEvalMethod::Min, + ] + .into_iter() + .map(move |m| -> (String, Box Box>) { + ( + format!("ComplexAgentD{}{:?}", d, m), + Box::new(move |piece| { + Box::new(ComplexAgent::new( + piece, + FutureMoveConfig { + max_depth: d, + children_eval_method: m, + ..FMV_BASE + }, + )) + }), + ) + }) + }) + .collect(); + + let mut arena = PlayerArena::new(vec); arena.prop_arena(1000); diff --git a/src/logic/future_moves.rs b/src/logic/future_moves.rs index 63922d2..40c0c33 100644 --- a/src/logic/future_moves.rs +++ b/src/logic/future_moves.rs @@ -21,7 +21,6 @@ pub struct FutureMoves { config: FutureMoveConfig, } -#[derive(Default)] pub struct FutureMoveConfig { /// Max depth of that we should try and traverse pub max_depth: usize, @@ -43,6 +42,15 @@ pub struct FutureMoveConfig { pub do_not_prune: bool, pub print: bool, + + pub children_eval_method: ChildrenEvalMethod, +} + +#[derive(Debug, Clone, Copy)] +pub enum ChildrenEvalMethod { + Average, + Max, + Min, } impl FutureMoves { @@ -126,21 +134,21 @@ impl FutureMoves { if cf.is_break() { // pruning unfinished level - let by_depth = self.by_depth(0..self.arena.len()); - let mut bdh = HashMap::new(); - for (a, b) in by_depth { - bdh.insert(a, b); - } + // let by_depth = self.by_depth(0..self.arena.len()); + // let mut bdh = HashMap::new(); + // for (a, b) in by_depth { + // bdh.insert(a, b); + // } - for &i in bdh.get(&(self.current_depth + 1)).unwrap_or(&Vec::new()) { - self.remove(i); - } + // for &i in bdh.get(&(self.current_depth + 1)).unwrap_or(&Vec::new()) { + // self.remove(i); + // } - for &i in bdh.get(&self.current_depth).unwrap_or(&Vec::new()) { - self.arena[i].tried_children = false; - } + // for &i in bdh.get(&self.current_depth).unwrap_or(&Vec::new()) { + // self.arena[i].tried_children = false; + // } - self.refocus_tree(); + // self.refocus_tree(); return; } @@ -251,12 +259,21 @@ impl FutureMoves { // 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 idx in nodes { - let children_value = self.arena[idx] + let children_values = self.arena[idx] .children .iter() .flat_map(|&child| self.arena[child].value) - .max() - .unwrap_or(0); + .collect::>(); + + let children_value = match self.config.children_eval_method { + ChildrenEvalMethod::Average => children_values + .into_iter() + .sum::() + .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 should really setup some sort of ELO rating for each commit, playing them against diff --git a/src/logic/mod.rs b/src/logic/mod.rs index e27556a..84e956d 100644 --- a/src/logic/mod.rs +++ b/src/logic/mod.rs @@ -1,4 +1,4 @@ mod board_value; mod future_moves; mod r#move; -pub use future_moves::{FutureMoveConfig, FutureMoves}; +pub use future_moves::{ChildrenEvalMethod, FutureMoveConfig, FutureMoves}; diff --git a/src/main.rs b/src/main.rs index ddc2c35..14080ae 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,6 @@ use elo::run; use game::Game; -use logic::FutureMoveConfig; +use logic::{ChildrenEvalMethod, FutureMoveConfig}; use repr::Piece; mod agent; @@ -25,6 +25,7 @@ fn main() { max_arena_size: 50_000_000, do_not_prune: false, print: true, + children_eval_method: ChildrenEvalMethod::Max, }, ); // let player2 = complexagent::ComplexAgent::new(