diff --git a/src/main.rs b/src/main.rs index 7ac20bb..cb70b49 100644 --- a/src/main.rs +++ b/src/main.rs @@ -31,8 +31,8 @@ impl World { self.map = vec!['.'; (self.x * self.y) as usize]; } /// Set robot on the map. - fn set_robot(&mut self, r: Robot) { - self.map[(r.p.x * r.p.y) as usize] = match r.o { + fn set_robot(&mut self, r: &Robot) { + self.map[(r.p.x + (r.p.y * self.x as i32)) as usize] = match r.o { Orientation::N => '↑', Orientation::S => '↓', Orientation::E => '→', @@ -40,8 +40,15 @@ impl World { } } /// Check if a position is free. - fn empty_position(&mut self, p: Position) -> bool { - self.map[(p.x * p.y) as usize] == '.' + fn empty_position(&mut self, p: &Position) -> bool { + self.map[(p.x + (p.y * self.x as i32)) as usize] == '.' + } + /// Place robot on the map after checking if the position is valid. + fn place_robot(&mut self, r: &Robot) -> Result<(), String> { + match r.p.is_valid(&self) { + Ok(_) => Ok(self.set_robot(r)), + Err(e) => Err(e), + } } } @@ -53,7 +60,7 @@ struct Position { impl Position { /// Check if position is in the map. - fn is_valid(self, w: World) -> Result<(), String> { + fn is_valid(&self, w: &World) -> Result<(), String> { if (self.x, self.y) > (0, 0) && (self.x, self.y) < (w.x as i32, w.y as i32) { Ok(()) } else { @@ -93,7 +100,8 @@ impl Robot { self.q = q; } /// Apply forward instruction to the robot. - fn move_forward(&mut self) { + fn move_forward(&mut self, w: &mut World) { + w.map[(self.p.x + (self.p.y * w.x as i32)) as usize] = '.'; match self.o { Orientation::N => self.p.y -= 1, Orientation::S => self.p.y += 1, @@ -102,7 +110,8 @@ impl Robot { } } /// Apply right instruction to the robot. - fn move_right(&mut self) { + fn move_right(&mut self, w: &mut World) { + w.map[(self.p.x + (self.p.y * w.x as i32)) as usize] = '.'; match self.o { Orientation::N => self.p.x += 1, Orientation::S => self.p.x -= 1, @@ -111,7 +120,8 @@ impl Robot { } } /// Apply left instruction to the robot. - fn move_left(&mut self) { + fn move_left(&mut self, w: &mut World) { + w.map[(self.p.x + (self.p.y * w.x as i32)) as usize] = '.'; match self.o { Orientation::N => self.p.x -= 1, Orientation::S => self.p.x += 1, @@ -279,7 +289,7 @@ mod tests { map: Vec::new(), }; w.create(); - w.set_robot(r); + w.set_robot(&r); assert_eq!(w.map, vec!['↑', '.', '.', '.']); } @@ -291,14 +301,62 @@ mod tests { p: Position { x: 1, y: 1 }, q: Queue::new(), }; - r.move_forward(); + let mut w: World = World { + x: 2, + y: 2, + map: Vec::new(), + }; + w.create(); + r.move_forward(&mut w); assert_eq!(0, r.p.y); - r.move_right(); + r.move_right(&mut w); assert_eq!(2, r.p.x); - r.move_left(); + r.move_left(&mut w); assert_eq!(1, r.p.x); } + #[test] + fn test_place_robot() { + let mut r: Robot = Robot { + id: 0, + o: Orientation::N, + p: Position { x: 1, y: 1 }, + q: Queue::new(), + }; + let mut w: World = World { + x: 2, + y: 2, + map: Vec::new(), + }; + w.create(); + w.set_robot(&r); + assert_eq!(w.map, vec!['.', '.', '.', '↑']); + r.move_forward(&mut w); + assert!(w.place_robot(&r).is_ok()); + assert_eq!(w.map, vec!['.', '↑', '.', '.']); + } + + #[test] + #[should_panic] + fn test_place_robot_fail() { + let mut r: Robot = Robot { + id: 0, + o: Orientation::N, + p: Position { x: 1, y: 1 }, + q: Queue::new(), + }; + let mut w: World = World { + x: 2, + y: 2, + map: Vec::new(), + }; + w.create(); + w.set_robot(&r); + r.move_forward(&mut w); + r.move_forward(&mut w); + assert!(w.place_robot(&r).is_ok()); + } + #[test] fn test_empty_position() { let mut w: World = World { @@ -307,7 +365,7 @@ mod tests { map: Vec::new(), }; w.create(); - assert!(w.empty_position(Position { x: 0, y: 0 })); + assert!(w.empty_position(&Position { x: 0, y: 0 })); } #[test] @@ -318,7 +376,7 @@ mod tests { y: 5, map: Vec::new(), }; - assert!(p.is_valid(w).is_ok()); + assert!(p.is_valid(&w).is_ok()); } #[test] @@ -330,6 +388,6 @@ mod tests { y: 5, map: Vec::new(), }; - assert!(p.is_valid(w).is_ok()); + assert!(p.is_valid(&w).is_ok()); } }