allow move arena to properly handle skipping a move
This commit is contained in:
parent
4a82c01d64
commit
d3cac6ae91
@ -120,16 +120,22 @@ impl FutureMoves {
|
||||
|
||||
// use [`Board::all_positions`] here instead of [`Board::possible_moves`]
|
||||
// because we use [`Board::what_if`] later and we want to reduce calls to [`Board::propegate_from_dry`]
|
||||
let new: Vec<Move> = Board::all_positions()
|
||||
let mut new: Vec<Move> = Board::all_positions()
|
||||
.flat_map(|(i, j)| {
|
||||
parent
|
||||
.board
|
||||
.what_if(i, j, new_color)
|
||||
.map(move |x| (i, j, x))
|
||||
})
|
||||
.map(|(i, j, new_board)| Move::new(i, j, new_board, new_color, self.agent_color))
|
||||
.map(|(i, j, new_board)| {
|
||||
Move::new(Some((i, j)), new_board, new_color, self.agent_color)
|
||||
})
|
||||
.collect();
|
||||
|
||||
if new.is_empty() {
|
||||
new.push(Move::new(None, parent.board, new_color, self.agent_color));
|
||||
}
|
||||
|
||||
let start_idx = self.arena.len();
|
||||
self.arena.extend(new);
|
||||
|
||||
@ -224,7 +230,7 @@ impl FutureMoves {
|
||||
"selected move color should be the same as the color of the agent"
|
||||
);
|
||||
})
|
||||
.map(|&x| self.arena[x].coords())
|
||||
.and_then(|&x| self.arena[x].coord)
|
||||
}
|
||||
|
||||
/// Updates `FutureMoves` based on the current state of the board
|
||||
@ -248,13 +254,8 @@ impl FutureMoves {
|
||||
/// Clear the arena and create and set a root which contains a Board
|
||||
pub fn set_root_from_board(&mut self, board: Board) {
|
||||
self.arena.clear();
|
||||
self.arena.push(Move::new(
|
||||
0, // dummy
|
||||
0, // dummy
|
||||
board,
|
||||
!self.agent_color,
|
||||
self.agent_color,
|
||||
));
|
||||
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_depth = 0;
|
||||
@ -275,7 +276,7 @@ impl FutureMoves {
|
||||
self.arena
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find(|(_, node)| node.parent == self.current_root && node.coords() == (i, j))
|
||||
.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))
|
||||
@ -470,8 +471,7 @@ mod tests {
|
||||
let mut futm = FutureMoves::new(Piece::Black, FUTURE_MOVES_CONFIG);
|
||||
|
||||
futm.arena.push(Move {
|
||||
i: 0,
|
||||
j: 0,
|
||||
coord: None,
|
||||
board: Board::new(),
|
||||
winner: Winner::None,
|
||||
parent: None,
|
||||
@ -487,13 +487,12 @@ mod tests {
|
||||
|
||||
// child 1
|
||||
futm.arena
|
||||
.push(Move::new(0, 0, Board::new(), Piece::White, Piece::Black));
|
||||
.push(Move::new(None, Board::new(), Piece::White, Piece::Black));
|
||||
futm.set_parent_child(0, 1);
|
||||
|
||||
// dummy (2)
|
||||
futm.arena.push(Move::new(
|
||||
1234,
|
||||
1234,
|
||||
Some((1234, 1234)),
|
||||
Board::new(),
|
||||
Piece::White,
|
||||
Piece::Black,
|
||||
@ -501,12 +500,12 @@ mod tests {
|
||||
|
||||
// 3
|
||||
futm.arena
|
||||
.push(Move::new(0, 0, Board::new(), Piece::White, Piece::Black));
|
||||
.push(Move::new(None, Board::new(), Piece::White, Piece::Black));
|
||||
futm.set_parent_child(0, 3);
|
||||
|
||||
// 4
|
||||
futm.arena
|
||||
.push(Move::new(0, 0, Board::new(), Piece::White, Piece::Black));
|
||||
.push(Move::new(None, Board::new(), Piece::White, Piece::Black));
|
||||
futm.set_parent_child(0, 4);
|
||||
|
||||
assert_eq!(futm.arena_len(), 5);
|
||||
@ -515,7 +514,11 @@ mod tests {
|
||||
assert_eq!(futm.arena_len(), 4);
|
||||
assert_eq!(futm.arena[0].children.len(), 3);
|
||||
|
||||
assert_ne!(futm.arena[2].i, 1234, "dummy value still exists");
|
||||
assert_ne!(
|
||||
futm.arena[2].coord,
|
||||
Some((1234, 1234)),
|
||||
"dummy value still exists"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -524,8 +527,7 @@ mod tests {
|
||||
futm.config.max_depth = 1;
|
||||
|
||||
futm.arena.push(Move::new(
|
||||
0,
|
||||
0,
|
||||
None,
|
||||
Board::new().starting_pos(),
|
||||
Piece::Black,
|
||||
Piece::Black,
|
||||
@ -556,8 +558,7 @@ mod tests {
|
||||
let mut futm = FutureMoves::new(Piece::Black, FUTURE_MOVES_CONFIG);
|
||||
|
||||
futm.arena.push(Move {
|
||||
i: 0,
|
||||
j: 0,
|
||||
coord: None,
|
||||
board: Board::new(),
|
||||
winner: Winner::None,
|
||||
parent: None,
|
||||
@ -573,25 +574,20 @@ mod tests {
|
||||
|
||||
// child 1
|
||||
futm.arena
|
||||
.push(Move::new(0, 0, Board::new(), Piece::White, Piece::Black));
|
||||
.push(Move::new(None, Board::new(), Piece::White, Piece::Black));
|
||||
futm.set_parent_child(0, 1);
|
||||
|
||||
// dummy
|
||||
futm.arena.push(Move::new(
|
||||
1234,
|
||||
1234,
|
||||
Board::new(),
|
||||
Piece::White,
|
||||
Piece::Black,
|
||||
));
|
||||
futm.arena
|
||||
.push(Move::new(None, Board::new(), Piece::White, Piece::Black));
|
||||
|
||||
futm.arena
|
||||
.push(Move::new(0, 0, Board::new(), Piece::White, Piece::Black));
|
||||
.push(Move::new(None, Board::new(), Piece::White, Piece::Black));
|
||||
|
||||
futm.set_parent_child(1, 3);
|
||||
|
||||
futm.arena
|
||||
.push(Move::new(0, 0, Board::new(), Piece::White, Piece::Black));
|
||||
.push(Move::new(None, Board::new(), Piece::White, Piece::Black));
|
||||
|
||||
futm.set_parent_child(0, 4);
|
||||
|
||||
@ -603,8 +599,7 @@ mod tests {
|
||||
let mut futm = FutureMoves::new(Piece::Black, FUTURE_MOVES_CONFIG);
|
||||
|
||||
futm.arena.push(Move {
|
||||
i: 0,
|
||||
j: 0,
|
||||
coord: None,
|
||||
board: Board::new(),
|
||||
winner: Winner::None,
|
||||
parent: None,
|
||||
@ -620,20 +615,15 @@ mod tests {
|
||||
|
||||
// child 1
|
||||
futm.arena
|
||||
.push(Move::new(0, 0, Board::new(), Piece::White, Piece::Black));
|
||||
.push(Move::new(None, Board::new(), Piece::White, Piece::Black));
|
||||
futm.set_parent_child(0, 1);
|
||||
|
||||
// dummy
|
||||
futm.arena.push(Move::new(
|
||||
1234,
|
||||
1234,
|
||||
Board::new(),
|
||||
Piece::White,
|
||||
Piece::Black,
|
||||
));
|
||||
futm.arena
|
||||
.push(Move::new(None, Board::new(), Piece::White, Piece::Black));
|
||||
|
||||
futm.arena
|
||||
.push(Move::new(0, 0, Board::new(), Piece::White, Piece::Black));
|
||||
.push(Move::new(None, Board::new(), Piece::White, Piece::Black));
|
||||
futm.set_parent_child(1, 3);
|
||||
|
||||
assert_eq!(
|
||||
|
||||
@ -4,11 +4,8 @@ use lazy_static::lazy_static;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Move {
|
||||
/// `i` position of move
|
||||
pub i: usize,
|
||||
|
||||
/// `j` position of move
|
||||
pub j: usize,
|
||||
/// Coordinates (i, j) of the move (if it exists)
|
||||
pub coord: Option<(usize, usize)>,
|
||||
|
||||
/// [`Board`] state after move is made
|
||||
pub board: Board,
|
||||
@ -43,10 +40,14 @@ lazy_static! {
|
||||
}
|
||||
|
||||
impl Move {
|
||||
pub fn new(i: usize, j: usize, board: Board, color: Piece, agent_color: Piece) -> Self {
|
||||
pub fn new(
|
||||
coord: Option<(usize, usize)>,
|
||||
board: Board,
|
||||
color: Piece,
|
||||
agent_color: Piece,
|
||||
) -> Self {
|
||||
let mut m = Move {
|
||||
i,
|
||||
j,
|
||||
coord,
|
||||
board,
|
||||
winner: board.game_winner(),
|
||||
parent: None,
|
||||
@ -61,10 +62,6 @@ impl Move {
|
||||
m
|
||||
}
|
||||
|
||||
pub const fn coords(&self) -> (usize, usize) {
|
||||
(self.i, self.j)
|
||||
}
|
||||
|
||||
fn compute_self_value(&self, agent_color: Piece) -> i64 {
|
||||
if self.winner == Winner::Player(!agent_color) {
|
||||
// if this board results in the opponent winning, MAJORLY negatively weigh this move
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user