more elo testing

This commit is contained in:
Simon Gardling 2025-03-04 16:23:34 -05:00
parent c0224f1a05
commit 013f81cd79
Signed by: titaniumtown
GPG Key ID: 9AB28AC10ECE533D
2 changed files with 66 additions and 23 deletions

View File

@ -6,6 +6,7 @@ use crate::{
repr::{Board, Piece, Winner}, repr::{Board, Piece, Winner},
}; };
use indicatif::{ParallelProgressIterator, ProgressStyle}; use indicatif::{ParallelProgressIterator, ProgressStyle};
use rand::seq::SliceRandom;
use rayon::iter::{IntoParallelIterator, ParallelIterator}; use rayon::iter::{IntoParallelIterator, ParallelIterator};
use skillratings::{ use skillratings::{
elo::{elo, EloConfig, EloRating}, elo::{elo, EloConfig, EloRating},
@ -24,30 +25,49 @@ pub fn run() {
children_eval_method: ChildrenEvalMethod::Average, children_eval_method: ChildrenEvalMethod::Average,
}; };
let vec: Vec<(String, Box<dyn Fn(Piece) -> Box<dyn Agent>>)> = (5..=6) let configs = (1..=6)
.flat_map(move |d| { .map(move |d| FutureMoveConfig {
// -> (String, Box<dyn Fn(Piece) -> Box<dyn Agent>>)
[true, false].map(move |p| -> (String, Box<dyn Fn(Piece) -> Box<dyn Agent>>) {
(
format!("ComplexAgentD{}P{}", d, p),
Box::new(move |piece| {
Box::new(ComplexAgent::new(
piece,
FutureMoveConfig {
max_depth: d, max_depth: d,
do_not_prune: p,
..FMV_BASE ..FMV_BASE
}, })
)) .flat_map(move |prev_c| {
}), // create children which enable, and disable pruning
[true, false].map(move |do_not_prune| FutureMoveConfig {
do_not_prune,
..prev_c
})
})
.flat_map(move |prev_c| {
if prev_c.do_not_prune {
// do not bother making configs where do_not_prune is true
// as top_k_children does nothing when pruning is skipped
return vec![prev_c];
}
// different values of top_k_children
[1, 2, 3]
.map(move |top_k_children| FutureMoveConfig {
top_k_children,
..prev_c
})
.to_vec()
});
let vec: Vec<(String, Box<dyn Fn(Piece) -> Box<dyn Agent>>)> = configs
.into_iter()
.map(
move |config| -> (String, Box<dyn Fn(Piece) -> Box<dyn Agent>>) {
(
format!("{}", config),
Box::new(move |piece| Box::new(ComplexAgent::new(piece, config))),
)
},
) )
})
})
.collect(); .collect();
let mut arena = PlayerArena::new(vec); let mut arena = PlayerArena::new(vec);
arena.prop_arena(10); arena.prop_arena(1);
println!("{}", arena); println!("{}", arena);
} }
@ -87,7 +107,7 @@ impl PlayerArena {
} }
fn play(&mut self, pairs: &[(usize, usize)]) { fn play(&mut self, pairs: &[(usize, usize)]) {
pairs let mut created_pairs = pairs
.iter() .iter()
.map(|&(i, j)| { .map(|&(i, j)| {
( (
@ -95,13 +115,17 @@ impl PlayerArena {
Self::create_agents(&self.players[i].1, &self.players[j].1), Self::create_agents(&self.players[i].1, &self.players[j].1),
) )
}) })
.collect::<Vec<_>>() .collect::<Vec<_>>();
// shuffle for consistency
created_pairs.shuffle(&mut rand::rng());
// after the agents are created, we can multithread the games being played // after the agents are created, we can multithread the games being played
created_pairs
.into_par_iter() .into_par_iter()
.progress_with_style( .progress_with_style(
ProgressStyle::with_template("[{elapsed_precise}] {pos:>7}/{len:7} ETA: {eta}") ProgressStyle::with_template("[{elapsed_precise}] {pos:>7}/{len:7} ETA: {eta}")
.expect("invalid ProgressStyle") .expect("invalid ProgressStyle"),
.progress_chars("##-"),
) )
.map(|((i, j), (p1, p2))| (i, j, Self::play_two_inner(p1, p2))) .map(|((i, j), (p1, p2))| (i, j, Self::play_two_inner(p1, p2)))
.collect::<Vec<_>>() .collect::<Vec<_>>()

View File

@ -21,6 +21,7 @@ pub struct FutureMoves {
config: FutureMoveConfig, config: FutureMoveConfig,
} }
#[derive(Copy, Clone)]
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,
@ -46,6 +47,24 @@ pub struct FutureMoveConfig {
pub children_eval_method: ChildrenEvalMethod, pub children_eval_method: ChildrenEvalMethod,
} }
impl std::fmt::Display for FutureMoveConfig {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "D{} ", self.max_depth)?;
write!(f, "MD{} ", self.min_arena_depth)?;
write!(f, "K{} ", self.top_k_children)?;
write!(f, "UM{} ", self.up_to_minus)?;
if self.max_arena_size == usize::MAX {
write!(f, "SMAX ")?;
} else {
write!(f, "S{} ", self.max_arena_size)?;
}
write!(f, "P{} ", !self.do_not_prune)?;
write!(f, "C{:?}", self.children_eval_method)?;
Ok(())
}
}
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub enum ChildrenEvalMethod { pub enum ChildrenEvalMethod {
/// Best (by far) strat compared to Max or Min /// Best (by far) strat compared to Max or Min