more things

This commit is contained in:
nora 2022-12-05 16:20:18 +01:00
parent 5b0c3106c0
commit a3b836265a
No known key found for this signature in database
4 changed files with 19 additions and 8 deletions

1
.gitignore vendored
View file

@ -1 +1,2 @@
/target /target
perf.*

View file

@ -61,6 +61,8 @@ struct Args {
x: PlayerConfig, x: PlayerConfig,
#[arg(short)] #[arg(short)]
o: PlayerConfig, o: PlayerConfig,
#[arg(long)]
no_print_time: bool,
} }
fn main() { fn main() {
@ -72,7 +74,7 @@ fn main() {
match player { match player {
PlayerConfig::Human => Box::new(connect4::HumanPlayer), PlayerConfig::Human => Box::new(connect4::HumanPlayer),
PlayerConfig::Perfect { depth } => { PlayerConfig::Perfect { depth } => {
Box::new(PerfectPlayer::new().with_max_depth(depth)) Box::new(PerfectPlayer::new(!args.no_print_time).with_max_depth(depth))
} }
} }
}; };
@ -87,7 +89,7 @@ fn main() {
match player { match player {
PlayerConfig::Human => Box::new(tic_tac_toe::HumanPlayer), PlayerConfig::Human => Box::new(tic_tac_toe::HumanPlayer),
PlayerConfig::Perfect { depth } => { PlayerConfig::Perfect { depth } => {
Box::new(PerfectPlayer::new().with_max_depth(depth)) Box::new(PerfectPlayer::new(!args.no_print_time).with_max_depth(depth))
} }
} }
}; };

View file

@ -1,22 +1,26 @@
use std::time::Instant;
use crate::{Game, GamePlayer, Player, Score, State}; use crate::{Game, GamePlayer, Player, Score, State};
#[derive(Clone)] #[derive(Clone)]
pub struct PerfectPlayer<G: Game> { pub struct PerfectPlayer<G: Game> {
best_move: Option<G::Move>, best_move: Option<G::Move>,
max_depth: Option<usize>, max_depth: Option<usize>,
print_time: bool,
} }
impl<G: Game> Default for PerfectPlayer<G> { impl<G: Game> Default for PerfectPlayer<G> {
fn default() -> Self { fn default() -> Self {
Self::new() Self::new(true)
} }
} }
impl<G: Game> PerfectPlayer<G> { impl<G: Game> PerfectPlayer<G> {
pub fn new() -> Self { pub fn new(print_time: bool) -> Self {
Self { Self {
best_move: None, best_move: None,
max_depth: G::REASONABLE_SEARCH_DEPTH, max_depth: G::REASONABLE_SEARCH_DEPTH,
print_time,
} }
} }
@ -64,11 +68,15 @@ impl<G: Game> PerfectPlayer<G> {
impl<G: Game> GamePlayer<G> for PerfectPlayer<G> { impl<G: Game> GamePlayer<G> for PerfectPlayer<G> {
fn next_move(&mut self, board: &mut G, this_player: Player) { fn next_move(&mut self, board: &mut G, this_player: Player) {
println!("{board}"); let start = Instant::now();
self.best_move = None; self.best_move = None;
self.minmax(board, this_player, 0); self.minmax(board, this_player, 0);
board.make_move(self.best_move.expect("could not make move"), this_player); board.make_move(self.best_move.expect("could not make move"), this_player);
if self.print_time {
let duration = start.elapsed();
println!("Move took {duration:?}");
}
} }
} }

View file

@ -33,11 +33,11 @@ mod tests {
#[test] #[test]
fn perfect_always_beats_greedy() { fn perfect_always_beats_greedy() {
assert_win_ratio(20, 1.0, || PerfectPlayer::new(), || GreedyPlayer); assert_win_ratio(20, 1.0, || PerfectPlayer::new(false), || GreedyPlayer);
} }
#[test] #[test]
fn perfect_beats_random() { fn perfect_beats_random() {
assert_win_ratio(10, 0.95, || PerfectPlayer::new(), || RandomPlayer); assert_win_ratio(10, 0.95, || PerfectPlayer::new(false), || RandomPlayer);
} }
} }