2020: day12: refacto turn directions

This commit is contained in:
Antoine Martin 2020-12-12 15:48:15 +01:00
parent e19ca07c6b
commit 442f4621fb

View file

@ -51,12 +51,17 @@ enum Direction {
West, West,
} }
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum TurnDirection {
Left,
Right,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum ActionKind { enum ActionKind {
Move(Direction), Move(Direction),
Left, Turn(TurnDirection),
Right,
Forward, Forward,
} }
@ -87,8 +92,8 @@ impl std::str::FromStr for Action {
'E' => ActionKind::Move(Direction::East), 'E' => ActionKind::Move(Direction::East),
'W' => ActionKind::Move(Direction::West), 'W' => ActionKind::Move(Direction::West),
'L' => ActionKind::Left, 'L' => ActionKind::Turn(TurnDirection::Left),
'R' => ActionKind::Right, 'R' => ActionKind::Turn(TurnDirection::Right),
'F' => ActionKind::Forward, 'F' => ActionKind::Forward,
@ -154,14 +159,14 @@ impl Ship {
match action.kind { match action.kind {
ActionKind::Move(dir) => self.forward(dir, action.arg), ActionKind::Move(dir) => self.forward(dir, action.arg),
ActionKind::Right | ActionKind::Left => { ActionKind::Turn(turn_dir) => {
debug_assert!(action.arg % 90 == 0, "only right angles are supported"); debug_assert!(action.arg % 90 == 0, "only right angles are supported");
let quarters = (action.arg / 90) as usize; let quarters = (action.arg / 90) as usize;
let directions_iter = Self::CLOCKWISE_DIRECTIONS.iter().copied(); let directions_iter = Self::CLOCKWISE_DIRECTIONS.iter().copied();
let new_dir = if action.kind == ActionKind::Left { let new_dir = if turn_dir == TurnDirection::Left {
// go through cardinal directions the other way around, anti-clockwise // go through cardinal directions the other way around, anti-clockwise
Ship::find_direction(directions_iter.rev(), quarters, self.direction) Ship::find_direction(directions_iter.rev(), quarters, self.direction)
} else { } else {
@ -184,31 +189,12 @@ impl Ship {
Direction::East => self.waypoint.x += action.arg as i64, Direction::East => self.waypoint.x += action.arg as i64,
}, },
ActionKind::Left => { ActionKind::Turn(turn_dir) => {
debug_assert!(action.arg % 90 == 0, "only right angles are supported"); debug_assert!(action.arg % 90 == 0, "only right angles are supported");
let quarters = (action.arg / 90) as usize % 4; let quadrants = (action.arg / 90) as usize % 4;
for _ in 0..quarters { self.waypoint.turn(turn_dir, quadrants);
let x = self.waypoint.x as i64;
let y = self.waypoint.y as i64;
self.waypoint.x = y;
self.waypoint.y = -x;
}
}
ActionKind::Right => {
debug_assert!(action.arg % 90 == 0, "only right angles are supported");
let quarters = (action.arg / 90) as usize % 4;
for _ in 0..quarters {
let x = self.waypoint.x as i64;
let y = self.waypoint.y as i64;
self.waypoint.x = -y;
self.waypoint.y = x;
}
} }
ActionKind::Forward => { ActionKind::Forward => {
@ -257,6 +243,21 @@ impl Waypoint {
(west_east, north_south) (west_east, north_south)
} }
fn turn(&mut self, turn_dir: TurnDirection, quadrants: usize) {
for _ in 0..quadrants {
let mut x = self.x;
let mut y = self.y;
match turn_dir {
TurnDirection::Left => x = -x,
TurnDirection::Right => y = -y,
}
self.x = y;
self.y = x;
}
}
} }
#[cfg(test)] #[cfg(test)]