cleanup minmax impl

This commit is contained in:
Simon Gardling 2025-04-29 18:31:41 -04:00
parent 9342760d82
commit 111ce718da
Signed by: titaniumtown
GPG Key ID: 9AB28AC10ECE533D
3 changed files with 19 additions and 62 deletions

View File

@ -30,7 +30,7 @@ pub fn run() {
..Default::default() ..Default::default()
}; };
let configs = [2, 4, 6, 8] let configs = [2, 4, 6]
.into_iter() .into_iter()
.map(move |d| FutureMoveConfig { .map(move |d| FutureMoveConfig {
max_depth: d, max_depth: d,

View File

@ -213,18 +213,7 @@ impl FutureMoves {
} }
fn create_move(&self, coord: MoveCoord, board: Board, color: Piece) -> Move { fn create_move(&self, coord: MoveCoord, board: Board, color: Piece) -> Move {
Move::new( Move::new(coord, board, color, self.agent_color, MoveValueConfig {})
coord,
board,
color,
self.agent_color,
MoveValueConfig {
self_value_raw: matches!(
self.config.children_eval_method,
ChildrenEvalMethod::MinMaxProb
),
},
)
} }
fn generate_children_raw(&self, parent_idx: usize) -> Vec<Move> { fn generate_children_raw(&self, parent_idx: usize) -> Vec<Move> {
@ -307,38 +296,27 @@ impl FutureMoves {
.iter() .iter()
.map(|&child| self.arena[child].value) .map(|&child| self.arena[child].value)
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let child_value = if self.arena[idx].color == self.agent_color {
// get best (for the adversary) enemy play
// this assumes the adversary is playing optimally
children_values.iter().min()
} else {
children_values.iter().max()
}
.cloned()
.unwrap_or(Default::default());
self.arena[idx].value = self.arena[idx].self_value;
match self.config.children_eval_method { match self.config.children_eval_method {
ChildrenEvalMethod::MinMax => { ChildrenEvalMethod::MinMax => {
let child_value = if self.arena[idx].color == self.agent_color { self.arena[idx].value.value += child_value.value;
// get best (for the adversary) enemy play
// this assumes the adversary is playing optimally
children_values.into_iter().map(|x| x.value).min()
} else {
children_values.into_iter().map(|x| x.value).max()
}
.unwrap_or(0);
self.arena[idx].value.value =
self.arena[idx].self_value.value + child_value;
} }
ChildrenEvalMethod::MinMaxProb => { ChildrenEvalMethod::MinMaxProb => {
let child_value = if self.arena[idx].color == self.agent_color {
// get best (for the adversary) enemy play
// this assumes the adversary is playing optimally
children_values.iter().min()
} else {
children_values.iter().max()
}
.cloned()
.unwrap_or(Default::default());
self.arena[idx].value = self.arena[idx].self_value;
self.arena[idx] self.arena[idx]
.value .value
.populate_self_from_children(&children_values); .populate_self_from_children(&children_values);
self.arena[idx].value.value += child_value.value; self.arena[idx].value.value += child_value.value;
} }
} }

View File

@ -38,9 +38,7 @@ pub struct Move {
pub is_trimmed: bool, pub is_trimmed: bool,
} }
pub struct MoveValueConfig { pub struct MoveValueConfig {}
pub self_value_raw: bool,
}
impl Move { impl Move {
pub fn new( pub fn new(
@ -48,7 +46,7 @@ impl Move {
board: Board, board: Board,
color: Piece, color: Piece,
agent_color: Piece, agent_color: Piece,
mvc: MoveValueConfig, _: MoveValueConfig,
) -> Self { ) -> Self {
let mut m = Move { let mut m = Move {
coord, coord,
@ -76,30 +74,11 @@ impl Move {
Winner::None => {} Winner::None => {}
} }
if mvc.self_value_raw { m.self_value.value =
m.self_value.value = const { BoardValueMap::weighted() }.board_value(&board, agent_color) as i32;
const { BoardValueMap::weighted() }.board_value(&board, agent_color) as i32;
} else {
m.self_value.value = m.compute_self_value(agent_color, &board, mvc) as i32;
}
m m
} }
fn compute_self_value(&self, agent_color: Piece, board: &Board, _mvc: MoveValueConfig) -> i16 {
if self.winner == Winner::Player(!agent_color) {
// if this board results in the opponent winning, MAJORLY negatively weigh this move
// NOTE! this branch isn't completely deleted because if so, the bot wouldn't make a move.
// We shouldn't prune branches because we still need to always react to the opponent's moves
return i16::MIN + 1;
} else if self.winner == Winner::Player(agent_color) {
// results in a win for the agent
return i16::MAX - 1;
}
// I guess ignore Ties here, don't give them an explicit value,
const { BoardValueMap::weighted() }.board_value(board, agent_color)
}
/// Sort children of the [`Move`] by their self_value in `arena` /// Sort children of the [`Move`] by their self_value in `arena`
pub fn sort_children(&mut self, arena: &[Move]) { pub fn sort_children(&mut self, arena: &[Move]) {
self.children.sort_by(|&a, &b| { self.children.sort_by(|&a, &b| {