From e1d83825b7e646ac623ea0131cb0a6a8eed02c40 Mon Sep 17 00:00:00 2001 From: Simon Gardling Date: Thu, 20 Feb 2025 16:40:11 -0500 Subject: [PATCH] initial BVM usage (halfs performance :( ) --- src/logic/board_value.rs | 29 +++++++++++++++++++++-------- src/logic/move.rs | 21 +++++++++------------ src/repr/board.rs | 27 ++++++++++++++++++++++++--- 3 files changed, 54 insertions(+), 23 deletions(-) diff --git a/src/logic/board_value.rs b/src/logic/board_value.rs index 62d9ae5..b837990 100644 --- a/src/logic/board_value.rs +++ b/src/logic/board_value.rs @@ -1,20 +1,33 @@ use crate::repr::{Board, Piece, PosMap}; -pub struct BoardValueMap(PosMap); +pub struct BoardValueMap(PosMap); impl BoardValueMap { - pub fn board_value(&self, board: &Board, color: Piece) -> f32 { - let mut board_value: f32 = 0.0; - for (i, j) in Board::all_positions() { - if let Some(pos_p) = board.get(i, j) { + pub fn board_value(&self, board: &Board, color: Piece) -> i8 { + Board::all_positions() + .filter_map(|(i, j)| board.get(i, j).map(|p| (i, j, p))) + .map(|(i, j, pos_p)| { let mut value = *self.0.get(i, j); if pos_p != color { // enemy has position value = -value; } - board_value += value; - } + value + }) + .sum() + } + + pub fn new() -> Self { + let mut map = PosMap::new(); + + for (i, j) in Board::all_positions() { + map.set(i, j, 1); } - board_value + + for (i, j) in Board::sides() { + map.set(i, j, 4); + } + + Self(map) } } diff --git a/src/logic/move.rs b/src/logic/move.rs index 2ae9e26..0794ad3 100644 --- a/src/logic/move.rs +++ b/src/logic/move.rs @@ -1,5 +1,9 @@ +use lazy_static::lazy_static; + use crate::repr::{Board, Piece, Winner}; +use super::board_value::BoardValueMap; + #[derive(Clone, Debug)] pub struct Move { /// `i` position of move @@ -28,6 +32,10 @@ pub struct Move { pub lazy_children: bool, } +lazy_static! { + static ref BVM: BoardValueMap = BoardValueMap::new(); +} + impl Move { pub const fn coords(&self) -> (usize, usize) { (self.i, self.j) @@ -47,17 +55,6 @@ impl Move { return 0; } - let mut self_value = self.board.net_score(agent_color) as i64; - let corner_v_agent = Board::sides() - .filter(|&(i, j)| self.board.get_piece(i, j, agent_color)) - .count() as i64; - let corner_v_not_agent = Board::sides() - .filter(|&(i, j)| self.board.get_piece(i, j, !agent_color)) - .count() as i64; - - // make net-corner capture important - self_value += (corner_v_agent - corner_v_not_agent) * 4; - - self_value + BVM.board_value(&self.board, agent_color) as i64 } } diff --git a/src/repr/board.rs b/src/repr/board.rs index 85d95a2..a368ae1 100644 --- a/src/repr/board.rs +++ b/src/repr/board.rs @@ -26,11 +26,21 @@ type ChainCollection = ArrayVec; /// Map of all points on the board against some type T /// Used to index like so: example[i][j] /// with each coordinate -pub struct PosMap(ArrayVec); +pub struct PosMap(ArrayVec); + +impl PosMap { + const fn index(row: usize, col: usize) -> usize { + row * BOARD_SIZE + col + } + + pub fn new() -> Self { + Self(ArrayVec::from_iter( + (0..BOARD_AREA).map(|_| Default::default()), + )) + } -impl PosMap { pub fn get(&self, row: usize, col: usize) -> &T { - let index = row * BOARD_SIZE + col; + let index = Self::index(row, col); debug_assert!( BOARD_AREA + 1 >= index, @@ -40,6 +50,17 @@ impl PosMap { unsafe { self.0.get_unchecked(index) } } + + pub fn set(&mut self, row: usize, col: usize, value: T) { + let index = Self::index(row, col); + debug_assert!( + BOARD_AREA + 1 >= index, + "index out of range, was: {}", + index + ); + + self.0[index] = value; + } } /// Creates a lookup map for adjacencies and chains from each position on the board