simplify move creation and allow switching between value methods
This commit is contained in:
@@ -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!(
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user