69 lines
1.7 KiB
Rust
69 lines
1.7 KiB
Rust
use super::Board;
|
|
use num::Integer;
|
|
use static_assertions::const_assert;
|
|
|
|
/// PERF! having `Coord` be of type `u8` (instead of usize) increases
|
|
/// performance by about 1-2% overall
|
|
pub type CoordAxis = u8;
|
|
|
|
/// using u8 for this results in a ~3-6% perf increase
|
|
pub type CoordPairInner = u8;
|
|
|
|
const_assert!(CoordPairInner::MAX as usize >= Board::AREA.0 as usize);
|
|
|
|
#[derive(PartialEq, Eq, Copy, Clone, Hash)]
|
|
pub struct CoordPair(pub CoordPairInner);
|
|
|
|
impl CoordPair {
|
|
/// Convert a row and column to an index in the board
|
|
pub const fn from_axes(row: CoordAxis, col: CoordAxis) -> Self {
|
|
Self(row * Board::SIZE + col)
|
|
}
|
|
|
|
#[allow(clippy::wrong_self_convention)]
|
|
fn into_indexes(&self) -> (CoordAxis, CoordAxis) {
|
|
self.0.div_mod_floor(&Board::SIZE)
|
|
}
|
|
|
|
pub const fn area(pos: CoordAxis) -> Self {
|
|
Self(pos.pow(2) as CoordPairInner)
|
|
}
|
|
}
|
|
|
|
impl std::fmt::Display for CoordPair {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
let (i, j) = (*self).into();
|
|
write!(f, "({}, {})", i, j)
|
|
}
|
|
}
|
|
|
|
impl std::fmt::Debug for CoordPair {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
write!(f, "{}", self)
|
|
}
|
|
}
|
|
|
|
impl From<CoordPair> for (CoordAxis, CoordAxis) {
|
|
fn from(val: CoordPair) -> Self {
|
|
val.into_indexes()
|
|
}
|
|
}
|
|
|
|
impl From<(CoordAxis, CoordAxis)> for CoordPair {
|
|
fn from(value: (CoordAxis, CoordAxis)) -> Self {
|
|
Self::from_axes(value.0, value.1)
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn into_out_of() {
|
|
let a: CoordPair = (1, 3).into();
|
|
let back: (CoordAxis, CoordAxis) = a.into();
|
|
assert_eq!(back, (1, 3));
|
|
}
|
|
}
|