Example #1
0
 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
Example #2
0
class RobotExecutorMockRotate(RobotExecutor):
    robot1_coordinates = Coordinates(2, 3)
    robot1_future_rotate = Direction.LEFT
    robot1_sleep = 1
    robot2_coordinates = Coordinates(1, 3)
    robot2_future_rotate = Direction.DOWN
    robot2_sleep = 3

    def __init__(self, where_rotate: Direction, how_long_sleep: int,
                 robot: Robot, shared_grid_access: SharedGridAccess,
                 goal_building: GoalBuilding):
        super().__init__(robot, shared_grid_access, goal_building)
        self.how_long_sleep = how_long_sleep
        self.where_rotate = where_rotate

    def start_process(self):
        sleep(self.how_long_sleep * 0.01)
        self.shared_actions_executor.try_rotate_robot(self.where_rotate)
        with self.shared_grid_access.grid_lock_sync as grid:
            if self.how_long_sleep == RobotExecutorMockRotate.robot1_sleep:
                robot1 = grid.get_tile_from_grid(
                    RobotExecutorMockRotate.robot1_coordinates)
                assert robot1.rotation == RobotExecutorMockRotate.robot1_future_rotate
            if self.how_long_sleep == RobotExecutorMockRotate.robot2_sleep:
                robot1 = grid.get_tile_from_grid(
                    RobotExecutorMockRotate.robot1_coordinates)
                assert robot1.rotation == RobotExecutorMockRotate.robot1_future_rotate
                robot2 = grid.get_tile_from_grid(
                    RobotExecutorMockRotate.robot2_coordinates)
                assert robot2.rotation == RobotExecutorMockRotate.robot2_future_rotate
 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
Example #4
0
 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)
Example #5
0
 def pop_tile_from_grid(self,
                        coordinates: Coordinates) -> Union[Tile, None]:
     tile_index = self.tile_grid[coordinates.get_array_index()]
     if tile_index is None:
         return None
     self.coordinates_from_index.pop(tile_index)
     self.tile_grid[coordinates.get_array_index()] = BaseGrid.empty_tile_id
     tile = self._get_tile_from_index(tile_index)
     if tile.get_type() == TileType.BLOCK:
         self.block_tile_grid[coordinates.get_array_index()] = False
     return tile
Example #6
0
        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))
Example #7
0
 def change_tile_type(col, row):
     if grid_window[col][row].cget('bg') == 'grey76':
         grid_window[col][row].configure(bg='yellow')
         controller.number_of_robots += 1
         robots_pos_set.add(Coordinates(col, row))
     elif grid_window[col][row].cget('bg') == 'yellow':
         grid_window[col][row].configure(bg='grey76')
         controller.number_of_robots -= 1
         robots_pos_set.remove(Coordinates(col, row))
     if controller.number_of_robots == 0:
         button.configure(state='disabled')
     else:
         button.configure(state='normal')
 def __init__(self, goal_building: GoalBuilding,
              robot_coordinates: Coordinates):
     super().__init__(goal_building)
     width = self.goal_building.width
     height = self.goal_building.height
     self.source_positions = list()
     self.source_positions.append(SourcePosition(Coordinates(0, 0)))
     self.source_positions.append(SourcePosition(Coordinates(0,
                                                             height - 1)))
     self.source_positions.append(
         SourcePosition(Coordinates(width - 1, height - 1)))
     self.source_positions.append(SourcePosition(Coordinates(width - 1, 0)))
     self.robot_coordinates = robot_coordinates
     self.is_splitted = False
 def go_to_goal(self, goal: Coordinates):
     goal = goal.copy()
     while not self._is_robot_on_same_edge_and_not_too_far(goal):
         robot_edge_side = self.robot_coordinates.get_edge_side(
             width=self.width, height=self.height)
         next_corner = self.spin.get_edge_next_corner(robot_edge_side,
                                                      width=self.width,
                                                      height=self.height)
         pre_corner_pos = self.spin.get_pre_corner_coordinates(next_corner)
         moving_direction = self.spin.get_edge_move_direction(
             robot_edge_side)
         if self.robot_coordinates != pre_corner_pos:
             self.shared_actions_executor.try_rotate_robot(moving_direction)
         while self.robot_coordinates != pre_corner_pos:
             hit_information = self.shared_actions_executor.try_move_robot(
                 moving_direction)
             if hit_information.hit_type != HitType.NO_HIT:
                 self.shared_actions_executor.wait_action()
         # robot is on pre_corner_coordinates
         self._go_around_corner(moving_direction)
     # here robot is on same edge as goal
     moving_direction = self.robot_coordinates.get_to_other_direction(goal)
     if self.robot.rotation != moving_direction:
         self.shared_actions_executor.try_rotate_robot(moving_direction)
     while self.robot_coordinates != goal:
         hit_information = self.shared_actions_executor.try_move_robot(
             moving_direction)
         if hit_information.hit_type != HitType.NO_HIT:
             self.shared_actions_executor.wait_action()
