def scan_line(self, line: LineToMiddle, _first_iteration: bool = True):
     # TODO: remove when work
     if _first_iteration:
         raise NotImplementedError()
     # end remove
     if line.is_finished():
         raise ValueError("cannot scan finished line")
     line_start_coordinates = line.start_coordinates.copy()
     if _first_iteration:
         if self.robot_coordinates != line_start_coordinates:
             raise ValueError("scanner assume that robot is at line start")
     if not self.robot.has_block():
         raise ValueError("scanner assume that robot has block")
     to_block_direction = line.get_to_block_direction()
     from_block_direction = line.get_from_block_direction()
     before_block_coordinates = line.get_next_block_position(
     ).create_neighbour_coordinate(from_block_direction)
     if _first_iteration:
         if self._move_to_block_towards_inside(to_block_direction,
                                               from_block_direction, line,
                                               before_block_coordinates):
             return
     else:
         if self.robot_coordinates.get_straight_distance_to_other(
                 to_block_direction, before_block_coordinates) > 0:
             if self._move_to_block_towards_inside(
                     to_block_direction, from_block_direction, line,
                     before_block_coordinates):
                 return
         else:
             self._move_to_block_from_inside(from_block_direction,
                                             before_block_coordinates)
     while True:
         # we need to rotate in case we were not
         if self.robot.rotation != to_block_direction:
             self.shared_actions_executor.try_rotate_robot(
                 to_block_direction)
         # if we are just before position to put block and correctly rotated
         hit_information = self.shared_actions_executor.try_put_block(
             to_block_direction)
         if hit_information.hit_type == HitType.PLACED_BLOCK:
             line.place_block()
             break
         elif hit_information.hit_type == HitType.BLOCK:
             # when another robot already put this block
             line.place_block()
             if line.is_finished():
                 break
             before_block_coordinates = line.get_next_block_position(). \
                 create_neighbour_coordinate(from_block_direction)
             self._move_to_block_from_inside(from_block_direction,
                                             before_block_coordinates)
             continue
         else:
             raise ValueError(
                 "different tile type cannot be on position where block will be added"
             )
     self._go_back_to_start_line(from_block_direction, line)
Example #2
0
 def _move_to_block_towards_inside(self, line: LineToMiddle) -> bool:
     to_block_direction = line.get_to_block_direction()
     from_block_direction = line.get_from_block_direction()
     before_block_coordinates = line.get_next_block_position(
     ).create_neighbour_coordinate(from_block_direction)
     before_last_coordinates = line.get_last_position(
     ).create_neighbour_coordinate(from_block_direction)
     # print(f"robot: {self.robot}, start move_to_block_towards_inside, " +
     #       f"before: {before_block_coordinates}, last: {before_last_coordinates}")
     # returns True when finished but False when still need to add block
     while self.robot_coordinates != before_last_coordinates:
         hit_information = self.shared_actions_executor.try_move_robot(
             to_block_direction)
         if hit_information.hit_type == HitType.OBSTACLE:
             raise ValueError("scanner cannot work with obstacles")
         elif hit_information.hit_type == HitType.BLOCK:
             placed_block_position: Coordinates = before_block_coordinates
             discovered_block_position = self.robot_coordinates.create_neighbour_coordinate(
                 to_block_direction)
             print(
                 f"robot: {self.robot.id}, hit block at {discovered_block_position}"
             )
             if before_block_coordinates == discovered_block_position:
                 self._put_block_on_map(line)
             while placed_block_position != discovered_block_position:
                 placed_block_position = self._put_block_on_map(line)
             if line.is_finished():
                 self._go_back_to_start_line(from_block_direction,
                                             line.start_coordinates)
                 return True
             self.shared_actions_executor.try_rotate_robot(
                 from_block_direction)
             before_block_coordinates = line.get_next_block_position(). \
                 create_neighbour_coordinate(from_block_direction)
             self._move_to_block_from_inside(from_block_direction,
                                             before_block_coordinates)
             return False
         elif hit_information.hit_type == HitType.ROBOT:
             # if we hit robot then he already put at least one new block and we continue with block elsewhere
             other_robot_position = self.robot_coordinates.create_neighbour_coordinate(
                 to_block_direction)
             print(
                 f"robot: {self.robot.id}, hit robot at {other_robot_position}"
             )
             self._go_back_to_start_line(from_block_direction,
                                         line.start_coordinates)
             return True
     self.shared_actions_executor.try_rotate_robot(from_block_direction)
     before_block_coordinates = line.get_next_block_position(). \
         create_neighbour_coordinate(from_block_direction)
     self._move_to_block_from_inside(from_block_direction,
                                     before_block_coordinates)
     return False