simplify move creation and allow switching between value methods

This commit is contained in:
2025-04-20 01:43:00 -04:00
parent 5e4e240e33
commit 517e54dade
2 changed files with 43 additions and 36 deletions

View File

@@ -101,6 +101,8 @@ pub enum ChildrenEvalMethod {
/// Best so far? /// Best so far?
MinMax, MinMax,
MinMaxFlat,
} }
impl Default for ChildrenEvalMethod { impl Default for ChildrenEvalMethod {
@@ -225,6 +227,19 @@ impl FutureMoves {
false false
} }
fn create_move(&self, coord: MoveCoord, board: Board, color: Piece) -> Move {
Move::new(
coord,
board,
color,
self.agent_color,
!matches!(
self.config.children_eval_method,
ChildrenEvalMethod::MinMaxFlat
),
)
}
fn generate_children_raw(&self, parent_idx: usize) -> Vec<Move> { fn generate_children_raw(&self, parent_idx: usize) -> Vec<Move> {
let parent = &self.arena[parent_idx]; let parent = &self.arena[parent_idx];
@@ -241,15 +256,13 @@ impl FutureMoves {
.what_if(coord, new_color) .what_if(coord, new_color)
.map(move |x| (coord, x)) .map(move |x| (coord, x))
}) })
.map(|(coord, new_board)| { .map(|(coord, new_board)| self.create_move(Some(coord), new_board, new_color))
Move::new(Some(coord), new_board, new_color, self.agent_color)
})
.collect(); .collect();
// if there are no moves to take, making // if there are no moves to take, making
// no move is also an option! // no move is also an option!
if new.is_empty() { if new.is_empty() {
new.push(Move::new(None, parent_board, new_color, self.agent_color)); new.push(self.create_move(None, parent_board, new_color));
} }
for m in new.iter_mut() { for m in new.iter_mut() {
@@ -334,7 +347,7 @@ impl FutureMoves {
} }
} }
ChildrenEvalMethod::MinMax => { ChildrenEvalMethod::MinMax | ChildrenEvalMethod::MinMaxFlat => {
if self.arena[idx].color == self.agent_color { if self.arena[idx].color == self.agent_color {
// get best (for the adversary) enemy play // get best (for the adversary) enemy play
// this assumes the adversary is playing optimally // this assumes the adversary is playing optimally
@@ -446,7 +459,7 @@ impl FutureMoves {
} }
fn rebuild_from_board(&mut self, board: Board) { fn rebuild_from_board(&mut self, board: Board) {
self.arena = vec![Move::new(None, board, !self.agent_color, self.agent_color)]; self.arena = vec![self.create_move(None, board, !self.agent_color)];
self.current_root = Some(0); self.current_root = Some(0);
self.current_depth = 0; self.current_depth = 0;
self.board = board; self.board = board;
@@ -653,25 +666,21 @@ mod tests {
// child 1 // child 1
futm.arena futm.arena
.push(Move::new(None, Board::new(), Piece::White, Piece::Black)); .push(futm.create_move(None, Board::new(), Piece::White));
futm.set_parent_child(0, 1); futm.set_parent_child(0, 1);
// dummy (2) // dummy (2)
futm.arena.push(Move::new( futm.arena
Some((9, 9).into()), .push(futm.create_move(Some((9, 9).into()), Board::new(), Piece::White));
Board::new(),
Piece::White,
Piece::Black,
));
// 3 // 3
futm.arena futm.arena
.push(Move::new(None, Board::new(), Piece::White, Piece::Black)); .push(futm.create_move(None, Board::new(), Piece::White));
futm.set_parent_child(0, 3); futm.set_parent_child(0, 3);
// 4 // 4
futm.arena futm.arena
.push(Move::new(None, Board::new(), Piece::White, Piece::Black)); .push(futm.create_move(None, Board::new(), Piece::White));
futm.set_parent_child(0, 4); futm.set_parent_child(0, 4);
assert_eq!(futm.arena_len(), 5); assert_eq!(futm.arena_len(), 5);
@@ -720,20 +729,20 @@ mod tests {
// child 1 // child 1
futm.arena futm.arena
.push(Move::new(None, Board::new(), Piece::White, Piece::Black)); .push(futm.create_move(None, Board::new(), Piece::White));
futm.set_parent_child(0, 1); futm.set_parent_child(0, 1);
// dummy // dummy
futm.arena futm.arena
.push(Move::new(None, Board::new(), Piece::White, Piece::Black)); .push(futm.create_move(None, Board::new(), Piece::White));
futm.arena futm.arena
.push(Move::new(None, Board::new(), Piece::White, Piece::Black)); .push(futm.create_move(None, Board::new(), Piece::White));
futm.set_parent_child(1, 3); futm.set_parent_child(1, 3);
futm.arena futm.arena
.push(Move::new(None, Board::new(), Piece::White, Piece::Black)); .push(futm.create_move(None, Board::new(), Piece::White));
futm.set_parent_child(0, 4); futm.set_parent_child(0, 4);
@@ -748,15 +757,15 @@ mod tests {
// child 1 // child 1
futm.arena futm.arena
.push(Move::new(None, Board::new(), Piece::White, Piece::Black)); .push(futm.create_move(None, Board::new(), Piece::White));
futm.set_parent_child(0, 1); futm.set_parent_child(0, 1);
// dummy // dummy
futm.arena futm.arena
.push(Move::new(None, Board::new(), Piece::White, Piece::Black)); .push(futm.create_move(None, Board::new(), Piece::White));
futm.arena futm.arena
.push(Move::new(None, Board::new(), Piece::White, Piece::Black)); .push(futm.create_move(None, Board::new(), Piece::White));
futm.set_parent_child(1, 3); futm.set_parent_child(1, 3);
assert_eq!( assert_eq!(
@@ -838,12 +847,8 @@ mod tests {
b.place((4, 5).into(), Piece::White).unwrap(); b.place((4, 5).into(), Piece::White).unwrap();
futm.arena.push(Move::new( futm.arena
Some((4, 5).into()), .push(futm.create_move(Some((4, 5).into()), b, Piece::White));
b,
Piece::White,
Piece::White,
));
futm.set_parent_child(0, 1); futm.set_parent_child(0, 1);
@@ -855,12 +860,8 @@ mod tests {
b.place((5, 3).into(), Piece::Black).unwrap(); b.place((5, 3).into(), Piece::Black).unwrap();
futm.arena.push(Move::new( futm.arena
Some((5, 3).into()), .push(futm.create_move(Some((5, 3).into()), b, Piece::Black));
b,
Piece::Black,
Piece::White,
));
futm.set_parent_child(1, 2); futm.set_parent_child(1, 2);
assert_eq!( assert_eq!(

View File

@@ -36,7 +36,13 @@ pub struct Move {
} }
impl Move { impl Move {
pub fn new(coord: MoveCoord, board: Board, color: Piece, agent_color: Piece) -> Self { pub fn new(
coord: MoveCoord,
board: Board,
color: Piece,
agent_color: Piece,
use_weighted_bvm: bool,
) -> Self {
let mut m = Move { let mut m = Move {
coord, coord,
winner: board.game_winner(), winner: board.game_winner(),
@@ -47,7 +53,7 @@ impl Move {
is_trimmed: false, is_trimmed: false,
self_value: 0, self_value: 0,
}; };
m.self_value = m.compute_self_value(agent_color, &board, true); m.self_value = m.compute_self_value(agent_color, &board, use_weighted_bvm);
m m
} }