Example #10
0
    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()
Example #11
0
 def __init__(self, start_coordinates: Coordinates, direction: Direction,
              block_line: Iterable[bool]):
     self.block_line = copy.deepcopy(block_line)
     self.block_positions = LineToMiddle.get_block_positions_from_block_line(
         block_line)
     self.direction = direction
     self.start_coordinates = start_coordinates.copy()
     self.blocks_placed = 0
     self.blocks_to_place = len(self.block_positions)
Example #12
0
 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
Example #13
0
class TestBaseGrid(TestCase):
    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 test_add_new_tile_when_it_exists(self):
        self.base_grid_example.add_new_tile(self.block_tile)
        with self.assertRaises(TileAlreadyAddedException):
            self.base_grid_example.add_new_tile(self.block_tile)

    def test_add_get_tile_from_grid(self):
        self.base_grid_example.add_new_tile(self.block_tile)
        self.base_grid_example.add_new_tile(self.obstacle_tile)
        self.base_grid_example.add_tile_to_grid(
            tile=self.block_tile, coordinates=self.block_tile_coordinates)
        tile_from_block_tile_coordinates = self.base_grid_example.get_tile_from_grid(
            coordinates=self.block_tile_coordinates)
        assert tile_from_block_tile_coordinates == self.block_tile
        with self.assertRaises(TileTakenException):
            self.base_grid_example.add_tile_to_grid(
                tile=self.obstacle_tile,
                coordinates=self.block_tile_coordinates)
        self.base_grid_example.add_tile_to_grid(
            tile=self.obstacle_tile,
            coordinates=self.obstacle_tile_coordinates)
        tile_from_obstacle_tile_coordinates = self.base_grid_example.get_tile_from_grid(
            coordinates=self.obstacle_tile_coordinates)
        assert tile_from_obstacle_tile_coordinates == self.obstacle_tile

    def test_copy(self):
        self.test_add_get_tile_from_grid()
        grid_copy = self.base_grid_example.copy()
        tile_from_block_tile_coordinates = grid_copy.get_tile_from_grid(
            coordinates=self.block_tile_coordinates)
        print("copied", tile_from_block_tile_coordinates)
        print("not copied", self.block_tile)
        assert tile_from_block_tile_coordinates == self.block_tile
        new_block_coordinates = self.block_tile_coordinates.create_neighbour_coordinate(
            Direction.UP)
        print("new block coordinate", new_block_coordinates)
        grid_copy.move_tile_on_grid(self.block_tile, new_block_coordinates)
        assert grid_copy.get_tile_from_grid(
            new_block_coordinates) == self.block_tile
        assert grid_copy.get_tile_from_grid(
            self.block_tile_coordinates) is None
        assert self.base_grid_example.get_tile_from_grid(
            new_block_coordinates) != self.block_tile
        assert self.base_grid_example.get_tile_from_grid(
            self.block_tile_coordinates) == self.block_tile
    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 _is_robot_on_same_edge_and_not_too_far(self,
                                            goal: Coordinates) -> bool:
     robot_edge_side = self.robot_coordinates.get_edge_side(
         width=self.width, height=self.height)
     goal_edge_side = goal.get_edge_side(width=self.width,
                                         height=self.height)
     if robot_edge_side != goal_edge_side:
         return False
     moving_direction = self.spin.get_edge_move_direction(robot_edge_side)
     # distance <0 means we already are too far from source and need to make another lap
     return self.robot_coordinates.get_straight_distance_to_other(
         moving_direction, goal) >= 0
    def test_shared_sync(self):
        base_grid = BaseGrid(5, 5)

        robot1 = Robot(Direction.RIGHT)
        robot1_coordinates = Coordinates(2, 2)

        robot2 = Robot(Direction.UP)
        robot2_coordinates = Coordinates(1, 3)

        base_grid.add_tile_to_grid(robot1, robot1_coordinates)
        base_grid.add_tile_to_grid(robot2, robot2_coordinates)
        shared_grid_access = SharedGridAccess(base_grid, Manager())

        shared_grid_access.try_rotate_robot(robot1, Direction.LEFT)
        robot1.rotate_to_direction(Direction.LEFT)

        shared_grid_access.try_move_robot(robot2, Direction.UP)
        robot2_coordinates = robot2_coordinates.create_neighbour_coordinate(Direction.UP)
        with shared_grid_access.grid_lock_sync as grid:
            assert grid.get_tile_from_grid(robot1_coordinates) == robot1
            assert grid.get_tile_from_grid(robot2_coordinates) == robot2
            print(grid)
