use super::Score;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[repr(u8)]
#[allow(dead_code)] pub(super) enum Dir {
None = 0,
Diag = 1,
Up = 2,
Left = 3,
}
#[derive(Copy, Clone)]
pub(super) struct Cell(u32);
pub(super) const CELL_ZERO: Cell = Cell::new(0, Dir::None);
impl std::fmt::Debug for Cell {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Cell")
.field("score", &self.score())
.field("dir", &self.dir())
.finish()
}
}
impl Cell {
#[inline(always)]
pub(super) const fn new(score: Score, dir: Dir) -> Cell {
Cell((score as u16 as u32) | ((dir as u32) << 16))
}
#[inline(always)]
pub(super) fn score(self) -> Score {
self.0 as u16 as i16
}
#[inline(always)]
pub(super) fn dir(self) -> Dir {
unsafe { std::mem::transmute((self.0 >> 16) as u8 & 0x3) }
}
#[inline(always)]
pub(super) fn is_diag(self) -> bool {
(self.0 >> 16) & 0x3 == 1
}
}
#[derive(Default, Debug)]
pub(super) struct SWMatrix {
pub(super) data: Vec<Cell>,
pub(super) cols: usize,
pub(super) rows: usize,
}
impl SWMatrix {
pub fn zero(rows: usize, cols: usize) -> Self {
let mut res = SWMatrix::default();
res.resize(rows, cols);
res
}
pub fn resize(&mut self, rows: usize, cols: usize) {
let needed = rows * cols;
if needed > self.data.len() {
self.data.resize(needed, CELL_ZERO);
}
self.rows = rows;
self.cols = cols;
}
}