示例#1
0
def get_boundary_walls(x_axis: int, y_axis: int):
    """Get a set of the boundary walls."""
    a = Vec2d(0, 0)
    b = Vec2d(x_axis, 0)
    c = Vec2d(x_axis, y_axis)
    d = Vec2d(0, y_axis)
    return {Line2d(a, b), Line2d(b, c), Line2d(c, d), Line2d(d, a)}
示例#2
0
def combine_walls(wall_list: list):
    """
    Combine every two wall-segments (Line2d) together that can be represented by only one line segment. This will
    increase the performance later on, since the intersection methods must loop over less wall-segments.

    :param wall_list: List<Line2d>
    :return: List<Line2d>
    """
    i = 0
    while i < len(wall_list) - 1:
        concat = False
        # Check if wall at i can be concatenated with wall after i
        for w in wall_list[i + 1:]:
            # Check if in same horizontal line
            if wall_list[i].x.y == wall_list[i].y.y == w.x.y == w.y.y:
                # Check if at least one point collides
                if wall_list[i].x.x == w.x.x:
                    wall_list[i] = Line2d(Vec2d(wall_list[i].y.x, w.x.y),
                                          Vec2d(w.y.x, w.x.y))
                    concat = True
                elif wall_list[i].y.x == w.x.x:
                    wall_list[i] = Line2d(Vec2d(wall_list[i].x.x, w.x.y),
                                          Vec2d(w.y.x, w.x.y))
                    concat = True
                elif wall_list[i].y.x == w.y.x:
                    wall_list[i] = Line2d(Vec2d(wall_list[i].x.x, w.x.y),
                                          Vec2d(w.x.x, w.x.y))
                    concat = True
                elif wall_list[i].x.x == w.y.x:
                    wall_list[i] = Line2d(Vec2d(wall_list[i].y.x, w.x.y),
                                          Vec2d(w.x.x, w.x.y))
                    concat = True

            # Check if in same vertical line
            elif wall_list[i].x.x == wall_list[i].y.x == w.x.x == w.y.x:
                # Check if at least one point collides
                if wall_list[i].x.y == w.x.y:
                    wall_list[i] = Line2d(Vec2d(w.x.x, wall_list[i].y.y),
                                          Vec2d(w.x.x, w.y.y))
                    concat = True
                elif wall_list[i].y.y == w.x.y:
                    wall_list[i] = Line2d(Vec2d(w.x.x, wall_list[i].x.y),
                                          Vec2d(w.x.x, w.y.y))
                    concat = True
                elif wall_list[i].y.y == w.y.y:
                    wall_list[i] = Line2d(Vec2d(w.x.x, wall_list[i].x.y),
                                          Vec2d(w.x.x, w.x.y))
                    concat = True
                elif wall_list[i].x.y == w.y.y:
                    wall_list[i] = Line2d(Vec2d(w.x.x, wall_list[i].y.y),
                                          Vec2d(w.x.x, w.x.y))
                    concat = True

            # If w concatenated with i'th wall in wall_list, then remove w from list and break for-loop
            if concat:
                wall_list.remove(w)
                break

        # Current wall cannot be extended, go to next wall
        if not concat: i += 1
示例#3
0
def create_custom_game(cfg: Config, overwrite=False):
    """ Dummy to create a custom-defined game. """
    # Initial parameters
    game_id = 0

    # Create empty Game instance
    game = Game(config=cfg, game_id=game_id, overwrite=overwrite)

    # Put the target on a fixed position
    game.target = Vec2d(0.5, cfg.game.y_axis - 0.5)

    # Set game path
    p = dict()  # TODO!
    for x in range(0, cfg.game.x_axis * 10 + 1):  # TODO!
        for y in range(0, cfg.game.x_axis * 10 + 1):  # TODO!
            p[(x / 10, y / 10)] = Line2d(game.target,
                                         Vec2d(x / 10, y / 10)).get_length()
    game.path = p

    # Create random player
    game.player = MarXBot(game=game)
    game.set_player_init_angle(a=np.pi / 2)
    game.set_player_init_pos(p=Vec2d(cfg.game.x_axis - 0.5, 0.5))

    # Check if implemented correctly
    game.close()
    game.reset()
    game.get_blueprint()
    game.get_observation()
    game.step(0, 0)

    # Save the final game
    game.save()
示例#4
0
    def measure(self, close_walls: set = None):
        """
        Get the distance to the closest wall. If all the walls are 'far enough', as determined by self.max_dist, then
        the maximum sensor-distance is returned.
        
        :param close_walls: Walls which fall within ray_distance from the agent, speeds up readings
        :return: Float expressing the distance to the closest wall, if there is any
        """
        # Start and end point of ray
        normalized_offset = Vec2d(cos(self.game.player.angle + self.angle),
                                  sin(self.game.player.angle + self.angle))
        self.start_pos = self.game.player.pos + normalized_offset * self.pos_offset
        self.end_pos = self.game.player.pos + normalized_offset * (
            self.pos_offset + self.max_dist)
        sensor_line = Line2d(x=self.game.player.pos, y=self.end_pos)

        # Check if there is a wall intersecting with the sensor and return the closest distance to a wall
        self.value = self.max_dist
        for wall in close_walls if close_walls else self.game.walls:
            inter, pos = line_line_intersection(sensor_line, wall)
            if inter:
                new_dist = (pos - self.start_pos).get_length()
                if self.value > new_dist:
                    self.end_pos = pos
                    self.value = new_dist

        if self.game.noise:
            self.value += random.gauss(0, self.game.noise_proximity)
            self.value = max(0, min(self.value, self.max_dist))
