Merge branch 'place-robot-fix-borrow' into 'master'

add place_robot + tests, changed coordinate calculation, fixed borrowing issues

See merge request mhart/DancingDroids!29
This commit is contained in:
Martin HART 2020-10-26 20:35:40 +01:00
commit e8c02e41f7

View File

@ -31,8 +31,8 @@ impl World {
self.map = vec!['.'; (self.x * self.y) as usize]; self.map = vec!['.'; (self.x * self.y) as usize];
} }
/// Set robot on the map. /// Set robot on the map.
fn set_robot(&mut self, r: Robot) { fn set_robot(&mut self, r: &Robot) {
self.map[(r.p.x * r.p.y) as usize] = match r.o { self.map[(r.p.x + (r.p.y * self.x as i32)) as usize] = match r.o {
Orientation::N => '↑', Orientation::N => '↑',
Orientation::S => '↓', Orientation::S => '↓',
Orientation::E => '→', Orientation::E => '→',
@ -40,8 +40,15 @@ impl World {
} }
} }
/// Check if a position is free. /// Check if a position is free.
fn empty_position(&mut self, p: Position) -> bool { fn empty_position(&mut self, p: &Position) -> bool {
self.map[(p.x * p.y) as usize] == '.' 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 { impl Position {
/// Check if position is in the map. /// 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) { if (self.x, self.y) > (0, 0) && (self.x, self.y) < (w.x as i32, w.y as i32) {
Ok(()) Ok(())
} else { } else {
@ -93,7 +100,8 @@ impl Robot {
self.q = q; self.q = q;
} }
/// Apply forward instruction to the robot. /// 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 { match self.o {
Orientation::N => self.p.y -= 1, Orientation::N => self.p.y -= 1,
Orientation::S => self.p.y += 1, Orientation::S => self.p.y += 1,
@ -102,7 +110,8 @@ impl Robot {
} }
} }
/// Apply right instruction to the 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 { match self.o {
Orientation::N => self.p.x += 1, Orientation::N => self.p.x += 1,
Orientation::S => self.p.x -= 1, Orientation::S => self.p.x -= 1,
@ -111,7 +120,8 @@ impl Robot {
} }
} }
/// Apply left instruction to the 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 { match self.o {
Orientation::N => self.p.x -= 1, Orientation::N => self.p.x -= 1,
Orientation::S => self.p.x += 1, Orientation::S => self.p.x += 1,
@ -279,7 +289,7 @@ mod tests {
map: Vec::new(), map: Vec::new(),
}; };
w.create(); w.create();
w.set_robot(r); w.set_robot(&r);
assert_eq!(w.map, vec!['↑', '.', '.', '.']); assert_eq!(w.map, vec!['↑', '.', '.', '.']);
} }
@ -291,14 +301,62 @@ mod tests {
p: Position { x: 1, y: 1 }, p: Position { x: 1, y: 1 },
q: Queue::new(), 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); assert_eq!(0, r.p.y);
r.move_right(); r.move_right(&mut w);
assert_eq!(2, r.p.x); assert_eq!(2, r.p.x);
r.move_left(); r.move_left(&mut w);
assert_eq!(1, r.p.x); 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] #[test]
fn test_empty_position() { fn test_empty_position() {
let mut w: World = World { let mut w: World = World {
@ -307,7 +365,7 @@ mod tests {
map: Vec::new(), map: Vec::new(),
}; };
w.create(); w.create();
assert!(w.empty_position(Position { x: 0, y: 0 })); assert!(w.empty_position(&Position { x: 0, y: 0 }));
} }
#[test] #[test]
@ -318,7 +376,7 @@ mod tests {
y: 5, y: 5,
map: Vec::new(), map: Vec::new(),
}; };
assert!(p.is_valid(w).is_ok()); assert!(p.is_valid(&w).is_ok());
} }
#[test] #[test]
@ -330,6 +388,6 @@ mod tests {
y: 5, y: 5,
map: Vec::new(), map: Vec::new(),
}; };
assert!(p.is_valid(w).is_ok()); assert!(p.is_valid(&w).is_ok());
} }
} }