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.
104 lines
2.3 KiB
104 lines
2.3 KiB
use enum_map::Enum;
|
|
use strum_macros::EnumIter;
|
|
|
|
#[derive(Clone, Copy, Enum, Eq, PartialEq)]
|
|
pub enum State {
|
|
None,
|
|
Floor,
|
|
SeatEmpty,
|
|
SeatOccupied,
|
|
}
|
|
|
|
impl Default for State {
|
|
fn default() -> Self { Self::None }
|
|
}
|
|
|
|
impl State {
|
|
fn from_number(number: u8) -> Self {
|
|
match number {
|
|
0 => Self::None,
|
|
1 => Self::Floor,
|
|
2 => Self::SeatEmpty,
|
|
3 => Self::SeatOccupied,
|
|
_ => panic!("unsupported number {}", number),
|
|
}
|
|
}
|
|
|
|
fn get_number(&self) -> u8 {
|
|
match self {
|
|
Self::None => 0, // border should always be 0
|
|
Self::Floor => 1,
|
|
Self::SeatEmpty => 2,
|
|
Self::SeatOccupied => 3,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Copy, Clone, Enum, EnumIter)]
|
|
pub enum Direction {
|
|
UpLeft,
|
|
Up,
|
|
UpRight,
|
|
Left,
|
|
Right,
|
|
DownLeft,
|
|
Down,
|
|
DownRight,
|
|
}
|
|
|
|
impl Direction {
|
|
fn get_offset(&self) -> u16 {
|
|
match self {
|
|
Self::UpLeft => 0,
|
|
Self::Up => 2,
|
|
Self::UpRight => 4,
|
|
Self::Left => 6,
|
|
Self::Right => 8,
|
|
Self::DownLeft => 10,
|
|
Self::Down => 12,
|
|
Self::DownRight => 14,
|
|
}
|
|
}
|
|
}
|
|
|
|
pub struct CellState {
|
|
neighbours_states: u16,
|
|
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 & !(0b11 << direction.get_offset())) | ((new_state.get_number() as u16) << 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 >> 16) as u8,
|
|
neighbours_states: (number & 0xffff) as u16,
|
|
}
|
|
}
|
|
|
|
pub fn get_number(&self) -> u32 {
|
|
((self.state as u32) << 16) | (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()) & 0b11) as u8)
|
|
}
|
|
}
|
|
|
|
|