You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

105 lines
2.3 KiB

use enum_map::Enum;
use strum_macros::EnumIter;
#[derive(Clone, Copy, Enum, Eq, PartialEq)]
pub enum State {
Dead = 0,
Alive = 1,
}
impl Default for State {
fn default() -> Self { Self::Dead }
}
impl State {
fn from_number(number: u8) -> Self {
match number {
0 => Self::Dead,
1 => Self::Alive,
_ => panic!("unsupported number {}", number),
}
}
fn get_number(&self) -> u8 {
*self as u8
}
}
// terribly error-prone but I'm lazy :(
#[derive(Copy, Clone, Enum, EnumIter)]
pub enum Direction {
MinusMinusMinus = 0,
MinusMinusSame = 1,
MinusMinusPlus = 2,
MinusSameMinus = 3,
MinusSameSame = 4,
MinusSamePlus = 5,
MinusPlusMinus = 6,
MinusPlusSame = 7,
MinusPlusPlus = 8,
SameMinusMinus = 9,
SameMinusSame = 10,
SameMinusPlus = 11,
SameSameMinus = 12,
SameSamePlus = 13,
SamePlusMinus = 14,
SamePlusSame = 15,
SamePlusPlus = 16,
PlusMinusMinus = 17,
PlusMinusSame = 18,
PlusMinusPlus = 19,
PlusSameMinus = 20,
PlusSameSame = 21,
PlusSamePlus = 22,
PlusPlusMinus = 23,
PlusPlusSame = 24,
PlusPlusPlus = 25,
}
impl Direction {
fn get_offset(&self) -> u16 {
*self as u16
}
}
pub struct CellState {
neighbours_states: u32,
state: u8,
}
impl CellState {
pub fn new() -> Self {
Self {
neighbours_states: 0,
state: 0,
}
}
pub fn update_neighbour_state(&mut self, direction: Direction, new_state: State) -> () {
self.neighbours_states = (self.neighbours_states & !(0b1 << direction.get_offset())) | ((new_state.get_number() as u32) << direction.get_offset());
}
pub fn update_state(&mut self, new_state: State) {
self.state = new_state.get_number();
}
pub fn from_number(number: u32) -> Self {
CellState {
state: (number >> 26) as u8,
neighbours_states: (number & 0x3ffffff) as u32,
}
}
pub fn get_number(&self) -> u32 {
((self.state as u32) << 26) | (self.neighbours_states as u32)
}
pub fn get_state(&self) -> State {
State::from_number(self.state)
}
pub fn get_neighbour_state(&self, direction: Direction) -> State {
State::from_number(((self.neighbours_states >> direction.get_offset()) & 0b1) as u8)
}
}