def test_single_robot_finish_single_block_goal(self): goal_building = GoalBuilding2D(""" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 """) robot = Robot(Direction.UP) robot.take_block(Tile(TileType.BLOCK)) line_start_coordinates = Coordinates(0, 3) base_grid = BaseGrid(goal_building.width, goal_building.height) base_grid.add_tile_to_grid(robot, line_start_coordinates) shared_grid_access = SharedGridAccess(base_grid, manager=Manager()) shared_actions_executor = RobotSharedActionsExecutor( robot=robot, shared_grid_access=shared_grid_access, private_grid=shared_grid_access.get_private_copy(), robot_coordinates=line_start_coordinates.copy()) line_scanner_executor = LineScannerExecutor( shared_actions_executor=shared_actions_executor) line_to_middle = LineToMiddle( start_coordinates=line_start_coordinates.copy(), direction=Direction.RIGHT, block_line=map(bool, [0, 0, 0, 0, 1])) line_scanner_executor.scan_line(line=line_to_middle) grid = shared_grid_access.get_private_copy() assert line_to_middle.is_finished() assert goal_building.validate_grid(grid) assert grid.get_coord_from_tile(robot) == line_start_coordinates
def _move_to_block_towards_inside(self, to_block_direction: Direction, from_block_direction: Direction, line: LineToMiddle, before_block_coordinates: Coordinates): # returns True when finished but False when still need to add block while self.robot_coordinates != before_block_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: Union[None, Coordinates] = None discovered_block_position = self.robot_coordinates.create_neighbour_coordinate( to_block_direction) 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 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 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 self._put_block_on_map(line) self._go_back_to_start_line(from_block_direction, line.start_coordinates) return return
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)
def _put_block_on_map(self, line: LineToMiddle) -> Coordinates: placed_block_position = line.place_block() try: self.private_grid.add_tile_to_grid(Tile(TileType.BLOCK), placed_block_position) except Exception as e: print(f"WARNING: {e}") return placed_block_position
def __init__(self, line: LineToMiddle, robot: Robot, shared_grid_access: SharedGridAccess, goal_building: GoalBuilding): super().__init__(robot, shared_grid_access, goal_building) self.shared_actions_executor = RobotSharedActionsExecutor( robot=robot, shared_grid_access=shared_grid_access, private_grid=self.private_grid, robot_coordinates=self.robot_coordinates) self.line = line.copy() self.line_scanner = LineScannerExecutor(self.shared_actions_executor)
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
def test_another_robot_update_private_grid(self): goal_building = GoalBuilding2D(""" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 """) robot_1 = Robot(Direction.DOWN) robot_1.take_block(Tile(TileType.BLOCK)) robot_2 = Robot(Direction.UP) robot_2.take_block(Tile(TileType.BLOCK)) line_start_coordinates = Coordinates(0, 3) robot_1_coordinates = Coordinates(0, 4) robot_2_coordinates = Coordinates(0, 2) base_grid = BaseGrid(goal_building.width, goal_building.height) base_grid.add_tile_to_grid(robot_1, robot_1_coordinates) base_grid.add_tile_to_grid(robot_2, robot_2_coordinates) shared_grid_access = SharedGridAccess(base_grid, manager=Manager()) line_to_middle = LineToMiddle(start_coordinates=line_start_coordinates, direction=Direction.RIGHT, block_line=list( map(bool, [0, 0, 1, 0, 1]))) robot_1_executor = LineScannerWrapperExecutor( line=line_to_middle, robot=robot_1, shared_grid_access=shared_grid_access, goal_building=goal_building) robot_2_executor = LineScannerWrapperExecutor( line=line_to_middle, robot=robot_2, shared_grid_access=shared_grid_access, goal_building=goal_building) robot_1_executor.start_working() robot_2_executor.start_working() robot_1_executor.wait_for_finish() robot_2_executor.wait_for_finish() grid = shared_grid_access.get_private_copy() assert goal_building.validate_grid(grid)
def _go_back_to_start_line(self, from_block_direction: Direction, line: LineToMiddle): line_start_position = line.start_coordinates.copy() if self.robot_coordinates == line_start_position: return if self.robot.rotation != from_block_direction: self.shared_actions_executor.try_rotate_robot(from_block_direction) met_robot = False hit_information = None while self.robot_coordinates != line_start_position: if not met_robot: hit_information = self.shared_actions_executor.try_move_robot( from_block_direction) if hit_information.hit_type == HitType.OBSTACLE: raise ValueError("scanner cannot work with obstacles") elif hit_information.hit_type == HitType.BLOCK: # we wait for other robot to take this block back self.shared_actions_executor.wait_action() elif hit_information.hit_type == HitType.ROBOT: # if we hit robot then he will know we put block met_robot = True else: distance_to_line_start = self.robot_coordinates.get_straight_distance_to_other( from_block_direction, line_start_position) if line.is_finished() or distance_to_line_start < 3: # don't take block if line finished make other robot take it back he will go back updating one block # in his private grid [ self.shared_actions_executor.wait_action() for _ in range(3) ] met_robot = False else: hit_information = self.shared_actions_executor.try_get_block( from_block_direction) if hit_information.hit_type == HitType.GOT_BLOCK: raise NotImplementedError()
def _split_goal(self): if self.is_splitted: return self.edges: List[GridEdge] = list() width = self.goal_building.width height = self.goal_building.height # first add elements that are not on diagonals # test_array = np.zeros((width, height), dtype=int) edge_block_counts = np.zeros( 4, dtype=int) # how many blocks each edge have assigned raising_diag_grid = np.zeros((width, height), dtype=bool) # True if diag on field decreasing_diag_grid = np.zeros((width, height), dtype=bool) if width == 1 or height == 1: raise ValueError("goal_building should be at least 3x3") if (width % 2 == 1) and (height % 2 == 1): mid_block_x = width // 2 mid_block_y = height // 2 mid_block_pos = (mid_block_x, mid_block_y) decreasing_diag_grid[mid_block_pos] = True raising_diag_grid[mid_block_pos] = True # D 0 R # 0 RD 0 # R 0 D decreasing_diag_left_pos = Coordinates(mid_block_x - 1, mid_block_y + 1) decreasing_diag_grid[ decreasing_diag_left_pos.get_array_index()] = True decreasing_diag_right_pos = Coordinates(mid_block_x + 1, mid_block_y - 1) decreasing_diag_grid[ decreasing_diag_right_pos.get_array_index()] = True raising_diag_left_pos = Coordinates(mid_block_x - 1, mid_block_y - 1) raising_diag_grid[raising_diag_left_pos.get_array_index()] = True raising_diag_right_pos = Coordinates(mid_block_x + 1, mid_block_y + 1) raising_diag_grid[raising_diag_right_pos.get_array_index()] = True else: # D R # R D left_x = width // 2 - 1 if height % 2 == 0: down_y = height // 2 - 1 else: down_y = height // 2 decreasing_diag_left_pos = Coordinates(left_x, down_y + 1) decreasing_diag_grid[ decreasing_diag_left_pos.get_array_index()] = True decreasing_diag_right_pos = Coordinates(left_x + 1, down_y) decreasing_diag_grid[ decreasing_diag_right_pos.get_array_index()] = True raising_diag_left_pos = Coordinates(left_x, down_y) raising_diag_grid[raising_diag_left_pos.get_array_index()] = True raising_diag_right_pos = Coordinates(left_x + 1, down_y + 1) raising_diag_grid[raising_diag_right_pos.get_array_index()] = True top_right_corner_walker = ToCornerWalker(raising_diag_grid, x_direction=Direction.RIGHT, y_direction=Direction.UP, pos=raising_diag_right_pos, width=width, height=height) top_right_corner_walker.update_diag_to_corner() down_right_corner_walker = ToCornerWalker( decreasing_diag_grid, x_direction=Direction.RIGHT, y_direction=Direction.DOWN, pos=decreasing_diag_right_pos, width=width, height=height) down_right_corner_walker.update_diag_to_corner() down_left_corner_walker = ToCornerWalker(raising_diag_grid, x_direction=Direction.LEFT, y_direction=Direction.DOWN, pos=raising_diag_left_pos, width=width, height=height) down_left_corner_walker.update_diag_to_corner() top_left_corner_walker = ToCornerWalker(decreasing_diag_grid, x_direction=Direction.LEFT, y_direction=Direction.UP, pos=decreasing_diag_left_pos, width=width, height=height) top_left_corner_walker.update_diag_to_corner() both_diags = (raising_diag_grid + 2 * decreasing_diag_grid) # now we want to create lines for each edge: edge_builds: List[EdgeBuild] = [ EdgeBuild(width, height, direction.get_opposite()) for direction in Direction ] edge_num = -1 for direction in Direction: edge_num += 1 direction: Direction = direction if direction.is_x_axis(): # for x axis we have y axis length amount of lines edge_len = height opposite_len = width else: edge_len = width opposite_len = height # for each line for i in range(edge_len): # if direction = UP # we would have something like this: # if rising then last index if direction == Direction.LEFT: line_scan_coordinate = Coordinates(0, i) elif direction == Direction.UP: line_scan_coordinate = Coordinates(i, opposite_len - 1) elif direction == Direction.RIGHT: line_scan_coordinate = Coordinates(opposite_len - 1, i) else: # DOWN line_scan_coordinate = Coordinates(i, 0) edge_builds[edge_num].add_line_start(line_scan_coordinate) for j in range(opposite_len): diag_tile = both_diags[ line_scan_coordinate.get_array_index()] if diag_tile: if diag_tile != 10 and self.goal_building.grid[ line_scan_coordinate.get_array_index()]: both_diags[ line_scan_coordinate.get_array_index()] = 10 # TODO: decide where this tile goes # decide_later.append(block_line, coordinate, edge_set) something like this # for now lets just add to first that got this edge_builds[edge_num].block_lines[(i, j)] = True edge_block_counts[edge_num] += 1 break if self.goal_building.grid[ line_scan_coordinate.get_array_index()]: edge_builds[edge_num].block_lines[(i, j)] = True edge_block_counts[edge_num] += 1 line_scan_coordinate = line_scan_coordinate.create_neighbour_coordinate( direction.get_opposite()) edge_num = -1 for direction in Direction: edge_num += 1 edge_build = edge_builds[edge_num] lines: List[LineToMiddle] = list() for i in range(edge_build.length): line = LineToMiddle(edge_build.line_starts[i], direction.get_opposite(), edge_build.block_lines[i]) lines.append(line) edge = GridEdge(self.robot_coordinates, self.source_positions, edge_build.length, lines) self.edges.append(edge)
def _put_block_on_map(self, line: LineToMiddle) -> Coordinates: placed_block_position = line.place_block() self.private_grid.add_tile_to_grid(Tile(TileType.BLOCK), placed_block_position) return placed_block_position
def test_robot_crash_updated_tiles_not_by_self_with_sleeps(self): text_grid = """ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 1 1 1 0 1 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 """ goal_building = GoalBuilding2D(text_grid=text_grid) robot_1 = Robot(Direction.DOWN) robot_1_source = Tile(TileType.SOURCE) robot_2 = Robot(Direction.UP) robot_2_source = Tile(TileType.SOURCE) line_start_coordinates = Coordinates(0, 9) base_grid = BaseGrid(goal_building.width, goal_building.height) robot_1_coordinates = Coordinates(0, 16) base_grid.add_tile_to_grid(robot_1, robot_1_coordinates) base_grid.add_tile_to_grid( robot_1_source, robot_1_coordinates.create_neighbour_coordinate(Direction.UP)) robot_2_coordinates = Coordinates(0, 1) base_grid.add_tile_to_grid(robot_2, robot_2_coordinates) base_grid.add_tile_to_grid( robot_2_source, robot_2_coordinates.create_neighbour_coordinate(Direction.DOWN)) shared_grid_access = SharedGridAccess(base_grid, manager=Manager()) line_to_middle = LineToMiddle( start_coordinates=line_start_coordinates, direction=Direction.RIGHT, block_line=list( map(bool, map(int, text_grid.split("\n")[9].split())))) robot_1_executor = LineScannerWithSourceWrapperExecutor( line=line_to_middle, robot=robot_1, shared_grid_access=shared_grid_access, goal_building=goal_building) robot_2_executor = LineScannerWithSourceWrapperExecutor( line=line_to_middle, robot=robot_2, shared_grid_access=shared_grid_access, goal_building=goal_building) robot_1_executor.start_working() robot_2_executor.start_working() robot_1_executor.wait_for_finish() robot_2_executor.wait_for_finish() grid = shared_grid_access.get_private_copy() assert goal_building.validate_grid(grid)
def __init__(self, line: LineToMiddle, robot: Robot, shared_grid_access: SharedGridAccess, goal_building: GoalBuilding): super().__init__(robot, shared_grid_access, goal_building, 0.0001) self.line = line.copy() self.line_scanner = LineScannerExecutor(self.shared_actions_executor)