refactor chains file
This commit is contained in:
parent
c8ac4ce84b
commit
52cf81ec58
@ -1,106 +1,11 @@
|
|||||||
use super::{
|
use super::{
|
||||||
bitboard::BitBoard,
|
bitboard::BitBoard,
|
||||||
misc::get_index,
|
chains::{gen_adj_lookup, ChainCollection, PosMap},
|
||||||
misc::{diag_raw, split_from},
|
|
||||||
piece::Piece,
|
piece::Piece,
|
||||||
};
|
};
|
||||||
use arrayvec::ArrayVec;
|
|
||||||
use const_fn::const_fn;
|
use const_fn::const_fn;
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use std::{cmp::Ordering, collections::HashSet, fmt};
|
use std::{cmp::Ordering, fmt};
|
||||||
|
|
||||||
/// A chain of positions across the board
|
|
||||||
type Chain = ArrayVec<(usize, usize), { Board::BOARD_SIZE - 1 }>;
|
|
||||||
|
|
||||||
/// A collection of chains (up vert, down vert, left horiz, right horiz, diagonals....)
|
|
||||||
type ChainCollection = ArrayVec<Chain, 8>;
|
|
||||||
|
|
||||||
/// 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<T: Default>(ArrayVec<T, { Board::BOARD_AREA }>);
|
|
||||||
|
|
||||||
impl<T: Default> PosMap<T> {
|
|
||||||
#[allow(clippy::new_without_default)]
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self(ArrayVec::from_iter(
|
|
||||||
(0..Board::BOARD_AREA).map(|_| Default::default()),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get(&self, row: usize, col: usize) -> &T {
|
|
||||||
let index = get_index(row, col);
|
|
||||||
|
|
||||||
debug_assert!(
|
|
||||||
Board::BOARD_AREA + 1 >= index,
|
|
||||||
"index out of range, was: {}",
|
|
||||||
index
|
|
||||||
);
|
|
||||||
|
|
||||||
unsafe { self.0.get_unchecked(index) }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set(&mut self, row: usize, col: usize, value: T) {
|
|
||||||
let index = get_index(row, col);
|
|
||||||
debug_assert!(
|
|
||||||
Board::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
|
|
||||||
fn gen_adj_lookup() -> PosMap<ChainCollection> {
|
|
||||||
PosMap(
|
|
||||||
Board::all_positions()
|
|
||||||
.map(|(i, j)| {
|
|
||||||
let (i_chain, j_chain) = (
|
|
||||||
split_from(0..=Board::BOARD_SIZE - 1, i),
|
|
||||||
split_from(0..=Board::BOARD_SIZE - 1, j),
|
|
||||||
);
|
|
||||||
|
|
||||||
let chains: ChainCollection = ArrayVec::from_iter(
|
|
||||||
i_chain
|
|
||||||
.clone()
|
|
||||||
.into_iter()
|
|
||||||
.map(|range| range.map(move |i| (i, j)))
|
|
||||||
.map(Iterator::collect)
|
|
||||||
.chain(
|
|
||||||
j_chain
|
|
||||||
.clone()
|
|
||||||
.into_iter()
|
|
||||||
.map(|range| range.map(move |j| (i, j)))
|
|
||||||
.map(Iterator::collect),
|
|
||||||
)
|
|
||||||
.chain(diag_raw(i_chain, j_chain).map(Iterator::collect)),
|
|
||||||
);
|
|
||||||
|
|
||||||
// make sure all chains are in the proper range so we can ignore bounds checking later
|
|
||||||
assert!(
|
|
||||||
chains
|
|
||||||
.iter()
|
|
||||||
.flatten()
|
|
||||||
.flat_map(|(i, j)| [i, j]) // flatten to just numbers
|
|
||||||
.all(|x| (0..Board::BOARD_SIZE).contains(x)),
|
|
||||||
"chains go out-of-bounds"
|
|
||||||
);
|
|
||||||
|
|
||||||
// SAFETY! ensure all nodes in all chains are unique across chains, ensures beavior in
|
|
||||||
// [`Board::propegate_from`]
|
|
||||||
let mut uniq = HashSet::new();
|
|
||||||
assert!(
|
|
||||||
chains.iter().flatten().all(move |x| uniq.insert(x)),
|
|
||||||
"there are duplicate nodes in chain"
|
|
||||||
);
|
|
||||||
|
|
||||||
chains
|
|
||||||
})
|
|
||||||
.collect(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
|
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
|
||||||
pub enum Winner {
|
pub enum Winner {
|
||||||
|
|||||||
99
src/repr/chains.rs
Normal file
99
src/repr/chains.rs
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
use super::{
|
||||||
|
misc::{diag_raw, get_index, split_from},
|
||||||
|
Board,
|
||||||
|
};
|
||||||
|
use arrayvec::ArrayVec;
|
||||||
|
use std::collections::HashSet;
|
||||||
|
|
||||||
|
/// A chain of positions across the board
|
||||||
|
type Chain = ArrayVec<(usize, usize), { Board::BOARD_SIZE - 1 }>;
|
||||||
|
|
||||||
|
/// A collection of chains (up vert, down vert, left horiz, right horiz, diagonals....)
|
||||||
|
pub type ChainCollection = ArrayVec<Chain, 8>;
|
||||||
|
|
||||||
|
/// 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<T: Default>(ArrayVec<T, { Board::BOARD_AREA }>);
|
||||||
|
|
||||||
|
impl<T: Default> PosMap<T> {
|
||||||
|
#[allow(clippy::new_without_default)]
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self(ArrayVec::from_iter(
|
||||||
|
(0..Board::BOARD_AREA).map(|_| Default::default()),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get(&self, row: usize, col: usize) -> &T {
|
||||||
|
let index = get_index(row, col);
|
||||||
|
|
||||||
|
debug_assert!(
|
||||||
|
Board::BOARD_AREA + 1 >= index,
|
||||||
|
"index out of range, was: {}",
|
||||||
|
index
|
||||||
|
);
|
||||||
|
|
||||||
|
unsafe { self.0.get_unchecked(index) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set(&mut self, row: usize, col: usize, value: T) {
|
||||||
|
let index = get_index(row, col);
|
||||||
|
debug_assert!(
|
||||||
|
Board::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
|
||||||
|
pub fn gen_adj_lookup() -> PosMap<ChainCollection> {
|
||||||
|
PosMap(
|
||||||
|
Board::all_positions()
|
||||||
|
.map(|(i, j)| {
|
||||||
|
let (i_chain, j_chain) = (
|
||||||
|
split_from(0..=Board::BOARD_SIZE - 1, i),
|
||||||
|
split_from(0..=Board::BOARD_SIZE - 1, j),
|
||||||
|
);
|
||||||
|
|
||||||
|
let chains: ChainCollection = ArrayVec::from_iter(
|
||||||
|
i_chain
|
||||||
|
.clone()
|
||||||
|
.into_iter()
|
||||||
|
.map(|range| range.map(move |i| (i, j)))
|
||||||
|
.map(Iterator::collect)
|
||||||
|
.chain(
|
||||||
|
j_chain
|
||||||
|
.clone()
|
||||||
|
.into_iter()
|
||||||
|
.map(|range| range.map(move |j| (i, j)))
|
||||||
|
.map(Iterator::collect),
|
||||||
|
)
|
||||||
|
.chain(diag_raw(i_chain, j_chain).map(Iterator::collect)),
|
||||||
|
);
|
||||||
|
|
||||||
|
// make sure all chains are in the proper range so we can ignore bounds checking later
|
||||||
|
assert!(
|
||||||
|
chains
|
||||||
|
.iter()
|
||||||
|
.flatten()
|
||||||
|
.flat_map(|(i, j)| [i, j]) // flatten to just numbers
|
||||||
|
.all(|x| (0..Board::BOARD_SIZE).contains(x)),
|
||||||
|
"chains go out-of-bounds"
|
||||||
|
);
|
||||||
|
|
||||||
|
// SAFETY! ensure all nodes in all chains are unique across chains, ensures beavior in
|
||||||
|
// [`Board::propegate_from`]
|
||||||
|
let mut uniq = HashSet::new();
|
||||||
|
assert!(
|
||||||
|
chains.iter().flatten().all(move |x| uniq.insert(x)),
|
||||||
|
"there are duplicate nodes in chain"
|
||||||
|
);
|
||||||
|
|
||||||
|
chains
|
||||||
|
})
|
||||||
|
.collect(),
|
||||||
|
)
|
||||||
|
}
|
||||||
@ -1,7 +1,9 @@
|
|||||||
mod bitboard;
|
mod bitboard;
|
||||||
mod board;
|
mod board;
|
||||||
|
mod chains;
|
||||||
mod misc;
|
mod misc;
|
||||||
mod piece;
|
mod piece;
|
||||||
|
|
||||||
pub use board::{Board, PosMap, Winner};
|
pub use board::{Board, Winner};
|
||||||
|
pub use chains::PosMap;
|
||||||
pub use piece::Piece;
|
pub use piece::Piece;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user