logic fixes and nits
This commit is contained in:
parent
ca423942c8
commit
7992aca803
79
src/board.rs
79
src/board.rs
@ -4,7 +4,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use arrayvec::ArrayVec;
|
use arrayvec::ArrayVec;
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use std::{cmp::Ordering, fmt};
|
use std::{cmp::Ordering, fmt, mem::MaybeUninit};
|
||||||
|
|
||||||
pub const BOARD_SIZE: usize = 8;
|
pub const BOARD_SIZE: usize = 8;
|
||||||
|
|
||||||
@ -19,50 +19,43 @@ type ChainCollection = ArrayVec<Chain, 8>;
|
|||||||
/// with each coordinate
|
/// with each coordinate
|
||||||
type PosMap<T> = ArrayVec<ArrayVec<T, BOARD_SIZE>, BOARD_SIZE>;
|
type PosMap<T> = ArrayVec<ArrayVec<T, BOARD_SIZE>, BOARD_SIZE>;
|
||||||
|
|
||||||
|
fn gen_adj_lookup() -> PosMap<ChainCollection> {
|
||||||
|
(0..BOARD_SIZE)
|
||||||
|
.map(|i| {
|
||||||
|
(0..BOARD_SIZE)
|
||||||
|
.map(|j| {
|
||||||
|
let (i_chain, j_chain) = (
|
||||||
|
split_from(0..=BOARD_SIZE - 1, i),
|
||||||
|
split_from(0..=BOARD_SIZE - 1, j),
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut chains: ChainCollection = ArrayVec::new_const();
|
||||||
|
|
||||||
|
chains.extend(
|
||||||
|
i_chain
|
||||||
|
.clone()
|
||||||
|
.map(|range| range.map(move |i| (i, j)))
|
||||||
|
.map(Iterator::collect),
|
||||||
|
);
|
||||||
|
chains.extend(
|
||||||
|
j_chain
|
||||||
|
.clone()
|
||||||
|
.map(|range| range.map(move |j| (i, j)))
|
||||||
|
.map(Iterator::collect),
|
||||||
|
);
|
||||||
|
|
||||||
|
// handle diagonals
|
||||||
|
chains.extend(diag_raw(i_chain, j_chain).map(Iterator::collect));
|
||||||
|
chains
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
/// Precompute all possible chains for each position on the board
|
/// Precompute all possible chains for each position on the board
|
||||||
pub static ref ADJ_LOOKUP: PosMap<ChainCollection> = {
|
pub static ref ADJ_LOOKUP: PosMap<ChainCollection> = gen_adj_lookup();
|
||||||
let mut output = ArrayVec::new();
|
|
||||||
|
|
||||||
// populate arrayvec as we index it [i][j]
|
|
||||||
for _ in 0..BOARD_SIZE {
|
|
||||||
let mut a = ArrayVec::new();
|
|
||||||
// [j]
|
|
||||||
for _ in 0..BOARD_SIZE {
|
|
||||||
a.push(ArrayVec::new());
|
|
||||||
}
|
|
||||||
output.push(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i, j) in Board::all_positions() {
|
|
||||||
let (i_chain, j_chain) = (
|
|
||||||
split_from(0..=BOARD_SIZE - 1, i),
|
|
||||||
split_from(0..=BOARD_SIZE - 1, j),
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut chains: ChainCollection = ArrayVec::new_const();
|
|
||||||
|
|
||||||
chains.extend(
|
|
||||||
i_chain
|
|
||||||
.clone()
|
|
||||||
.map(|range| range.map(move |i| (i, j)))
|
|
||||||
.map(Iterator::collect),
|
|
||||||
);
|
|
||||||
chains.extend(
|
|
||||||
j_chain
|
|
||||||
.clone()
|
|
||||||
.map(|range| range.map(move |j| (i, j)))
|
|
||||||
.map(Iterator::collect),
|
|
||||||
);
|
|
||||||
|
|
||||||
// handle diagonals
|
|
||||||
chains.extend(diag_raw(i_chain, j_chain).map(Iterator::collect));
|
|
||||||
|
|
||||||
output[i][j] = chains;
|
|
||||||
}
|
|
||||||
|
|
||||||
output
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||||
|
|||||||
@ -142,11 +142,8 @@ impl FutureMoves {
|
|||||||
|
|
||||||
fn compute_values(&mut self) {
|
fn compute_values(&mut self) {
|
||||||
for depth in (0..=self.current_depth).rev() {
|
for depth in (0..=self.current_depth).rev() {
|
||||||
let nodes_at_depth: Vec<usize> = self
|
let nodes_at_depth: Vec<usize> = (0..self.arena.len())
|
||||||
.arena
|
.filter(|&idx| self.depth_of(idx) == depth)
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.filter_map(|(idx, node)| (self.depth_of(node.parent) == depth).then_some(idx))
|
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
for idx in nodes_at_depth {
|
for idx in nodes_at_depth {
|
||||||
@ -166,9 +163,10 @@ impl FutureMoves {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn depth_of(&self, node_parent: Option<usize>) -> usize {
|
/// Given an index from `self.arena`, what depth is it at? 0-indexed
|
||||||
|
fn depth_of(&self, node_parent: usize) -> usize {
|
||||||
let mut depth = 0;
|
let mut depth = 0;
|
||||||
let mut current = node_parent;
|
let mut current = Some(node_parent);
|
||||||
while let Some(parent_idx) = current {
|
while let Some(parent_idx) = current {
|
||||||
depth += 1;
|
depth += 1;
|
||||||
current = self.arena[parent_idx].parent;
|
current = self.arena[parent_idx].parent;
|
||||||
@ -203,7 +201,7 @@ impl FutureMoves {
|
|||||||
})
|
})
|
||||||
.inspect(|&root| {
|
.inspect(|&root| {
|
||||||
self.current_root = Some(root);
|
self.current_root = Some(root);
|
||||||
self.current_depth = self.max_depth - self.depth_of(Some(root));
|
self.current_depth = self.max_depth - self.depth_of(root);
|
||||||
self.prune_unrelated();
|
self.prune_unrelated();
|
||||||
})
|
})
|
||||||
.is_some()
|
.is_some()
|
||||||
@ -254,8 +252,8 @@ pub struct ComplexAgent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ComplexAgent {
|
impl ComplexAgent {
|
||||||
pub fn new(color: Piece) -> Self {
|
pub const fn new(color: Piece) -> Self {
|
||||||
const MAX_DEPTH: usize = 6;
|
const MAX_DEPTH: usize = 8;
|
||||||
Self {
|
Self {
|
||||||
color,
|
color,
|
||||||
future_moves: FutureMoves::new(color, MAX_DEPTH),
|
future_moves: FutureMoves::new(color, MAX_DEPTH),
|
||||||
|
|||||||
@ -11,8 +11,8 @@ mod piece;
|
|||||||
fn main() {
|
fn main() {
|
||||||
let player1 = complexagent::ComplexAgent::new(Piece::Black);
|
let player1 = complexagent::ComplexAgent::new(Piece::Black);
|
||||||
// let player2 = complexagent::ComplexAgent::new(Piece::White);
|
// let player2 = complexagent::ComplexAgent::new(Piece::White);
|
||||||
// let player2 = agent::ManualAgent::new(Piece::White);
|
let player2 = agent::ManualAgent::new(Piece::White);
|
||||||
let player2 = agent::RandomAgent::new(Piece::White);
|
// let player2 = agent::RandomAgent::new(Piece::White);
|
||||||
let mut game = Game::new(Box::new(player1), Box::new(player2));
|
let mut game = Game::new(Box::new(player1), Box::new(player2));
|
||||||
game.game_loop();
|
game.game_loop();
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user