dancing_droids/src/robot.rs

95 lines
2.7 KiB
Rust
Raw Normal View History

2020-10-27 22:55:31 +01:00
/// A Robot *aka droid* is represented here.
/// Each robot must have a unique id.
pub struct Robot {
2020-10-28 17:32:36 +01:00
id: u32,
2020-10-27 22:55:31 +01:00
o: Orientation,
p: Position,
2020-10-28 17:30:45 +01:00
i: Vec<char>,
}
impl Robot {
/// Create new `Robot` with given id, `Orientation`, `Position` and instructions.
2020-10-28 18:20:37 +01:00
fn new(id: u32, o: Orientation, p: Position, i: Vec<char>) -> Robot {
2020-10-28 17:30:45 +01:00
Robot { id, o, p, i }
}
/// Apply given instruction to a `Robot`.
2020-10-28 18:20:37 +01:00
fn execute_instruction(
&mut self,
hash: &mut std::collections::HashMap<Position, u32>,
) -> Result<(), &'static str> {
hash.remove(&self.p); // we need to insert the new position after calling execute_instruction()
2020-10-28 17:30:45 +01:00
match self.i.pop() {
Some(instruction) => match instruction {
'L' => Ok(match self.o {
Orientation::N => self.o = Orientation::W,
Orientation::E => self.o = Orientation::N,
Orientation::S => self.o = Orientation::E,
Orientation::W => self.o = Orientation::S,
}),
'R' => Ok(match self.o {
Orientation::N => self.o = Orientation::E,
Orientation::E => self.o = Orientation::S,
Orientation::S => self.o = Orientation::W,
Orientation::W => self.o = Orientation::N,
}),
'F' => Ok(match self.o {
Orientation::N => self.p.y += 1,
Orientation::E => self.p.x += 1,
Orientation::S => self.p.y -= 1,
Orientation::W => self.p.x -= 1,
}),
_ => Err("Invalid instruction."),
},
None => Ok(()),
}
}
2020-10-27 22:55:31 +01:00
}
/// Enum to store all possible orientations.
enum Orientation {
N,
E,
S,
W,
}
/// Struct to store robot position.
2020-10-28 18:20:37 +01:00
#[derive(PartialEq, Eq, Hash)]
2020-10-27 22:55:31 +01:00
struct Position {
x: i32,
y: i32,
}
2020-10-28 17:30:45 +01:00
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new_robot() {
let r: Robot = Robot::new(
0,
Orientation::N,
Position { x: 1, y: 2 },
vec!['L', 'L', 'F', 'R'],
);
assert_eq!(r.id, 0);
assert!(matches!(r.o, Orientation::N));
assert_eq!(r.p.x, 1);
assert_eq!(r.p.y, 2);
assert_eq!(r.i, vec!['L', 'L', 'F', 'R']);
}
#[test]
fn test_execute_instruction() {
let mut r: Robot = Robot::new(
0,
Orientation::N,
Position { x: 1, y: 2 },
vec!['R', 'L', 'F', 'F'],
);
assert!(r.execute_instruction().is_ok());
assert_eq!(r.p.x, 1);
assert_eq!(r.p.y, 3);
}
}