Example #17
0
 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)
Example #18
0
class RobotExecutorMockMove(RobotExecutor):
    robot1_coordinates = Coordinates(4, 4)
    robot1_move_direction = Direction.LEFT
    robot1_sleep = 1
    robot2_coordinates = Coordinates(1, 3)
    robot2_move_direction = Direction.DOWN
    robot2_sleep = 3

    def __init__(self, move_direction: Direction, how_long_sleep: int,
                 robot: Robot, shared_grid_access: SharedGridAccess,
                 goal_building: GoalBuilding):
        super().__init__(robot, shared_grid_access, goal_building)
        self.how_long_sleep = how_long_sleep
        self.move_direction = move_direction
        self.r1_c = RobotExecutorMockMove.robot1_coordinates.create_neighbour_coordinate(
            RobotExecutorMockMove.robot1_move_direction)
        self.r2_c = RobotExecutorMockMove.robot2_coordinates.create_neighbour_coordinate(
            RobotExecutorMockMove.robot2_move_direction)

    def start_process(self):
        sleep(self.how_long_sleep * 0.01)
        self.shared_actions_executor.try_move_robot(self.move_direction)
        with self.shared_grid_access.grid_lock_sync as grid:

            if self.how_long_sleep == RobotExecutorMockMove.robot1_sleep:
                robot1 = grid.get_tile_from_grid(self.r1_c)
                assert robot1 == self.robot
            if self.how_long_sleep == RobotExecutorMockMove.robot2_sleep:
                robot1 = grid.get_tile_from_grid(self.r1_c)
                assert robot1 is not None
                robot1 = grid.get_tile_from_grid(
                    RobotExecutorMockMove.robot1_coordinates)
                assert robot1 is None

                robot2 = grid.get_tile_from_grid(self.r2_c)
                assert robot2 == self.robot
                robot2 = grid.get_tile_from_grid(
                    RobotExecutorMockMove.robot2_coordinates)
                assert robot2 is None
Example #19
0
    def test_out_of_bound(self):
        base_grid = BaseGrid(5, 5)

        robot = Robot(Direction.UP)
        robot_coordinates = Coordinates(4, 4)

        base_grid.add_tile_to_grid(robot, robot_coordinates)
        shared_grid_access = SharedGridAccess(base_grid, Manager())
        h_info = shared_grid_access.try_move_robot(robot, Direction.UP)
        assert h_info.hit_type == HitType.ERROR
        assert isinstance(h_info.inner_error, OutOfBoundCoordinatesError)
        with shared_grid_access.grid_lock_sync as grid:
            assert grid.get_tile_from_grid(robot_coordinates) == robot
            print(grid)
