diff --git a/src/main.rs b/src/main.rs index c1bba05..a3e574e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -124,12 +124,12 @@ fn parse_config(conf: String, pool: &mut Vec) -> Result = instructions.chars().rev().collect(); - if !robot::is_instructions(&inst) { + if !robot::is_instructions(instructions) { return Err(String::from("Invalid instructions !")); } + let inst = robot::instructions_from_string(instructions.chars().rev().collect::())?; + let r = robot::Robot::new(r_id, r_o, robot::Position { x: r_x, y: r_y }, inst); // Load robot inside the pool. match check_map(&r, &world) { @@ -284,7 +284,7 @@ mod tests { 0, robot::Orientation::N, robot::Position { x: 2, y: 3 }, - vec!['F'], + vec![robot::Instruction::F], ); let w = world::World { x: 10, y: 10 }; @@ -298,7 +298,7 @@ mod tests { 0, robot::Orientation::N, robot::Position { x: 2, y: 4 }, - vec!['F'], + vec![robot::Instruction::F], ); let w = world::World { x: 3, y: 3 }; @@ -312,7 +312,7 @@ mod tests { 0, robot::Orientation::N, robot::Position { x: 2, y: 3 }, - vec!['F'], + vec![robot::Instruction::F], ); let mut h: HashMap = HashMap::new(); diff --git a/src/robot.rs b/src/robot.rs index 8d7654b..6d12f87 100644 --- a/src/robot.rs +++ b/src/robot.rs @@ -9,37 +9,26 @@ pub struct Robot { pub id: u32, pub o: Orientation, pub p: Position, - i: Vec, + i: Vec, } impl Robot { /// Create new `Robot` with given id, `Orientation`, `Position` and instructions. - pub fn new(id: u32, o: Orientation, p: Position, i: Vec) -> Robot { + pub fn new(id: u32, o: Orientation, p: Position, i: Vec) -> Robot { Robot { id, o, p, i } } /// Apply given instruction to a `Robot`. pub fn execute_instruction(&mut self) { match self.i.pop() { Some(instruction) => match instruction { - 'L' => 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' => 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' => match self.o { + Instruction::L => self.o = turn_left(&self.o), + Instruction::R => self.o = turn_right(&self.o), + Instruction::F => 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, }, - _ => (), // never happens 😉 }, None => (), } @@ -55,6 +44,44 @@ pub enum Orientation { W, } +fn turn_left(o: &Orientation) -> Orientation { + match o { + Orientation::N => Orientation::W, + Orientation::E => Orientation::N, + Orientation::S => Orientation::E, + Orientation::W => Orientation::S, + } +} +fn turn_right(o: &Orientation) -> Orientation { + match o { + Orientation::N => Orientation::E, + Orientation::E => Orientation::S, + Orientation::S => Orientation::W, + Orientation::W => Orientation::N, + } +} + +/// Enum to store all possible instructions. +#[derive(Debug, Eq, PartialEq)] +pub enum Instruction { + L, + R, + F, +} + +pub fn instructions_from_string(s: String) -> Result, String> { + let mut v: Vec = Vec::new(); + for c in s.chars() { + match c { + 'L' => v.push(Instruction::L), + 'R' => v.push(Instruction::R), + 'F' => v.push(Instruction::F), + _ => return Err(String::from("Not an instruction.")), + } + } + Ok(v) +} + impl Distribution for Standard { fn sample(&self, rng: &mut R) -> Orientation { match rng.gen_range(0, 3) { @@ -74,8 +101,8 @@ pub struct Position { } /// Check if instructions list is valid. -pub fn is_instructions(v: &Vec) -> bool { - for c in v { +pub fn is_instructions(s: &str) -> bool { + for c in s.chars() { match c { 'F' => continue, 'R' => continue, @@ -135,13 +162,15 @@ mod tests { 0, Orientation::N, Position { x: 1, y: 2 }, - vec!['L', 'L', 'F', 'R'], + vec![Instruction::L, Instruction::F, Instruction::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']); + assert_eq!(r.i[0], Instruction::L); + assert_eq!(r.i[1], Instruction::F); + assert_eq!(r.i[2], Instruction::R); } #[test] @@ -150,7 +179,12 @@ mod tests { 0, Orientation::N, Position { x: 1, y: 2 }, - vec!['R', 'F', 'L', 'F'], + vec![ + Instruction::R, + Instruction::F, + Instruction::L, + Instruction::F, + ], ); let mut hash = std::collections::HashMap::new(); //hash.insert(&r.p, &r.id); // first insert while initializing. @@ -167,15 +201,15 @@ mod tests { #[test] fn is_instructions_test() { - let v = vec!['F', 'R', 'L', 'F']; - assert!(is_instructions(&v)); + let s = "FFLRLRF"; + assert!(is_instructions(&s)); } #[test] #[should_panic] fn is_instructions_test_fail() { - let v = vec!['F', 'R', 'L', 'Z']; - assert!(is_instructions(&v)); + let s = "SZDASWQ"; + assert!(is_instructions(&s)); } #[test] @@ -184,7 +218,12 @@ mod tests { 0, Orientation::N, Position { x: 1, y: 2 }, - vec!['R', 'F', 'L', 'F'], + vec![ + Instruction::R, + Instruction::F, + Instruction::L, + Instruction::F, + ], ); r.i.pop(); r.i.pop();