def setUp(self): self.example_width = 5 self.example_height = 5 self.base_grid_example = BaseGrid(width=self.example_width, height=self.example_height) print("setup") self.block_tile = Tile(TileType.BLOCK) self.obstacle_tile = Tile(TileType.OBSTACLE) self.block_tile_coordinates = Coordinates(1, 1) self.obstacle_tile_coordinates = Coordinates(3, 3)
def create_simulation(parent, controller): robots: List[Robot] = list() how_many_robots = controller.number_of_robots robots_pos: List[Coordinates] = list() id = 10000 for pos in robots_pos_set: id += 1 robot = Robot(Direction.UP) robot.id = id robots.append(robot) robots_pos.append(pos) base_grid = BaseGrid(goal_building.width, goal_building.height) base_grid.add_tile_to_grid(Tile(TileType.SOURCE), Coordinates(0, 0)) base_grid.add_tile_to_grid(Tile(TileType.SOURCE), Coordinates(goal_building.width - 1, 0)) base_grid.add_tile_to_grid( Tile(TileType.SOURCE), Coordinates(goal_building.width - 1, goal_building.height - 1)) base_grid.add_tile_to_grid( Tile(TileType.SOURCE), Coordinates(0, goal_building.height - 1)) shared_grid_access = SharedGridAccess(base_grid, manager=Manager()) spin = Spin.ANTI_CLOCKWISE goal_to_edges_splitter = GoalToEdgesXSplitter(goal_building, spin) robot_executors: List[RobotExecutor] = list() for i in range(how_many_robots): robot_executors.append( SpiralRobotExecutor( robot=robots[i], shared_grid_access=shared_grid_access, goal_building=goal_building, goal_to_edges_splitter=goal_to_edges_splitter, spin=spin, start_offset=i, robot_coordinates=robots_pos[i], sleep_tick_seconds=0)) with shared_grid_access.grid_lock_sync as grid: for i in range(how_many_robots): grid.add_tile_to_grid(robots[i], robots_pos[i]) controller.robot_executors = robot_executors controller.shared_grid_access = shared_grid_access controller.goal_building = goal_building for robot_executor in controller.robot_executors: robot_executor.start_working() controller.show_frame(GridWindow(parent, controller))
def test_validate(self): base_grid = BaseGrid(5, 4) base_grid.add_tile_to_grid(Tile(TileType.BLOCK), Coordinates(1, 1)) base_grid.add_tile_to_grid(Tile(TileType.BLOCK), Coordinates(2, 2)) base_grid.add_tile_to_grid(Tile(TileType.BLOCK), Coordinates(3, 1)) base_grid.add_tile_to_grid(Tile(TileType.BLOCK), Coordinates(4, 0)) goal_building = GoalBuilding2D(self.text_grid) assert goal_building.validate_grid(base_grid) base_grid.add_tile_to_grid(Tile(TileType.BLOCK), Coordinates(3, 3)) assert not goal_building.validate_grid(base_grid) base_grid.pop_tile_from_grid(Coordinates(3, 3)) assert goal_building.validate_grid(base_grid) base_grid.remove_tile_from_grid(Coordinates(2, 2)) assert not goal_building.validate_grid(base_grid) print(str(goal_building))
def try_get_block(self, direction: Direction) -> HitInformation: hit_information = self.shared_grid_access.try_get_block( self.robot, direction) RobotSharedActionsExecutor._hit_error_validator(hit_information) if hit_information.hit_type == HitType.GOT_BLOCK: self.robot.update_from_robot(hit_information.updated_robot) elif hit_information.hit_type == HitType.BLOCK: self.private_grid.add_tile_to_grid( Tile(TileType.BLOCK), self._get_robot_neighbour_coordinates(direction)) elif hit_information.hit_type == HitType.OBSTACLE: self.private_grid.add_tile_to_grid( Tile(TileType.OBSTACLE), self._get_robot_neighbour_coordinates(direction)) return hit_information
def test_put_block(self): base_grid = BaseGrid(5, 5) robot = Robot(Direction.UP) robot_coordinates = Coordinates(4, 4) inner_block = Tile(TileType.BLOCK) robot.take_block(inner_block) base_grid.add_tile_to_grid(robot, robot_coordinates) shared_grid_access = SharedGridAccess(base_grid, Manager()) h_info = shared_grid_access.try_put_block(robot, Direction.UP) assert h_info.hit_type == HitType.ERROR assert isinstance(h_info.inner_error, OutOfBoundCoordinatesError) h_info = shared_grid_access.try_put_block(robot, Direction.LEFT) assert h_info.hit_type == HitType.ERROR assert isinstance(h_info.inner_error, WrongBlockPutDirection) h_info = shared_grid_access.try_rotate_robot(robot, Direction.LEFT) assert h_info.hit_type == HitType.ROTATED robot.rotate_to_direction(Direction.LEFT) h_info = shared_grid_access.try_put_block(robot, Direction.LEFT) assert h_info.hit_type == HitType.PLACED_BLOCK inner_block = robot.pop_block() h_info = shared_grid_access.try_move_robot(robot, Direction.LEFT) assert h_info.hit_type == HitType.BLOCK assert isinstance(h_info.inner_error, TileTakenException) assert inner_block == h_info.inner_error.get_tile()
def get_coord_from_tile(self, tile: Tile) -> Coordinates: coordinates = self.coordinates_from_index.get(tile.get_id()) if coordinates is None: raise TileNotExistsException("tile: (" + str(tile) + ") was not added") # print("coord from tile: ", tile, "was", coordinates) return coordinates.copy()
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 _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 try_put_block(self, direction: Direction) -> HitInformation: hit_information = self.shared_grid_access.try_put_block( self.robot, direction) RobotSharedActionsExecutor._hit_error_validator(hit_information) if hit_information.hit_type == HitType.PLACED_BLOCK: self.private_grid.add_tile_to_grid( self.robot.pop_block(), self._get_robot_neighbour_coordinates(direction)) # no need to update robot we already popped block elif hit_information.hit_type == HitType.BLOCK: self.private_grid.add_tile_to_grid( Tile(TileType.BLOCK), self._get_robot_neighbour_coordinates(direction)) elif hit_information.hit_type == HitType.OBSTACLE: self.private_grid.add_tile_to_grid( Tile(TileType.OBSTACLE), self._get_robot_neighbour_coordinates(direction)) return hit_information
def add_tile_to_grid(self, tile: Tile, coordinates: Coordinates): if self.tiles_from_index.get(tile.get_id()) is None: self.add_new_tile(tile) else: tile_coordinates = self.coordinates_from_index.get(tile.get_id()) if tile_coordinates is not None: raise AddDuplicateTileError("tile " + str(tile) + " already exists on " + str(tile_coordinates)) tile_on_coordinates = self.get_tile_from_grid(coordinates) if tile_on_coordinates is not None: raise TileTakenException( tile_on_coordinates, f"there is already tile: ({str(tile)}) on {str(coordinates)}") self.tile_grid[coordinates.get_array_index()] = tile.get_id() self.coordinates_from_index[tile.get_id()] = coordinates if tile.get_type() == TileType.BLOCK: self.block_tile_grid[coordinates.get_array_index()] = True
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 move_tile_on_grid(self, tile: Tile, coordinates: Coordinates): if self.tiles_from_index.get(tile.get_id()) is None: raise TileNotExistsException("tile: (" + str(tile) + ") was not added") tile_on_coordinates = self.get_tile_from_grid(coordinates) if tile_on_coordinates is not None: if tile_on_coordinates.id != tile.id: raise TileTakenException( tile_on_coordinates, f"there is already tile: ({str(tile)}) on {str(coordinates)}" ) # else it means we move to same tile we were on previous_coordinates = self.coordinates_from_index.get(tile.get_id()) if previous_coordinates is None: raise TileNotExistsException("tile: (" + str(tile) + ") did not have coordinates") self.coordinates_from_index[tile.get_id()] = coordinates.copy() self.tile_grid[ previous_coordinates.get_array_index()] = BaseGrid.empty_tile_id self.tile_grid[coordinates.get_array_index()] = tile.get_id() self.tiles_from_index[tile.get_id()] = tile if tile.get_type() == TileType.BLOCK: self.block_tile_grid[ previous_coordinates.get_array_index()] = False self.block_tile_grid[coordinates.get_array_index()] = True
def try_get_block(self, direction: Direction) -> HitInformation: hit_information = self.shared_grid_access.try_get_block( self.robot, direction) RobotSharedActionsExecutor._hit_error_validator(hit_information) if hit_information.hit_type == HitType.GOT_BLOCK: self.robot.update_from_robot(hit_information.updated_robot) block_coordinates = self.robot_coordinates.create_neighbour_coordinate( direction) if self.private_grid.get_tile_from_grid( block_coordinates).get_type() != TileType.SOURCE: self.private_grid.pop_tile_from_grid(block_coordinates) # if robot took block then his total is -1 self.put_blocks -= 1 elif hit_information.hit_type == HitType.BLOCK: self.private_grid.add_tile_to_grid( Tile(TileType.BLOCK), self._get_robot_neighbour_coordinates(direction)) elif hit_information.hit_type == HitType.OBSTACLE: self.private_grid.add_tile_to_grid( Tile(TileType.OBSTACLE), self._get_robot_neighbour_coordinates(direction)) return hit_information
def get_tile_from_source(self, coordinates: Coordinates) -> Tile: try: tile_index = self.tile_grid[coordinates.get_array_index()] except IndexError as e: raise OutOfBoundCoordinatesError(e.args) tile = self._get_tile_from_index(tile_index) if tile is None: raise TileNotExistsException("tile index: (" + str(tile_index) + ") did not have tile") if tile.get_type() != TileType.SOURCE: raise TileNotSourceError(tile, "tile: (" + str(tile) + ") is not source") return Tile(TileType.BLOCK)
def take_block(self, tile: Tile): if self.inner_block is not None: raise HasInnerBlockError("cannot get block if already has") if tile.get_type() != TileType.BLOCK: raise WrongBlockTypeError("robot can only take block type tiles") self.inner_block = tile
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 _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_simple_map(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 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 1 1 1 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 1 1 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 1 1 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 1 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 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 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.id = 1000000001 robot_2 = Robot(Direction.UP) robot_2.id = 1000000002 robot_1_coordinates = Coordinates(0, 1) robot_2_coordinates = Coordinates(23, 16) base_grid = BaseGrid(goal_building.width, goal_building.height) base_grid.add_tile_to_grid(Tile(TileType.SOURCE), Coordinates(0, 0)) base_grid.add_tile_to_grid(Tile(TileType.SOURCE), Coordinates(goal_building.width-1, 0)) base_grid.add_tile_to_grid(Tile(TileType.SOURCE), Coordinates(goal_building.width-1, goal_building.height-1)) base_grid.add_tile_to_grid(Tile(TileType.SOURCE), Coordinates(0, goal_building.height-1)) shared_grid_access = SharedGridAccess(base_grid, manager=Manager()) spin = Spin.ANTI_CLOCKWISE goal_to_edges_splitter = GoalToEdgesXSplitter(goal_building, spin) robot_1_executor = SpiralRobotExecutor( robot=robot_1, shared_grid_access=shared_grid_access, goal_building=goal_building, goal_to_edges_splitter=goal_to_edges_splitter, spin=spin, start_offset=0, start_edge_index=0, robot_coordinates=robot_1_coordinates, sleep_tick_seconds=0.000001 ) robot_2_executor = SpiralRobotExecutor( robot=robot_2, shared_grid_access=shared_grid_access, goal_building=goal_building, goal_to_edges_splitter=goal_to_edges_splitter, spin=spin, start_offset=0, start_edge_index=2, robot_coordinates=robot_2_coordinates, sleep_tick_seconds=0.000001 ) with shared_grid_access.grid_lock_sync as grid: grid.add_tile_to_grid(robot_1, robot_1_coordinates) grid.add_tile_to_grid(robot_2, robot_2_coordinates) 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 update_tile(self, tile: Tile): self.tiles_from_index[tile.get_id()] = tile
def test_multi_robot(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 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 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 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 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 0 0 1 0 0 0 1 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 1 0 1 1 1 0 0 1 0 0 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 1 0 0 0 1 0 0 1 0 0 0 1 0 1 0 0 0 0 0 0 0 1 0 0 1 0 1 1 1 1 0 0 0 0 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 1 0 1 0 1 0 0 1 0 0 0 1 0 1 0 0 0 0 0 0 0 1 0 0 1 0 1 1 1 1 0 0 0 0 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 1 0 1 0 1 0 0 1 0 0 0 1 0 1 0 0 0 0 0 0 0 1 0 0 0 0 1 1 1 1 0 1 0 0 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 1 0 1 0 1 0 0 1 0 0 0 1 0 1 0 0 0 0 0 0 0 1 0 0 0 0 1 1 1 1 0 0 0 0 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 1 0 1 0 1 0 0 1 0 0 0 1 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 1 1 0 0 0 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 1 0 1 0 1 0 0 1 0 0 0 1 0 1 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 1 1 0 0 0 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 1 0 1 0 1 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 1 1 0 0 0 1 0 0 0 1 1 1 1 1 1 1 1 1 0 1 0 0 1 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 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 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 """ goal_building = GoalBuilding2D(text_grid=text_grid) robots: List[Robot] = list() robots_pos: List[Coordinates] = list() how_many_robots = 4 for i in range(how_many_robots): robots.append(Robot(Direction.UP)) robots_pos.append(Coordinates(i+1, 0)) base_grid = BaseGrid(goal_building.width, goal_building.height) base_grid.add_tile_to_grid(Tile(TileType.SOURCE), Coordinates(0, 0)) base_grid.add_tile_to_grid(Tile(TileType.SOURCE), Coordinates(goal_building.width-1, 0)) base_grid.add_tile_to_grid(Tile(TileType.SOURCE), Coordinates(goal_building.width-1, goal_building.height-1)) base_grid.add_tile_to_grid(Tile(TileType.SOURCE), Coordinates(0, goal_building.height-1)) shared_grid_access = SharedGridAccess(base_grid, manager=Manager()) spin = Spin.ANTI_CLOCKWISE goal_to_edges_splitter = GoalToEdgesXSplitter(goal_building, spin) robot_executors: List[RobotExecutor] = list() for i in range(how_many_robots): robot_executors.append(SpiralRobotExecutor( robot=robots[i], shared_grid_access=shared_grid_access, goal_building=goal_building, goal_to_edges_splitter=goal_to_edges_splitter, spin=spin, start_offset=i, start_edge_index=i % 4, robot_coordinates=robots_pos[i], sleep_tick_seconds=0 )) with shared_grid_access.grid_lock_sync as grid: for i in range(how_many_robots): grid.add_tile_to_grid(robots[i], robots_pos[i]) for i in range(how_many_robots): robot_executors[i].start_working() for i in range(how_many_robots): robot_executors[i].wait_for_finish() grid = shared_grid_access.get_private_copy() assert goal_building.validate_grid(grid)
def add_new_tile(self, tile: Tile): if self.tiles_from_index.get(tile.get_id()) is not None: raise TileAlreadyAddedException("tile " + str(tile) + " already exists") self.tiles_from_index[tile.get_id()] = tile