abstract away more coordinates
This commit is contained in:
@@ -5,8 +5,8 @@ pub struct BoardValueMap(PosMap<i64>);
|
||||
impl BoardValueMap {
|
||||
pub fn board_value(&self, board: &Board, color: Piece) -> i64 {
|
||||
Board::all_positions()
|
||||
.filter_map(|(i, j)| board.get(i, j).map(|p| (i, j, p)))
|
||||
.map(|(i, j, pos_p)| (*self.0.get(i, j), pos_p))
|
||||
.filter_map(|coord| board.get(coord).map(|p| (coord, p)))
|
||||
.map(|(coord, pos_p)| (*self.0.get(coord), pos_p))
|
||||
.map(|(value, pos_p)| {
|
||||
if pos_p != color {
|
||||
// enemy has position
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
logic::r#move::Move,
|
||||
repr::{Board, Coord, Piece, Winner},
|
||||
repr::{Board, CoordPair, Piece, Winner},
|
||||
};
|
||||
use indicatif::{ProgressIterator, ProgressStyle};
|
||||
use std::{collections::HashMap, hash::BuildHasherDefault, ops::ControlFlow};
|
||||
@@ -94,10 +94,10 @@ impl FutureMoves {
|
||||
}
|
||||
});
|
||||
|
||||
self.prune_bad_children();
|
||||
// self.prune_bad_children();
|
||||
self.current_depth += 1;
|
||||
if cf.is_break() {
|
||||
dbg!("extend_layers: early break ({})", self.arena_len());
|
||||
println!("extend_layers: early break");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -130,14 +130,14 @@ 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 mut new: Vec<Move> = Board::all_positions()
|
||||
.flat_map(|(i, j)| {
|
||||
.flat_map(|coord| {
|
||||
parent
|
||||
.board
|
||||
.what_if(i, j, new_color)
|
||||
.map(move |x| (i, j, x))
|
||||
.what_if(coord, new_color)
|
||||
.map(move |x| (coord, x))
|
||||
})
|
||||
.map(|(i, j, new_board)| {
|
||||
Move::new(Some((i, j)), new_board, new_color, self.agent_color)
|
||||
.map(|(coord, new_board)| {
|
||||
Move::new(Some(coord), new_board, new_color, self.agent_color)
|
||||
})
|
||||
.collect();
|
||||
|
||||
@@ -200,32 +200,26 @@ impl FutureMoves {
|
||||
// reversed so we build up the value of the closest (in time) moves from the future
|
||||
for (depth, nodes) in by_depth_vec.into_iter().rev() {
|
||||
for idx in nodes {
|
||||
// TODO! impl dynamic sorting based on children's states, maybe it propegates
|
||||
// upwards using the `parent` field
|
||||
|
||||
// let mut parent_copy = self.arena[idx].clone();
|
||||
// parent_copy.sort_children(self.arena.as_mut_slice());
|
||||
// self.arena[idx] = parent_copy;
|
||||
|
||||
let children_value = self.arena[idx]
|
||||
.children
|
||||
.iter()
|
||||
.map(|&child| self.arena[child].value.expect("child has no value??"))
|
||||
.sum::<i128>();
|
||||
// average value of children
|
||||
.sum::<i128>()
|
||||
.checked_div(self.arena[idx].children.len() as i128)
|
||||
.unwrap_or(0);
|
||||
|
||||
// we use `depth` and divided `self_value` by it, idk if this is worth it
|
||||
// we should really setup some sort of ELO rating for each commit, playing them against
|
||||
// each other or something, could be cool to benchmark these more subjective things, not
|
||||
// just performance (cycles/time wise)
|
||||
self.arena[idx].value = Some(
|
||||
(self.arena[idx].self_value as i128 + children_value) / (depth + 1) as i128,
|
||||
);
|
||||
self.arena[idx].value = Some(self.arena[idx].self_value as i128 + children_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the best move which is a child of `self.current_root`
|
||||
pub fn best_move(&self) -> Option<Option<(Coord, Coord)>> {
|
||||
pub fn best_move(&self) -> Option<Option<CoordPair>> {
|
||||
self.current_root
|
||||
.and_then(|x| {
|
||||
self.arena[x]
|
||||
@@ -256,11 +250,11 @@ impl FutureMoves {
|
||||
|
||||
if let Some(curr_board_idx) = curr_board {
|
||||
self.set_root_idx_raw(curr_board_idx);
|
||||
return false;
|
||||
false
|
||||
} else {
|
||||
dbg!("regenerating arena from board");
|
||||
println!("regenerating arena from board");
|
||||
self.set_root_from_board(*board);
|
||||
return true;
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -269,6 +263,7 @@ impl FutureMoves {
|
||||
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_depth = 0;
|
||||
@@ -291,7 +286,7 @@ impl FutureMoves {
|
||||
self.compute_values(0..self.arena.len());
|
||||
|
||||
// check arena's consistancy
|
||||
assert_eq!(self.check_arena().join("\n"), "");
|
||||
debug_assert_eq!(self.check_arena().join("\n"), "");
|
||||
}
|
||||
|
||||
pub fn set_parent_child(&mut self, parent: usize, child: usize) {
|
||||
@@ -485,7 +480,7 @@ mod tests {
|
||||
|
||||
// dummy (2)
|
||||
futm.arena.push(Move::new(
|
||||
Some((123, 123)),
|
||||
Some((9, 9).into()),
|
||||
Board::new(),
|
||||
Piece::White,
|
||||
Piece::Black,
|
||||
@@ -509,7 +504,7 @@ mod tests {
|
||||
|
||||
assert_ne!(
|
||||
futm.arena[2].coord,
|
||||
Some((123, 123)),
|
||||
Some((9, 9).into()),
|
||||
"dummy value still exists"
|
||||
);
|
||||
}
|
||||
@@ -682,8 +677,8 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
if let Some((i, j)) = coords {
|
||||
board.place(i, j, color).unwrap();
|
||||
if let Some(coord) = coords {
|
||||
board.place(coord.into(), color).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
use super::board_value::BoardValueMap;
|
||||
use crate::repr::{Board, Coord, Piece, Winner};
|
||||
use crate::repr::{Board, CoordPair, Piece, Winner};
|
||||
use lazy_static::lazy_static;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Move {
|
||||
/// Coordinates (i, j) of the move (if it exists)
|
||||
pub coord: Option<(Coord, Coord)>,
|
||||
pub coord: Option<CoordPair>,
|
||||
|
||||
/// [`Board`] state after move is made
|
||||
pub board: Board,
|
||||
@@ -40,12 +40,7 @@ lazy_static! {
|
||||
}
|
||||
|
||||
impl Move {
|
||||
pub fn new(
|
||||
coord: Option<(Coord, Coord)>,
|
||||
board: Board,
|
||||
color: Piece,
|
||||
agent_color: Piece,
|
||||
) -> Self {
|
||||
pub fn new(coord: Option<CoordPair>, board: Board, color: Piece, agent_color: Piece) -> Self {
|
||||
let mut m = Move {
|
||||
coord,
|
||||
board,
|
||||
|
||||
Reference in New Issue
Block a user