Example #20
0
 def __init__(self, start_coordinates: Coordinates, direction: Direction,
              block_line: Iterable[bool]):
     self.block_line = copy.deepcopy(block_line)
     self.block_positions = LineToMiddle.get_block_positions_from_block_line(
         block_line)
     self.direction = direction
     self.start_coordinates = start_coordinates.copy()
     self.blocks_placed = 0
     self.blocks_to_place = len(self.block_positions)
     # last position where block could be placed or not
     if not self.is_finished():
         self.last_position = self.start_coordinates.create_moved_coordinate(
             self.direction, self.block_positions[0])
     else:
         self.last_position = self.start_coordinates
 def __init__(self, diag_grid: np.ndarray, x_direction: Direction,
              y_direction: Direction, pos: Coordinates, width: int,
              height: int):
     self.height = height
     self.width = width
     self.pos: Coordinates = pos
     self.diag_grid = diag_grid
     self.x_direction = x_direction
     self.y_direction = y_direction
     self.last_x_pos = self.x_direction.is_x_or_y_rising() * (self.width -
                                                              1)
     self.last_y_pos = self.y_direction.is_x_or_y_rising() * (self.height -
                                                              1)
     self.last_pos = Coordinates(self.last_x_pos, self.last_y_pos)
     self.was_last_x = False
     self.was_last_y = False
 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))
Example #23
0
 def get_edge_next_corner(self, edge_side: Direction, width: int, height: int) -> Coordinates:
     max_x = width - 1
     max_y = height - 1
     if self == Spin.CLOCKWISE:
         if edge_side == Direction.UP:
             return Coordinates(max_x, max_y)
         elif edge_side == Direction.RIGHT:
             return Coordinates(max_x, 0)
         elif edge_side == Direction.DOWN:
             return Coordinates(0, 0)
         else:
             return Coordinates(0, max_y)
     if edge_side == Direction.UP:
         return Coordinates(0, max_y)
     elif edge_side == Direction.LEFT:
         return Coordinates(0, 0)
     elif edge_side == Direction.DOWN:
         return Coordinates(max_x, 0)
     else:
         return Coordinates(max_x, max_y)
Example #24
0
 def get_pre_corner_coordinates(self, corner: Coordinates) -> Coordinates:
     if self == Spin.ANTI_CLOCKWISE:
         if corner.x == 0:
             if corner.y == 0:
                 return Coordinates(0, 1)
             # we assume y == height
             return Coordinates(1, corner.y)
         # we assume x == width
         elif corner.y != 0:
             # we assume y == height
             return Coordinates(corner.x, corner.y - 1)
         return Coordinates(corner.x - 1, 0)
     if corner.x == 0:
         if corner.y == 0:
             return Coordinates(1, 0)
         # we assume y == height
         return Coordinates(0, corner.y - 1)
     # we assume x == width
     elif corner.y != 0:
         # we assume y == height
         return Coordinates(corner.x - 1, corner.y)
     return Coordinates(corner.x, 1)
Example #25
0
 def get_position(self, direction: Direction) -> SourcePosition:
     max_x = self.width - 1
     max_y = self.height - 1
     if direction == Direction.LEFT:
         if self.spin == Spin.CLOCKWISE:
             return SourcePosition(Coordinates(0, 0))
         else:
             return SourcePosition(Coordinates(0, max_y))
     elif direction == Direction.UP:
         if self.spin == Spin.CLOCKWISE:
             return SourcePosition(Coordinates(0, max_y))
         else:
             return SourcePosition(Coordinates(max_x, max_y))
     elif direction == Direction.RIGHT:
         if self.spin == Spin.CLOCKWISE:
             return SourcePosition(Coordinates(max_x, max_y))
         else:
             return SourcePosition(Coordinates(max_x, 0))
     elif direction == Direction.DOWN:
         if self.spin == Spin.CLOCKWISE:
             return SourcePosition(Coordinates(max_x, 0))
         else:
             return SourcePosition(Coordinates(0, 0))
 def __init__(self,
              robot: Robot,
              shared_grid_access: SharedGridAccess,
              goal_building: GoalBuilding,
              goal_to_edges_splitter: GoalToEdgesSplitter,
              spin: Spin,
              sleep_tick_seconds: float = None,
              robot_coordinates: Coordinates = None,
              start_offset: int = 0,
              start_edge_index: int = None):
     super().__init__(robot, shared_grid_access, goal_building, robot_coordinates=robot_coordinates,
                      sleep_tick_seconds=sleep_tick_seconds)
     self.private_grid.add_tile_to_grid(self.robot, self.robot_coordinates.copy())
     self.start_offset = start_offset
     self.robot_coordinates = self.private_grid.get_coord_from_tile(robot)
     self.spin = spin
     self.highway_executor = HighwayExecutor(
         shared_actions_executor=self.shared_actions_executor,
         spin=spin
     )
     self.line_scanner_executor = LineScannerExecutor(
         shared_actions_executor=self.shared_actions_executor
     )
     self.edges: List[GridEdge] = goal_to_edges_splitter.get_edges()
     if start_edge_index is None:
         edge_side = robot_coordinates.get_edge_side(width=goal_building.width, height=goal_building.height)
         next_side = spin.get_edge_move_direction(edge_side)
         for i in range(0, 4):
             self.edge_index = i
             self.edge = self.edges[self.edge_index]
             if next_side == self.edge.edge_side:
                 print(f"robot: {robot} got side {next_side}")
                 break
     else:
         self.edge_index = start_edge_index
         self.edge = self.edges[self.edge_index % 4]
