This commit is contained in:
Simon Gardling 2025-03-02 23:36:40 -05:00
parent 1dd1f3da25
commit a9dd85762d
Signed by: titaniumtown
GPG Key ID: 9AB28AC10ECE533D
3 changed files with 159 additions and 27 deletions

View File

@ -12,6 +12,7 @@ fn extend_layers_no_pruning(depth: usize, arena_size: usize) -> usize {
up_to_minus: 4, up_to_minus: 4,
max_arena_size: arena_size, max_arena_size: arena_size,
do_not_prune: true, do_not_prune: true,
print: false,
}; };
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

@ -11,38 +11,131 @@ use skillratings::{
}; };
pub fn run() { pub fn run() {
const FMV_BASE: FutureMoveConfig = FutureMoveConfig {
max_depth: 20,
min_arena_depth: 14,
top_k_children: 2,
up_to_minus: 10,
max_arena_size: 5_000_000,
do_not_prune: false,
print: false,
};
let mut arena = PlayerArena::new(vec![ let mut arena = PlayerArena::new(vec![
( (
"RandomAgent".into(), "RandomAgent".into(),
Box::new(|piece| Box::new(RandomAgent::new(piece))), Box::new(|piece| Box::new(RandomAgent::new(piece))),
1,
), ),
( (
"ComplexAgentBasic".into(), "ComplexAgent100K".into(),
Box::new(|piece| { Box::new(|piece| {
Box::new(ComplexAgent::new( Box::new(ComplexAgent::new(
piece, piece,
FutureMoveConfig { FutureMoveConfig {
max_depth: 20,
min_arena_depth: 14,
top_k_children: 2,
up_to_minus: 10,
max_arena_size: 100_000, max_arena_size: 100_000,
do_not_prune: false, ..FMV_BASE
print: false,
}, },
)) ))
}), }),
1,
),
(
"ComplexAgent500K".into(),
Box::new(|piece| {
Box::new(ComplexAgent::new(
piece,
FutureMoveConfig {
max_arena_size: 500_000,
..FMV_BASE
},
))
}),
1,
),
(
"ComplexAgent1M".into(),
Box::new(|piece| {
Box::new(ComplexAgent::new(
piece,
FutureMoveConfig {
max_arena_size: 1_000_000,
..FMV_BASE
},
))
}),
1,
),
// NO PRUNING :
(
"ComplexAgent100K_NOPRUNE".into(),
Box::new(|piece| {
Box::new(ComplexAgent::new(
piece,
FutureMoveConfig {
max_arena_size: 100_000,
do_not_prune: true,
..FMV_BASE
},
))
}),
1,
),
(
"ComplexAgent500K_NOPRUNE".into(),
Box::new(|piece| {
Box::new(ComplexAgent::new(
piece,
FutureMoveConfig {
max_arena_size: 500_000,
do_not_prune: true,
..FMV_BASE
},
))
}),
1,
),
(
"ComplexAgent1M_NOPRUNE".into(),
Box::new(|piece| {
Box::new(ComplexAgent::new(
piece,
FutureMoveConfig {
max_arena_size: 1_000_000,
do_not_prune: true,
..FMV_BASE
},
))
}),
1,
), ),
]); ]);
for _ in 0..10 {
arena.play_two(0, 1); // for _ in 0..100 {
// arena.prop_arena();
// }
for _ in 0..20 {
arena.play_all_against(0);
} }
// for _ in 0..2 {
// arena.play_two(1, 2);
// }
println!("{}", arena); println!("{}", arena);
} }
pub struct PlayerArena { pub struct PlayerArena {
players: Vec<(String, Box<dyn Fn(Piece) -> Box<dyn Agent>>, EloRating)>, /// Name, Creator, Elo, freq (mod)
players: Vec<(
String,
Box<dyn Fn(Piece) -> Box<dyn Agent>>,
EloRating,
usize,
)>,
freq_map: Vec<usize>,
} }
impl std::fmt::Display for PlayerArena { impl std::fmt::Display for PlayerArena {
@ -64,23 +157,68 @@ impl std::fmt::Display for PlayerArena {
} }
impl PlayerArena { impl PlayerArena {
pub fn new(players: Vec<(String, Box<dyn Fn(Piece) -> Box<dyn Agent>>)>) -> Self { pub fn new(players: Vec<(String, Box<dyn Fn(Piece) -> Box<dyn Agent>>, usize)>) -> Self {
let len = players.len();
Self { Self {
players: players players: players
.into_iter() .into_iter()
.zip([EloRating::new()].into_iter().cycle()) .zip([EloRating::new()].into_iter().cycle())
.map(|((a, b), c)| (a, b, c)) .map(|((a, b, d), c)| (a, b, c, d))
.collect(), .collect(),
freq_map: [0].repeat(len).to_vec(),
}
}
fn play_all_against(&mut self, i: usize) {
for j in 0..self.players.len() {
if i == j {
continue;
}
self.freq_map[i] += 1;
self.freq_map[j] += 1;
if self.freq_map[i] % self.players[i].3 != 0 {
continue;
}
if self.freq_map[j] % self.players[j].3 != 0 {
continue;
}
self.play_two(i, j);
}
}
fn prop_arena(&mut self) {
for i in 0..self.players.len() {
self.play_all_against(i);
} }
} }
fn play_two(&mut self, player1: usize, player2: usize) { fn play_two(&mut self, player1: usize, player2: usize) {
let result = GameInner::new( println!(
self.players[player1].1(Piece::Black), "{} vs {}...",
self.players[player2].1(Piece::White), self.players[player1].0, self.players[player2].0
false, );
)
.loop_until_result(); let (np1, np2) = Self::play_two_inner(
&self.players[player1].1,
&self.players[player2].1,
&self.players[player1].2,
&self.players[player2].2,
);
self.players[player1].2 = np1;
self.players[player2].2 = np2;
}
fn play_two_inner(
player_1_fn: &Box<dyn Fn(Piece) -> Box<dyn Agent>>,
player_2_fn: &Box<dyn Fn(Piece) -> Box<dyn Agent>>,
player_1_elo: &EloRating,
player_2_elo: &EloRating,
) -> (EloRating, EloRating) {
let result = GameInner::new(player_1_fn(Piece::Black), player_2_fn(Piece::White), false)
.loop_until_result();
let outcome = match result { let outcome = match result {
Winner::Player(piece) => match piece { Winner::Player(piece) => match piece {
Piece::Black => Outcomes::WIN, Piece::Black => Outcomes::WIN,
@ -89,13 +227,7 @@ impl PlayerArena {
Winner::Tie => Outcomes::DRAW, Winner::Tie => Outcomes::DRAW,
Winner::None => panic!("somehow met None"), Winner::None => panic!("somehow met None"),
}; };
let (np1, np2) = elo(
&self.players[player1].2, elo(player_1_elo, player_2_elo, &outcome, &EloConfig::new())
&self.players[player2].2,
&outcome,
&EloConfig::new(),
);
self.players[player1].2 = np1;
self.players[player2].2 = np2;
} }
} }

View File

@ -1,7 +1,6 @@
use crate::{ use crate::{
agent::Agent, agent::Agent,
game_inner::GameInner, game_inner::GameInner,
repr::{Board, Piece, Winner},
}; };
pub struct Game { pub struct Game {