properly handle skipping a move
This commit is contained in:
parent
8719d31c38
commit
2c31589e51
@ -32,11 +32,9 @@ impl Agent for ComplexAgent {
|
|||||||
|
|
||||||
println!("# of moves stored: {}", self.future_moves.arena_len());
|
println!("# of moves stored: {}", self.future_moves.arena_len());
|
||||||
|
|
||||||
self.future_moves.best_move().inspect(|&(i, j)| {
|
self.future_moves
|
||||||
if !self.future_moves.update_root_coord(i, j) {
|
.best_move()
|
||||||
panic!("update_root_coord failed");
|
.expect("FutureMoves has no move?")
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn name(&self) -> &'static str {
|
fn name(&self) -> &'static str {
|
||||||
|
|||||||
@ -216,7 +216,7 @@ impl FutureMoves {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Return the best move which is a child of `self.current_root`
|
/// Return the best move which is a child of `self.current_root`
|
||||||
pub fn best_move(&self) -> Option<(Coord, Coord)> {
|
pub fn best_move(&self) -> Option<Option<(Coord, Coord)>> {
|
||||||
self.current_root
|
self.current_root
|
||||||
.and_then(|x| {
|
.and_then(|x| {
|
||||||
self.arena[x]
|
self.arena[x]
|
||||||
@ -230,25 +230,32 @@ impl FutureMoves {
|
|||||||
"selected move color should be the same as the color of the agent"
|
"selected move color should be the same as the color of the agent"
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
.and_then(|&x| self.arena[x].coord)
|
.map(|&x| self.arena[x].coord)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Updates `FutureMoves` based on the current state of the board
|
/// Updates `FutureMoves` based on the current state of the board
|
||||||
/// The board is supposed to be after the opposing move
|
/// The board is supposed to be after the opposing move
|
||||||
pub fn update_from_board(&mut self, board: &Board) {
|
/// Returns whether or not the arena was regenerated (bool)
|
||||||
|
pub fn update_from_board(&mut self, board: &Board) -> bool {
|
||||||
let curr_board = self
|
let curr_board = self
|
||||||
.arena
|
.arena
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.find(|(_, m)| &m.board == board && (m.parent == self.current_root))
|
.filter(|(idx, _)| {
|
||||||
.map(|(idx, _)| idx)
|
self.current_root
|
||||||
.filter(|_| self.current_root.is_some());
|
.map(|x| self.arena[x].children.contains(idx))
|
||||||
|
.unwrap_or(false)
|
||||||
|
})
|
||||||
|
.find(|(_, m)| &m.board == board)
|
||||||
|
.map(|(idx, _)| idx);
|
||||||
|
|
||||||
if let Some(curr_board_idx) = curr_board {
|
if let Some(curr_board_idx) = curr_board {
|
||||||
self.set_root_idx_raw(curr_board_idx);
|
self.set_root_idx_raw(curr_board_idx);
|
||||||
|
return false;
|
||||||
} else {
|
} else {
|
||||||
dbg!("regenerating arena from board");
|
dbg!("regenerating arena from board");
|
||||||
self.set_root_from_board(*board);
|
self.set_root_from_board(*board);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,26 +271,6 @@ impl FutureMoves {
|
|||||||
self.set_root_idx_raw(0);
|
self.set_root_idx_raw(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update the root based on the coordinate of the move
|
|
||||||
/// Returns a boolean, `true` if the operation was successful, false if not
|
|
||||||
#[must_use = "You must check if the root was properly set"]
|
|
||||||
pub fn update_root_coord(&mut self, i: Coord, j: Coord) -> bool {
|
|
||||||
// check to make sure current_root is some so we dont
|
|
||||||
// have to do that in the iterator
|
|
||||||
if self.current_root.is_none() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.arena
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.find(|(_, node)| node.parent == self.current_root && node.coord == Some((i, j)))
|
|
||||||
.map(|x| x.0)
|
|
||||||
// do raw set so we can prune it on the next move (in `update`)
|
|
||||||
.inspect(|&root| self.update_root_idx_raw(root))
|
|
||||||
.is_some()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Update current root without modifying or pruning the Arena
|
/// Update current root without modifying or pruning the Arena
|
||||||
fn update_root_idx_raw(&mut self, idx: usize) {
|
fn update_root_idx_raw(&mut self, idx: usize) {
|
||||||
self.current_root = Some(idx);
|
self.current_root = Some(idx);
|
||||||
@ -461,8 +448,8 @@ mod tests {
|
|||||||
|
|
||||||
const FUTURE_MOVES_CONFIG: FutureMoveConfig = FutureMoveConfig {
|
const FUTURE_MOVES_CONFIG: FutureMoveConfig = FutureMoveConfig {
|
||||||
max_depth: 1,
|
max_depth: 1,
|
||||||
min_arena_depth_sub: 2,
|
min_arena_depth_sub: 0,
|
||||||
top_k_children: 2,
|
top_k_children: 1,
|
||||||
up_to_minus: 0,
|
up_to_minus: 0,
|
||||||
max_arena_size: 100,
|
max_arena_size: 100,
|
||||||
};
|
};
|
||||||
@ -662,17 +649,32 @@ mod tests {
|
|||||||
(Some((4, 2)), Piece::White),
|
(Some((4, 2)), Piece::White),
|
||||||
];
|
];
|
||||||
|
|
||||||
for (coords, color) in moves {
|
for (i, (coords, color)) in moves.into_iter().enumerate() {
|
||||||
if color == futm.agent_color {
|
if color == futm.agent_color {
|
||||||
// my turn
|
// my turn
|
||||||
futm.update_from_board(&board);
|
|
||||||
|
// seperate variable because we want it to always be executed
|
||||||
|
let update_result = futm.update_from_board(&board);
|
||||||
|
|
||||||
|
// make sure that the arena should only be
|
||||||
|
// regenerated on the first move
|
||||||
|
assert!(i <= 0 || update_result, "board regenerated on move #{}", i);
|
||||||
|
|
||||||
let best_move = futm.best_move();
|
let best_move = futm.best_move();
|
||||||
|
assert!(
|
||||||
|
best_move.is_some(),
|
||||||
|
"best_move (#{}) resulted in ABSOLUTE None: {:?}",
|
||||||
|
i,
|
||||||
|
best_move
|
||||||
|
);
|
||||||
|
|
||||||
if coords.is_none() {
|
if coords.is_none() {
|
||||||
assert_eq!(best_move, None);
|
assert_eq!(best_move, Some(None));
|
||||||
} else {
|
} else {
|
||||||
assert_ne!(best_move, None);
|
assert_ne!(best_move, Some(None));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some((i, j)) = coords {
|
if let Some((i, j)) = coords {
|
||||||
board.place(i, j, color).unwrap();
|
board.place(i, j, color).unwrap();
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user