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];
}
/// 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());
}
}