Coverage for rover/rover.py : 100%
Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1import dataclasses
4@dataclasses.dataclass
5class Rover:
6 x: int
7 y: int
8 direction: str
9 obstacles: list[list[int]] = dataclasses.field(default_factory=list)
11 valid_commands = ("F", "B", "R", "L")
13 direction_map = {
14 "NORTH": (0, 1, "WEST", "EAST"),
15 "EAST": (1, 0, "NORTH", "SOUTH"),
16 "SOUTH": (0, -1, "EAST", "WEST"),
17 "WEST": (-1, 0, "SOUTH", "NORTH"),
18 }
20 def is_valid_command(self, command):
21 for ch in command:
22 if ch not in self.valid_commands:
23 return False
25 return True
27 def is_obstacle(self, x: int, y: int):
28 return [x, y] in self.obstacles
30 def move(self, command: str):
31 if not self.is_valid_command(command):
32 raise ValueError("invalid command. The rover does not move")
34 for ch in command:
35 x, y, direction = self._compute_new_coordinates(ch)
36 if obstacle := self.is_obstacle(x, y):
37 return self.new_coordinates_output(obstacle)
39 self.apply_new_coordinates(x, y, direction)
41 return self.new_coordinates_output()
43 def new_coordinates_output(self, obstacle: bool = False):
44 if obstacle:
45 return self.x, self.y, self.direction, "STOPPED"
46 return self.x, self.y, self.direction
48 def _compute_new_coordinates(self, command):
49 x = self.x
50 y = self.y
51 direction = self.direction
53 if command == "B":
54 x -= self.direction_map[self.direction][0]
55 y -= self.direction_map[self.direction][1]
56 if command == "F":
57 x += self.direction_map[self.direction][0]
58 y += self.direction_map[self.direction][1]
59 if command == "R":
60 direction = self.direction_map[self.direction][3]
61 if command == "L":
62 direction = self.direction_map[self.direction][2]
64 return x, y, direction
66 def apply_new_coordinates(self, x, y, direction):
67 self.x = x
68 self.y = y
69 self.direction = direction