100 lines
2.6 KiB
Rust
100 lines
2.6 KiB
Rust
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<Direction> for rand::distr::StandardUniform {
|
|
fn sample<R: rand::Rng + ?Sized>(&self, rng: &mut R) -> Direction {
|
|
let a = [
|
|
Direction::Up,
|
|
Direction::Right,
|
|
Direction::Down,
|
|
Direction::Left,
|
|
];
|
|
let r = rng.random_range(0..4);
|
|
a[r]
|
|
}
|
|
}
|