mirror of
https://github.com/Noratrieb/minmax.git
synced 2026-01-14 15:25:08 +01:00
more things
This commit is contained in:
parent
5b0c3106c0
commit
a3b836265a
4 changed files with 19 additions and 8 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -1 +1,2 @@
|
||||||
/target
|
/target
|
||||||
|
perf.*
|
||||||
|
|
|
||||||
|
|
@ -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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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:?}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue