1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
//! A direction.
use std::ops::Neg;
use nalgebra::Vector2;
/// A direction.
#[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)]
pub enum Direction {
/// Upward direction (negative Y-axis).
Up,
/// Downward direction (positive Y-axis).
Down,
/// Leftward direction (negative X-axis).
Left,
/// Rightward direction (positive X-axis).
Right,
}
impl Direction {
/// Returns an iterator over all directions.
pub fn iter() -> std::array::IntoIter<Direction, 4> {
[Self::Up, Self::Down, Self::Left, Self::Right].into_iter()
}
/// Rotate the direction 90° clockwise.
///
/// # Examples
///
/// ```
/// # use soukoban::direction::Direction;
/// assert_eq!(Direction::Up.rotate(), Direction::Right);
///
/// // Rotate the direction 90° counter clockwis.
/// assert_eq!(-Direction::Right.rotate(), Direction::Up);
/// ```
pub fn rotate(self) -> Direction {
match self {
Self::Up => Self::Right,
Self::Right => Self::Down,
Self::Down => Self::Left,
Self::Left => Self::Up,
}
}
/// Flip the direction.
///
/// # Examples
///
/// ```
/// # use soukoban::direction::Direction;
/// assert_eq!(Direction::Left.flip(), Direction::Right);
/// assert_eq!(Direction::Up.flip(), Direction::Down);
/// ```
pub fn flip(self) -> Direction {
match self {
Self::Up => Self::Down,
Self::Down => Self::Up,
Self::Left => Self::Right,
Self::Right => Self::Left,
}
}
}
impl Neg for Direction {
type Output = Self;
fn neg(self) -> Self::Output {
self.flip()
}
}
impl From<Direction> for Vector2<i32> {
fn from(direction: Direction) -> Self {
use Direction as E;
match direction {
E::Up => -Vector2::y(),
E::Down => Vector2::y(),
E::Left => -Vector2::x(),
E::Right => Vector2::x(),
}
}
}
impl TryFrom<Vector2<i32>> for Direction {
type Error = ();
fn try_from(vector: Vector2<i32>) -> Result<Self, Self::Error> {
use Direction::*;
match vector {
v if v == -Vector2::<i32>::y() => Ok(Up),
v if v == Vector2::<i32>::y() => Ok(Down),
v if v == -Vector2::<i32>::x() => Ok(Left),
v if v == Vector2::<i32>::x() => Ok(Right),
_ => Err(()),
}
}
}