use crate::prelude::*; use serde::{Deserialize, Serialize}; #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Deserialize, Serialize)] #[cfg_attr(test, derive(proptest_derive::Arbitrary))] pub enum Direction { Up, Right, Down, Left, } impl Direction { pub fn from_neighbors(pos: &Position, neighbor: &Position) -> Self { let x_diff = pos.x as i64 - neighbor.x as i64; let y_diff = pos.y as i64 - neighbor.y as i64; match (x_diff, y_diff) { (1, 0) => Direction::Left, (0, 1) => Direction::Up, (-1, 0) => Direction::Right, (0, -1) => Direction::Down, _ => { panic!("Positions are not neighbors.") } } } pub fn vertical(&self) -> bool { match self { Direction::Up => true, Direction::Right => false, Direction::Down => true, Direction::Left => false, } } pub fn horizontal(&self) -> bool { !self.vertical() } pub fn reverse(&self) -> Self { match self { Direction::Up => Direction::Down, Direction::Right => Direction::Left, Direction::Down => Direction::Up, Direction::Left => Direction::Right, } } pub fn clockwise(&self) -> Self { match self { Direction::Up => Direction::Right, Direction::Right => Direction::Down, Direction::Down => Direction::Left, Direction::Left => Direction::Up, } } pub fn counter_clockwise(&self) -> Self { match self { Direction::Up => Direction::Left, Direction::Right => Direction::Up, Direction::Down => Direction::Right, Direction::Left => Direction::Down, } } pub fn get_index(&self) -> u8 { match self { Direction::Up => 0, Direction::Right => 1, Direction::Down => 2, Direction::Left => 3, } } pub fn from_index(i: u8) -> Self { match i { 0 => Direction::Up, 1 => Direction::Right, 2 => Direction::Down, 3 => Direction::Left, _ => panic!(), } } } impl rand::prelude::Distribution for rand::distr::StandardUniform { fn sample(&self, rng: &mut R) -> Direction { let a = [ Direction::Up, Direction::Right, Direction::Down, Direction::Left, ]; let r = rng.random_range(0..4); a[r] } }