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

This commit is contained in:
Volodymyr Patuta 2020-10-26 20:11:27 +01:00
parent 38a2ea98eb
commit 80dfe2d69e
1 changed files with 67 additions and 11 deletions

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,
@ -279,7 +287,7 @@ mod tests {
map: Vec::new(),
};
w.create();
w.set_robot(r);
w.set_robot(&r);
assert_eq!(w.map, vec!['↑', '.', '.', '.']);
}
@ -291,7 +299,13 @@ 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();
assert_eq!(2, r.p.x);
@ -299,6 +313,48 @@ mod tests {
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 +363,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 +374,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 +386,6 @@ mod tests {
y: 5,
map: Vec::new(),
};
assert!(p.is_valid(w).is_ok());
assert!(p.is_valid(&w).is_ok());
}
}