示例#5
0
 def test_simple_length(self):
     """> Test for simple line-segments."""
     # Folder must be root to load in make_net properly
     if os.getcwd().split('\\')[-1] == 'tests': os.chdir('..')
     
     # Create simple lines
     a = Vec2d(1, 1)
     b = Vec2d(1, 2)
     c = Vec2d(2, 2)
     line1 = Line2d(a, b)
     line2 = Line2d(b, c)
     line3 = Line2d(a, c)
     
     # Test the length
     self.assertTrue(1 - EPSILON <= line1.get_length() <= 1 + EPSILON)
     self.assertTrue(1 - EPSILON <= line2.get_length() <= 1 + EPSILON)
     self.assertTrue(sqrt(2) - EPSILON <= line3.get_length() <= sqrt(2) + EPSILON)
示例#6
0
 def test_other_angles(self):
     """> Check if drone cannot force itself through a wall."""
     # Folder must be root to load in make_net properly
     if os.getcwd().split('\\')[-1] == 'tests': os.chdir('..')
     
     # Create the lines
     zero = Vec2d(0, 0)
     a = Vec2d(1, 1)
     line1 = Line2d(zero, a)
     
     # Tests
     self.assertTrue(pi / 4 - EPSILON <= line1.get_orientation() % (2 * pi) <= pi / 4 + EPSILON)
示例#7
0
 def test_quadrant_angles(self):
     """> Check if drone cannot force itself through a wall."""
     # Folder must be root to load in make_net properly
     if os.getcwd().split('\\')[-1] == 'tests': os.chdir('..')
     
     # Create the lines
     zero = Vec2d(0, 0)
     a = Vec2d(1, 0)
     b = Vec2d(0, 1)
     c = Vec2d(-1, 0)
     d = Vec2d(0, -1)
     line1 = Line2d(zero, a)
     line2 = Line2d(zero, b)
     line3 = Line2d(zero, c)
     line4 = Line2d(zero, d)
     
     # Tests
     self.assertTrue(0 - EPSILON <= line1.get_orientation() % (2 * pi) <= 0 + EPSILON)
     self.assertTrue(pi / 2 - EPSILON <= line2.get_orientation() % (2 * pi) <= pi / 2 + EPSILON)
     self.assertTrue(pi - EPSILON <= line3.get_orientation() % (2 * pi) <= pi + EPSILON)
     self.assertTrue(3 * pi / 2 - EPSILON <= line4.get_orientation() % (2 * pi) <= 3 * pi / 2 + EPSILON)
示例#8
0
    def get_wall_coordinates(self):
        """
        :return: Wall coordinates of final maze (excluding boundaries) in original axis-format.
        """
        wall_list = []
        # Horizontal segments
        for x in range(1, self.x_width - 1, 2):
            for y in range(2, self.y_width, 2):
                if self.maze[y, x] == -1:
                    wall_list.append(
                        Line2d(Vec2d((x - 1) // 2, y // 2),
                               Vec2d((x + 1) // 2, y // 2)))
        # Vertical segments
        for x in range(2, self.x_width, 2):
            for y in range(1, self.y_width - 1, 2):
                if self.maze[y, x] == -1:
                    wall_list.append(
                        Line2d(Vec2d(x // 2, (y - 1) // 2),
                               Vec2d(x // 2, (y + 1) // 2)))

        combine_walls(wall_list)
        return wall_list
示例#9
0
    def load(self):
        """
        Load in a game, specified by its current id.

        :return: True: game successfully loaded | False: otherwise
        """
        try:
            game = load_pickle(f'{self.save_path}{self}')
            self.player = MarXBot(game=self)  # Create a dummy-player to set values on
            self.set_player_init_angle(game[D_ANGLE])
            self.set_player_init_pos(Vec2d(game[D_POS][0], game[D_POS][1]))
            self.path = {p[0]: p[1] for p in game[D_PATH]}
            self.target = Vec2d(game[D_TARGET][0], game[D_TARGET][1])
            self.walls = {Line2d(Vec2d(w[0][0], w[0][1]), Vec2d(w[1][0], w[1][1])) for w in game[D_WALLS]}
            if not self.silent: print(f"Existing game loaded with id: {self.id}")
            return True
        except FileNotFoundError:
            return False
示例#10
0
 def test_negative_component(self):
     """> Test for line-segments with negative components."""
     # Folder must be root to load in make_net properly
     if os.getcwd().split('\\')[-1] == 'tests': os.chdir('..')
     
     # Create simple lines
     a = Vec2d(1, 1)
     b = Vec2d(1, -1)
     c = Vec2d(-1, -1)
     d = Vec2d(-1, 1)
     line1 = Line2d(a, b)
     line2 = Line2d(b, c)
     line3 = Line2d(c, d)
     line4 = Line2d(d, a)
     diag1 = Line2d(a, c)
     diag2 = Line2d(b, d)
     
     # Test the length
     self.assertTrue(2 - EPSILON <= line1.get_length() <= 2 + EPSILON)
     self.assertTrue(2 - EPSILON <= line2.get_length() <= 2 + EPSILON)
     self.assertTrue(2 - EPSILON <= line3.get_length() <= 2 + EPSILON)
     self.assertTrue(2 - EPSILON <= line4.get_length() <= 2 + EPSILON)
     self.assertTrue(sqrt(8) - EPSILON <= diag1.get_length() <= sqrt(8.) + EPSILON)
     self.assertTrue(sqrt(8) - EPSILON <= diag2.get_length() <= sqrt(8.) + EPSILON)