touchups
This commit is contained in:
81
src/board.rs
81
src/board.rs
@@ -2,10 +2,51 @@ use crate::{
|
||||
misc::{diag_raw, split_from},
|
||||
piece::Piece,
|
||||
};
|
||||
use std::{cmp::Ordering, fmt};
|
||||
|
||||
use arrayvec::ArrayVec;
|
||||
use lazy_static::lazy_static;
|
||||
use std::{cmp::Ordering, collections::HashMap, fmt};
|
||||
pub const BOARD_SIZE: usize = 8;
|
||||
|
||||
/// A chain of positions across the board
|
||||
type Chain = ArrayVec<(usize, usize), BOARD_SIZE>;
|
||||
|
||||
/// A collection of chains (up vert, down vert, left horiz, right horiz, diagonals....)
|
||||
type ChainCollection = ArrayVec<Chain, 8>;
|
||||
|
||||
lazy_static! {
|
||||
/// Precompute all possible chains for each position on the board
|
||||
pub static ref ADJ_LOOKUP: HashMap<(usize, usize), ChainCollection> = {
|
||||
let mut output = HashMap::new();
|
||||
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.insert((i, j), chains);
|
||||
}
|
||||
|
||||
output
|
||||
};
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
pub struct Board {
|
||||
board: [[Option<Piece>; BOARD_SIZE]; BOARD_SIZE],
|
||||
@@ -68,10 +109,12 @@ impl Board {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn all_positions() -> impl Iterator<Item = (usize, usize)> {
|
||||
(0..BOARD_SIZE).flat_map(|i| (0..BOARD_SIZE).map(move |j| (i, j)))
|
||||
}
|
||||
|
||||
pub fn possible_moves(&self, color: Piece) -> impl Iterator<Item = (usize, usize)> + use<'_> {
|
||||
(0..BOARD_SIZE)
|
||||
.flat_map(|i| (0..BOARD_SIZE).map(move |j| (i, j)))
|
||||
.filter(move |(i, j)| self.would_prop(*i, *j, color))
|
||||
Self::all_positions().filter(move |(i, j)| self.would_prop(*i, *j, color))
|
||||
}
|
||||
|
||||
/// Returns a mutable reference to a place on the [`Board`]
|
||||
@@ -138,29 +181,7 @@ impl Board {
|
||||
// NOTE! got it down to 24.86% (61.1% decrease) with allocator optimizations
|
||||
// IDEAS: early-exit from each chain so we don't have to call `diag` (which allocs a lot and uses a lot of cycles)
|
||||
fn propegate_from_dry(&self, i: usize, j: usize, starting_color: Piece) -> Vec<(usize, usize)> {
|
||||
// Create all chains from the piece being propegated from in `i` and `j` coordinates
|
||||
let (i_chain, j_chain) = (
|
||||
split_from(0, BOARD_SIZE - 1, i),
|
||||
split_from(0, BOARD_SIZE - 1, j),
|
||||
);
|
||||
|
||||
let mut chains: Vec<Vec<(usize, usize)>> = Vec::with_capacity(8);
|
||||
|
||||
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));
|
||||
let chains = ADJ_LOOKUP.get(&(i, j)).unwrap();
|
||||
|
||||
// Longest chain is (BOARD_SIZE - 2) as there needs to be the two pieces containing it
|
||||
let mut fill: Vec<(usize, usize)> = Vec::with_capacity((BOARD_SIZE - 2) * chains.len());
|
||||
@@ -176,9 +197,7 @@ impl Board {
|
||||
// get history of this chain
|
||||
if let Some(history) = chain.get(..chain_length) {
|
||||
// fill all opposite colors with this color
|
||||
for &(i_o, j_o) in history {
|
||||
fill.push((i_o, j_o));
|
||||
}
|
||||
fill.extend(history);
|
||||
}
|
||||
|
||||
// either the other pieces were replaced, or this was an invalid chain,
|
||||
|
||||
Reference in New Issue
Block a user