brutus tweaks
parent
00270569db
commit
786e70fe9a
|
@ -2,6 +2,7 @@ use std::{cmp::Ordering, iter};
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
use rand::{seq::SliceRandom, thread_rng};
|
||||||
use rayon::iter::{ParallelBridge, ParallelIterator};
|
use rayon::iter::{ParallelBridge, ParallelIterator};
|
||||||
|
|
||||||
use super::{Agent, Chase, MaximizerAgent, MinimizerAgent};
|
use super::{Agent, Chase, MaximizerAgent, MinimizerAgent};
|
||||||
|
@ -27,14 +28,20 @@ impl Brutus {
|
||||||
.collect_vec();
|
.collect_vec();
|
||||||
|
|
||||||
if symbols.is_empty() {
|
if symbols.is_empty() {
|
||||||
return Chase::new(self.player).step_max(board);
|
return if minimize {
|
||||||
|
Chase::new(self.player).step_min(board)
|
||||||
|
} else {
|
||||||
|
Chase::new(self.player).step_max(board)
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Number of free slots
|
// Number of free slots
|
||||||
let n_free = board.get_board().iter().filter(|x| x.is_none()).count();
|
let n_free = board.get_board().iter().filter(|x| x.is_none()).count();
|
||||||
|
|
||||||
// Number of slots we need to fill with numbers
|
// Number of slots we need to fill with numbers
|
||||||
let n_fill = n_free - symbols.len();
|
// Add one if we have two or fewer symbols available, so that we can
|
||||||
|
// account for one unused symbol while keeping a reasonable runtime
|
||||||
|
let n_fill = n_free - symbols.len() + if symbols.len() <= 2 { 1 } else { 0 };
|
||||||
|
|
||||||
let mut items = iter::repeat(None)
|
let mut items = iter::repeat(None)
|
||||||
.take(n_fill)
|
.take(n_fill)
|
||||||
|
@ -70,7 +77,7 @@ impl Brutus {
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
if minimize {
|
if minimize {
|
||||||
// Sort from smallest midpoint to biggest midpoint
|
// Sort from smallest to biggest midpoint
|
||||||
items.sort_by(|a, b| a.1.partial_cmp(&b.1).unwrap_or(Ordering::Equal));
|
items.sort_by(|a, b| a.1.partial_cmp(&b.1).unwrap_or(Ordering::Equal));
|
||||||
} else {
|
} else {
|
||||||
items.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap_or(Ordering::Equal));
|
items.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap_or(Ordering::Equal));
|
||||||
|
@ -88,15 +95,27 @@ impl Brutus {
|
||||||
|
|
||||||
let (t, _) = items.first().unwrap();
|
let (t, _) = items.first().unwrap();
|
||||||
|
|
||||||
for (i, s) in t.get_board().iter().enumerate() {
|
let mut symbols = symbols.clone();
|
||||||
if let Some(s) = s {
|
symbols.shuffle(&mut thread_rng());
|
||||||
if s.is_op() && board.get_board()[i].is_none() {
|
|
||||||
return Ok(PlayerAction { pos: i, symb: *s });
|
// Place a random unused symbol
|
||||||
|
for target_s in symbols {
|
||||||
|
for (i, s) in t.get_board().iter().enumerate() {
|
||||||
|
if let Some(s) = s {
|
||||||
|
if board.get_board()[i].is_none() && target_s == *s {
|
||||||
|
return Ok(PlayerAction { pos: i, symb: *s });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unreachable!()
|
// Final escape hatch, if we didn't decide to place any symbols
|
||||||
|
// (which is possible, since we add one to free_spots above!)
|
||||||
|
if minimize {
|
||||||
|
Chase::new(self.player).step_min(board)
|
||||||
|
} else {
|
||||||
|
Chase::new(self.player).step_max(board)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue