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.
106 lines
2.3 KiB
106 lines
2.3 KiB
3 years ago
|
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)
|
||
|
}
|
||
|
}
|
||
|
|