mars-rover-kata/rover/rover.py
2021-08-30 11:50:36 +02:00

69 lines
2 KiB
Python

import dataclasses
@dataclasses.dataclass
class Rover:
x: int
y: int
direction: str
obstacles: list[list[int]] = dataclasses.field(default_factory=list)
valid_commands = ("F", "B", "R", "L")
direction_map = {
"NORTH": (0, 1, "WEST", "EAST"),
"EAST": (1, 0, "NORTH", "SOUTH"),
"SOUTH": (0, -1, "EAST", "WEST"),
"WEST": (-1, 0, "SOUTH", "NORTH"),
}
def is_valid_command(self, command):
for ch in command:
if ch not in self.valid_commands:
return False
return True
def is_obstacle(self, x: int, y: int):
return [x, y] in self.obstacles
def move(self, command: str):
if not self.is_valid_command(command):
raise ValueError("invalid command. The rover does not move")
for ch in command:
x, y, direction = self._compute_new_coordinates(ch)
if obstacle := self.is_obstacle(x, y):
return self.new_coordinates_output(obstacle)
self.apply_new_coordinates(x, y, direction)
return self.new_coordinates_output()
def new_coordinates_output(self, obstacle: bool = False):
if obstacle:
return self.x, self.y, self.direction, "STOPPED"
return self.x, self.y, self.direction
def _compute_new_coordinates(self, command):
x = self.x
y = self.y
direction = self.direction
if command == "B":
x -= self.direction_map[self.direction][0]
y -= self.direction_map[self.direction][1]
if command == "F":
x += self.direction_map[self.direction][0]
y += self.direction_map[self.direction][1]
if command == "R":
direction = self.direction_map[self.direction][3]
if command == "L":
direction = self.direction_map[self.direction][2]
return x, y, direction
def apply_new_coordinates(self, x, y, direction):
self.x = x
self.y = y
self.direction = direction