AdventOfCode/Rust/lib/grid.rs

86 lines
2.4 KiB
Rust

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Direction {
North,
East,
South,
West,
}
impl Direction {
pub fn step(self, x: usize, y: usize, width: usize, height: usize) -> Option<(usize, usize)> {
Some(match self {
Direction::North if y > 0 => (x, y - 1),
Direction::East if x < width - 1 => (x + 1, y),
Direction::South if y < height - 1 => (x, y + 1),
Direction::West if x > 0 => (x - 1, y),
_ => return None,
})
}
pub fn step_signed(self, (x, y): (isize, isize)) -> (isize, isize) {
match self {
Direction::North => (x, y - 1),
Direction::East => (x + 1, y),
Direction::South => (x, y + 1),
Direction::West => (x - 1, y),
}
}
pub fn step_signed_n(self, (x, y): (isize, isize), n: isize) -> (isize, isize) {
match self {
Direction::North => (x, y - n),
Direction::East => (x + n, y),
Direction::South => (x, y + n),
Direction::West => (x - n, y),
}
}
pub fn invert(self) -> Self {
match self {
Direction::North => Direction::South,
Direction::East => Direction::West,
Direction::South => Direction::North,
Direction::West => Direction::East,
}
}
pub fn rotate_left(self) -> Self {
match self {
Direction::North => Direction::West,
Direction::East => Direction::North,
Direction::South => Direction::East,
Direction::West => Direction::South,
}
}
pub fn rotate_right(self) -> Self {
match self {
Direction::North => Direction::East,
Direction::East => Direction::South,
Direction::South => Direction::West,
Direction::West => Direction::North,
}
}
pub fn iter() -> impl Iterator<Item = Self> + Clone {
[Self::North, Self::East, Self::South, Self::West].into_iter()
}
}
impl From<char> for Direction {
fn from(c: char) -> Self {
match c {
'U' | 'N' | '^' => Self::North,
'R' | 'E' | '>' => Self::East,
'D' | 'S' | 'v' => Self::South,
'L' | 'W' | '<' => Self::West,
_ => panic!(),
}
}
}
impl From<u8> for Direction {
fn from(c: u8) -> Self {
char::from(c).into()
}
}