Esempio n. 1
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_single_robot_finish_single_line_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 1 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 = 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)
     base_grid.add_tile_to_grid(
         Tile(TileType.SOURCE),
         line_start_coordinates.create_neighbour_coordinate(Direction.UP))
     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, 1, 1, 0, 1]))
     for i in range(3):
         line_scanner_executor.scan_line(line=line_to_middle)
         grid = shared_grid_access.get_private_copy()
         assert grid.get_coord_from_tile(robot) == line_start_coordinates
         # we rotate take block from source and do another block
         shared_actions_executor.try_rotate_robot(Direction.UP)
         shared_actions_executor.try_get_block(Direction.UP)
         grid = shared_grid_access.get_private_copy()
         assert grid.get_tile_from_grid(line_start_coordinates) == robot
     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 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)
    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 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)