2020: day12: refacto coordinates system
This commit is contained in:
parent
1f0eeb3b04
commit
f85bea7bb4
|
@ -149,10 +149,26 @@ impl std::str::FromStr for Action {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
struct Ship {
|
struct Coordinates {
|
||||||
direction: Direction,
|
|
||||||
x: i64,
|
x: i64,
|
||||||
y: i64,
|
y: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Coordinates {
|
||||||
|
fn move_towards(&mut self, direction: Direction, distance: i64) {
|
||||||
|
match direction {
|
||||||
|
Direction::North => self.y -= distance,
|
||||||
|
Direction::South => self.y += distance,
|
||||||
|
Direction::West => self.x -= distance,
|
||||||
|
Direction::East => self.x += distance,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
struct Ship {
|
||||||
|
direction: Direction,
|
||||||
|
coordinates: Coordinates,
|
||||||
|
|
||||||
waypoint: Waypoint,
|
waypoint: Waypoint,
|
||||||
}
|
}
|
||||||
|
@ -161,36 +177,35 @@ impl Ship {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
direction: Direction::East,
|
direction: Direction::East,
|
||||||
x: 0,
|
coordinates: Coordinates { x: 0, y: 0 },
|
||||||
y: 0,
|
|
||||||
waypoint: Waypoint::new(),
|
waypoint: Waypoint::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn manhattan_distance(&self) -> i64 {
|
fn manhattan_distance(&self) -> i64 {
|
||||||
self.x.abs() + self.y.abs()
|
self.coordinates.x.abs() + self.coordinates.y.abs()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process(&mut self, action: Action) {
|
fn process(&mut self, action: Action) {
|
||||||
match action.kind {
|
match action.kind {
|
||||||
ActionKind::Move(dir) => self.forward(dir, action.arg),
|
ActionKind::Move(dir) => self.coordinates.move_towards(dir, action.arg as i64),
|
||||||
|
|
||||||
ActionKind::Turn(turn_dir) => {
|
ActionKind::Turn(turn_dir) => {
|
||||||
self.direction = self.direction.rotate(turn_dir, action.arg);
|
self.direction = self.direction.rotate(turn_dir, action.arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
ActionKind::Forward => self.forward(self.direction, action.arg),
|
ActionKind::Forward => self
|
||||||
|
.coordinates
|
||||||
|
.move_towards(self.direction, action.arg as i64),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_with_waypoint(&mut self, action: Action) {
|
fn process_with_waypoint(&mut self, action: Action) {
|
||||||
match action.kind {
|
match action.kind {
|
||||||
ActionKind::Move(dir) => match dir {
|
ActionKind::Move(dir) => self
|
||||||
Direction::North => self.waypoint.y -= action.arg as i64,
|
.waypoint
|
||||||
Direction::South => self.waypoint.y += action.arg as i64,
|
.coordinates
|
||||||
Direction::West => self.waypoint.x -= action.arg as i64,
|
.move_towards(dir, action.arg as i64),
|
||||||
Direction::East => self.waypoint.x += action.arg as i64,
|
|
||||||
},
|
|
||||||
|
|
||||||
ActionKind::Turn(turn_dir) => {
|
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");
|
||||||
|
@ -202,43 +217,36 @@ impl Ship {
|
||||||
|
|
||||||
ActionKind::Forward => {
|
ActionKind::Forward => {
|
||||||
let (west_east, north_south) = self.waypoint.as_dirs();
|
let (west_east, north_south) = self.waypoint.as_dirs();
|
||||||
|
let (dx, dy) = self.waypoint.diff();
|
||||||
|
|
||||||
self.forward(west_east, self.waypoint.x.abs() as u16 * action.arg);
|
self.coordinates
|
||||||
self.forward(north_south, self.waypoint.y.abs() as u16 * action.arg);
|
.move_towards(west_east, dx * action.arg as i64);
|
||||||
|
self.coordinates
|
||||||
|
.move_towards(north_south, dy * action.arg as i64);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn forward(&mut self, direction: Direction, arg: u16) {
|
|
||||||
let arg = arg as i64;
|
|
||||||
|
|
||||||
match direction {
|
|
||||||
Direction::North => self.y -= arg as i64,
|
|
||||||
Direction::South => self.y += arg as i64,
|
|
||||||
Direction::West => self.x -= arg as i64,
|
|
||||||
Direction::East => self.x += arg as i64,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
struct Waypoint {
|
struct Waypoint {
|
||||||
x: i64,
|
coordinates: Coordinates,
|
||||||
y: i64,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Waypoint {
|
impl Waypoint {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
Self { x: 10, y: -1 }
|
Self {
|
||||||
|
coordinates: Coordinates { x: 10, y: -1 },
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_dirs(&self) -> (Direction, Direction) {
|
fn as_dirs(&self) -> (Direction, Direction) {
|
||||||
let west_east = if self.x < 0 {
|
let west_east = if self.coordinates.x < 0 {
|
||||||
Direction::West
|
Direction::West
|
||||||
} else {
|
} else {
|
||||||
Direction::East
|
Direction::East
|
||||||
};
|
};
|
||||||
let north_south = if self.y < 0 {
|
let north_south = if self.coordinates.y < 0 {
|
||||||
Direction::North
|
Direction::North
|
||||||
} else {
|
} else {
|
||||||
Direction::South
|
Direction::South
|
||||||
|
@ -247,18 +255,27 @@ impl Waypoint {
|
||||||
(west_east, north_south)
|
(west_east, north_south)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn diff(&self) -> (i64, i64) {
|
||||||
|
(
|
||||||
|
self.coordinates.x.abs() as i64,
|
||||||
|
self.coordinates.y.abs() as i64,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fn turn(&mut self, turn_dir: TurnDirection, quadrants: usize) {
|
fn turn(&mut self, turn_dir: TurnDirection, quadrants: usize) {
|
||||||
|
let coords = &mut self.coordinates;
|
||||||
|
|
||||||
for _ in 0..quadrants {
|
for _ in 0..quadrants {
|
||||||
let mut x = self.x;
|
let mut x = coords.x;
|
||||||
let mut y = self.y;
|
let mut y = coords.y;
|
||||||
|
|
||||||
match turn_dir {
|
match turn_dir {
|
||||||
TurnDirection::Left => x = -x,
|
TurnDirection::Left => x = -x,
|
||||||
TurnDirection::Right => y = -y,
|
TurnDirection::Right => y = -y,
|
||||||
}
|
}
|
||||||
|
|
||||||
self.x = y;
|
coords.x = y;
|
||||||
self.y = x;
|
coords.y = x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue