elo work 2

This commit is contained in:
2025-03-03 09:14:22 -05:00
parent a9dd85762d
commit 2eb1e6e5ed
3 changed files with 19 additions and 83 deletions

1
Cargo.lock generated
View File

@@ -438,6 +438,7 @@ dependencies = [
"nohash-hasher", "nohash-hasher",
"num", "num",
"rand", "rand",
"rayon",
"skillratings", "skillratings",
"static_assertions", "static_assertions",
] ]

View File

@@ -33,6 +33,7 @@ indicatif = "0.17"
nohash-hasher = "0.2" nohash-hasher = "0.2"
num = "0.4" num = "0.4"
rand = "0.9" rand = "0.9"
rayon = "1.10.0"
skillratings = "0.27.1" skillratings = "0.27.1"
static_assertions = "1.1" static_assertions = "1.1"

View File

@@ -25,89 +25,42 @@ pub fn run() {
( (
"RandomAgent".into(), "RandomAgent".into(),
Box::new(|piece| Box::new(RandomAgent::new(piece))), Box::new(|piece| Box::new(RandomAgent::new(piece))),
1,
), ),
( (
"ComplexAgent100K".into(), "ComplexAgentD5".into(),
Box::new(|piece| { Box::new(|piece| {
Box::new(ComplexAgent::new( Box::new(ComplexAgent::new(
piece, piece,
FutureMoveConfig { FutureMoveConfig {
max_arena_size: 100_000, max_depth: 5,
..FMV_BASE ..FMV_BASE
}, },
)) ))
}), }),
1,
), ),
( (
"ComplexAgent500K".into(), "ComplexAgentD6".into(),
Box::new(|piece| { Box::new(|piece| {
Box::new(ComplexAgent::new( Box::new(ComplexAgent::new(
piece, piece,
FutureMoveConfig { FutureMoveConfig {
max_arena_size: 500_000, max_depth: 6,
..FMV_BASE ..FMV_BASE
}, },
)) ))
}), }),
1,
), ),
( (
"ComplexAgent1M".into(), "ComplexAgentD7".into(),
Box::new(|piece| { Box::new(|piece| {
Box::new(ComplexAgent::new( Box::new(ComplexAgent::new(
piece, piece,
FutureMoveConfig { FutureMoveConfig {
max_arena_size: 1_000_000, max_depth: 7,
..FMV_BASE ..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,
), ),
]); ]);
@@ -128,14 +81,7 @@ pub fn run() {
pub struct PlayerArena { pub struct PlayerArena {
/// Name, Creator, Elo, freq (mod) /// Name, Creator, Elo, freq (mod)
players: Vec<( players: Vec<(String, Box<dyn Fn(Piece) -> Box<dyn Agent>>, EloRating)>,
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 {
@@ -157,15 +103,14 @@ impl std::fmt::Display for PlayerArena {
} }
impl PlayerArena { impl PlayerArena {
pub fn new(players: Vec<(String, Box<dyn Fn(Piece) -> Box<dyn Agent>>, usize)>) -> Self { pub fn new(players: Vec<(String, Box<dyn Fn(Piece) -> Box<dyn Agent>>)>) -> Self {
let len = players.len(); 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, d), c)| (a, b, c, d)) .map(|((a, b), c)| (a, b, c))
.collect(), .collect(),
freq_map: [0].repeat(len).to_vec(),
} }
} }
@@ -174,15 +119,6 @@ impl PlayerArena {
if i == j { if i == j {
continue; 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); self.play_two(i, j);
} }
@@ -200,11 +136,13 @@ impl PlayerArena {
self.players[player1].0, self.players[player2].0 self.players[player1].0, self.players[player2].0
); );
let (np1, np2) = Self::play_two_inner( let outcome = Self::play_two_inner(&self.players[player1].1, &self.players[player2].1);
&self.players[player1].1,
&self.players[player2].1, let (np1, np2) = elo(
&self.players[player1].2, &self.players[player1].2,
&self.players[player2].2, &self.players[player2].2,
&outcome,
&EloConfig::new(),
); );
self.players[player1].2 = np1; self.players[player1].2 = np1;
self.players[player2].2 = np2; self.players[player2].2 = np2;
@@ -213,21 +151,17 @@ impl PlayerArena {
fn play_two_inner( fn play_two_inner(
player_1_fn: &Box<dyn Fn(Piece) -> Box<dyn Agent>>, player_1_fn: &Box<dyn Fn(Piece) -> Box<dyn Agent>>,
player_2_fn: &Box<dyn Fn(Piece) -> Box<dyn Agent>>, player_2_fn: &Box<dyn Fn(Piece) -> Box<dyn Agent>>,
player_1_elo: &EloRating, ) -> Outcomes {
player_2_elo: &EloRating,
) -> (EloRating, EloRating) {
let result = GameInner::new(player_1_fn(Piece::Black), player_2_fn(Piece::White), false) let result = GameInner::new(player_1_fn(Piece::Black), player_2_fn(Piece::White), false)
.loop_until_result(); .loop_until_result();
let outcome = match result { match result {
Winner::Player(piece) => match piece { Winner::Player(piece) => match piece {
Piece::Black => Outcomes::WIN, Piece::Black => Outcomes::WIN,
Piece::White => Outcomes::LOSS, Piece::White => Outcomes::LOSS,
}, },
Winner::Tie => Outcomes::DRAW, Winner::Tie => Outcomes::DRAW,
Winner::None => panic!("somehow met None"), Winner::None => panic!("somehow met None"),
}; }
elo(player_1_elo, player_2_elo, &outcome, &EloConfig::new())
} }
} }