fully fix future_moves
This commit is contained in:
parent
efd762e5d2
commit
52e7ed7386
@ -16,7 +16,7 @@ fn extend_layers_no_pruning(depth: usize, arena_size: usize) -> usize {
|
||||
children_eval_method: ChildrenEvalMethod::Max,
|
||||
};
|
||||
let mut fut = FutureMoves::new(Piece::Black, config);
|
||||
fut.set_root_from_board(Board::new().starting_pos());
|
||||
fut.update_from_board(&Board::new().starting_pos());
|
||||
fut.extend_layers();
|
||||
fut.arena_len()
|
||||
}
|
||||
|
||||
@ -22,6 +22,7 @@ impl ComplexAgent {
|
||||
impl Agent for ComplexAgent {
|
||||
fn next_move(&mut self, board: &Board) -> Option<CoordPair> {
|
||||
self.future_moves.update_from_board(board);
|
||||
self.future_moves.generate();
|
||||
|
||||
self.future_moves
|
||||
.best_move()
|
||||
|
||||
@ -366,54 +366,41 @@ impl FutureMoves {
|
||||
// match the agent_color usually root or great-grand child
|
||||
.filter(|&idx| self.depth_of(idx) % 2 == 0)
|
||||
.find(|&idx| {
|
||||
self.get_board_from_idx(idx).as_ref() == Some(board)
|
||||
&& self.arena[idx].color == !self.agent_color
|
||||
self.arena[idx].color == !self.agent_color
|
||||
&& self.get_board_from_idx(idx).as_ref() == Some(board)
|
||||
});
|
||||
|
||||
if let Some(curr_board_idx) = curr_board {
|
||||
self.set_root_idx_raw(curr_board_idx);
|
||||
self.root_from_child_idx_board(curr_board_idx, *board);
|
||||
false
|
||||
} else {
|
||||
if self.config.print && !self.arena.is_empty() {
|
||||
println!("regenerating arena from board");
|
||||
}
|
||||
self.set_root_from_board(*board);
|
||||
self.rebuild_from_board(*board);
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
/// Clear the arena and create and set a root which contains a Board
|
||||
pub fn set_root_from_board(&mut self, board: Board) {
|
||||
pub fn generate(&mut self) {
|
||||
self.extend_layers();
|
||||
self.compute_values(0..self.arena.len());
|
||||
}
|
||||
|
||||
fn rebuild_from_board(&mut self, board: Board) {
|
||||
self.arena.clear();
|
||||
self.arena
|
||||
.push(Move::new(None, board, !self.agent_color, self.agent_color));
|
||||
|
||||
// because we have to regenerate root from a [`Board`]
|
||||
// we need to reset the current_depth (fixes `skip_move_recovery`)
|
||||
self.current_root = Some(0);
|
||||
self.current_depth = 0;
|
||||
|
||||
self.set_root_idx_raw(0);
|
||||
self.board = board;
|
||||
}
|
||||
|
||||
/// Update current root without modifying or pruning the Arena
|
||||
fn update_root_idx_raw(&mut self, idx: usize) {
|
||||
self.current_root = Some(idx);
|
||||
fn root_from_child_idx_board(&mut self, idx: usize, board: Board) {
|
||||
self.current_depth -= self.depth_of(idx);
|
||||
}
|
||||
|
||||
/// Update current root index while pruning and extending the tree (also recalculate values)
|
||||
fn set_root_idx_raw(&mut self, idx: usize) {
|
||||
self.update_root_idx_raw(idx);
|
||||
|
||||
self.current_root = Some(idx);
|
||||
self.board = board;
|
||||
self.refocus_tree();
|
||||
self.extend_layers();
|
||||
if self.config.print {
|
||||
println!("# of moves stored: {}", self.arena_len());
|
||||
}
|
||||
self.compute_values(0..self.arena.len());
|
||||
|
||||
// check arena's consistancy
|
||||
debug_assert_eq!(self.check_arena().join("\n"), "");
|
||||
}
|
||||
|
||||
pub fn set_parent_child(&mut self, parent: usize, child: usize) {
|
||||
@ -574,26 +561,14 @@ mod tests {
|
||||
max_arena_size: 100,
|
||||
do_prune: false,
|
||||
print: false,
|
||||
children_eval_method: ChildrenEvalMethod::Max,
|
||||
children_eval_method: ChildrenEvalMethod::Average,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn prune_tree_test() {
|
||||
let mut futm = FutureMoves::new(Piece::Black, FUTURE_MOVES_CONFIG);
|
||||
|
||||
futm.arena.push(Move {
|
||||
coord: None,
|
||||
winner: Winner::None,
|
||||
parent: None,
|
||||
children: Vec::new(),
|
||||
value: None,
|
||||
self_value: 0,
|
||||
color: Piece::Black,
|
||||
is_trimmed: false,
|
||||
tried_children: false,
|
||||
});
|
||||
|
||||
futm.update_root_idx_raw(0);
|
||||
futm.update_from_board(&Board::new());
|
||||
|
||||
// child 1
|
||||
futm.arena
|
||||
@ -636,20 +611,17 @@ mod tests {
|
||||
let mut futm = FutureMoves::new(Piece::Black, FUTURE_MOVES_CONFIG);
|
||||
futm.config.max_depth = 1;
|
||||
|
||||
futm.arena.push(Move::new(
|
||||
None,
|
||||
Board::new().starting_pos(),
|
||||
Piece::Black,
|
||||
Piece::Black,
|
||||
));
|
||||
|
||||
futm.update_root_idx_raw(0);
|
||||
futm.update_from_board(&Board::new().starting_pos());
|
||||
|
||||
futm.extend_layers();
|
||||
assert_eq!(futm.arena_len(), 5);
|
||||
|
||||
// move to a child
|
||||
futm.update_root_idx_raw(1);
|
||||
futm.root_from_child_idx_board(
|
||||
1,
|
||||
futm.get_board_from_idx(1)
|
||||
.expect("unable to get board from child"),
|
||||
);
|
||||
futm.refocus_tree();
|
||||
assert_eq!(futm.arena_len(), 1);
|
||||
|
||||
@ -667,19 +639,7 @@ mod tests {
|
||||
fn depth_of_test() {
|
||||
let mut futm = FutureMoves::new(Piece::Black, FUTURE_MOVES_CONFIG);
|
||||
|
||||
futm.arena.push(Move {
|
||||
coord: None,
|
||||
winner: Winner::None,
|
||||
parent: None,
|
||||
children: vec![],
|
||||
value: None,
|
||||
self_value: 0,
|
||||
color: Piece::Black,
|
||||
is_trimmed: false,
|
||||
tried_children: false,
|
||||
});
|
||||
|
||||
futm.update_root_idx_raw(0);
|
||||
futm.update_from_board(&Board::new());
|
||||
|
||||
// child 1
|
||||
futm.arena
|
||||
@ -707,19 +667,7 @@ mod tests {
|
||||
fn by_depth_test() {
|
||||
let mut futm = FutureMoves::new(Piece::Black, FUTURE_MOVES_CONFIG);
|
||||
|
||||
futm.arena.push(Move {
|
||||
coord: None,
|
||||
winner: Winner::None,
|
||||
parent: None,
|
||||
children: vec![1],
|
||||
value: None,
|
||||
self_value: 0,
|
||||
color: Piece::Black,
|
||||
is_trimmed: false,
|
||||
tried_children: false,
|
||||
});
|
||||
|
||||
futm.update_root_idx_raw(0);
|
||||
futm.update_from_board(&Board::new());
|
||||
|
||||
// child 1
|
||||
futm.arena
|
||||
@ -775,6 +723,7 @@ mod tests {
|
||||
|
||||
// seperate variable because we want it to always be executed
|
||||
let update_result = futm.update_from_board(&board);
|
||||
futm.generate();
|
||||
|
||||
// make sure that the arena should only be
|
||||
// regenerated on the first move
|
||||
@ -808,9 +757,7 @@ mod tests {
|
||||
let mut futm = FutureMoves::new(Piece::White, FUTURE_MOVES_CONFIG);
|
||||
|
||||
let mut b = Board::new().starting_pos();
|
||||
futm.arena
|
||||
.push(Move::new(None, b, Piece::Black, Piece::White));
|
||||
futm.update_root_idx_raw(0);
|
||||
futm.update_from_board(&Board::new().starting_pos());
|
||||
|
||||
b.place((4, 2).into(), Piece::White).unwrap();
|
||||
|
||||
@ -877,7 +824,8 @@ mod tests {
|
||||
|
||||
let mut futm = FutureMoves::new(Piece::White, FUTURE_MOVES_CONFIG);
|
||||
futm.update_from_board(&board);
|
||||
futm.extend_layers();
|
||||
futm.generate();
|
||||
|
||||
let best_move = futm.best_move();
|
||||
|
||||
if let Some(best_move) = best_move {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user