Example #27
0
    def test_move_far_scenario(self):
        base_grid = BaseGrid(5, 5)
        goal_building = GoalBuilding("""
            0 0 0 0 0
            0 0 1 0 0
            0 1 2 1 0
            0 0 1 2 0
            0 0 0 0 0
            """)
        # rotate, move, end coordinates:
        # if move or rotate is None then don't do it
        robot_states = [(Direction.UP, None, Coordinates(0, 0)),
                        (None, Direction.UP, Coordinates(0, 1)),
                        (Direction.DOWN, Direction.UP, Coordinates(0, 2)),
                        (Direction.RIGHT, Direction.RIGHT, Coordinates(1, 2)),
                        (None, Direction.RIGHT, Coordinates(2, 2)),
                        (None, Direction.LEFT, Coordinates(1, 2))]
        rotate_directions = [state[0] for state in robot_states]
        moving_directions = [state[1] for state in robot_states]
        robot_coordinates = [state[2] for state in robot_states]

        robot = Robot(rotate_directions[0])
        base_grid.add_tile_to_grid(robot, robot_coordinates[0])

        shared_grid_access = SharedGridAccess(base_grid, Manager())

        for i in range(1, len(robot_states)):
            rotate = rotate_directions[i]
            move = moving_directions[i]

            robot_executor = RobotRotateMoveMockExecutor(
                rotate, move, robot, shared_grid_access, goal_building)
            robot_executor.start_working()
            robot_executor.wait_for_finish()
            if rotate is not None:
                robot.rotate_to_direction(rotate)
            grid_copy = shared_grid_access.get_private_copy()
            # robot from grid has wrong direction
            robot_grid = grid_copy.get_tile_from_grid(robot_coordinates[i])
            assert robot_grid == robot
    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)
                self._make_y_progress()
            else:
                self._make_x_progress()


class GoalBuildingMock(GoalBuilding):
    def __init__(self):
        self.width = 11
        self.height = 16
        self.grid = np.zeros((self.width, self.height), dtype=bool)
        self.grid[(7, 3)] = True
        self.grid[(7, 4)] = True
        self.grid[(8, 3)] = True
        self.grid[(8, 4)] = True

    def validate_grid(self, base_grid: BaseGrid):
        pass


if __name__ == '__main__':
    goal_building_mock = GoalBuildingMock()
    building = GoalBuilding2D("""
        0 0 0 0 0
        0 0 1 0 0
        0 1 1 1 0
        0 0 1 0 0
        0 0 0 0 0
        """)
    splitter = GoalToEdgesXSplitter(building, Coordinates(1, 0))
    splitter._split_goal()
Example #30
0
 def get_tile_from_grid(self, coordinates: Coordinates) -> Tile:
     try:
         tile_index = self.tile_grid[coordinates.get_array_index()]
     except IndexError as e:
         raise OutOfBoundCoordinatesError(e.args)
     return self._get_tile_from_index(tile_index)