Beispiel #1
0
    def close_claim(self, poly, speed, game):
        inside, outside = game_utils.cut_poly(self.game_area, poly)

        # we will triangulate only one of the guys
        # then we check if it is the bigger portion (last known area minus new)

        total_area = game_utils.total_area([self._start_game_area])
        prev_remaining = total_area - game.stats['claimed_area']

        rects_out = game_utils.triangulate(outside) or []

        qixes = [qix for qix in self.qix if not qix.claimed]
        # flip sides if the qix is not in the game area - can't claim
        # qix space
        claimed_qix = []
        for qix in qixes:
            if not game_utils.in_area((qix.x, qix.y), rects_out, on_line=True):
                claimed_qix.append(qix)

        claimed_area = prev_remaining - game_utils.total_area(rects_out)
        available_area = prev_remaining - claimed_area

        if (len(claimed_qix) > len(qixes) / 2.0) or (available_area < claimed_area and len(claimed_qix) >= len(qixes)):
            # outside normally should be bigger than inside
            # exception is when we have more qix on the smaller patch
            inside, outside = outside, inside
            rects_out = game_utils.triangulate(outside) or []
            claimed_area = prev_remaining - game_utils.total_area(rects_out)


        for qix in qixes:
            if not game_utils.in_area((qix.x, qix.y), rects_out, on_line=True):
                qix.claimed = True

        self.game_rects = rects_out
        self.game_area = outside
        self.game_area_path.points = outside

        claimed = sprites.ClaimedPoly(inside, speed)
        self.claimed_polys_containter.add_child(claimed)
        claimed.appear()
        self.claimed_polys.append((inside, 1))

        for qix in self.qix:
            # make sure they are not easing some place nasty
            qix.next_target()

        game.update_score(claimed_area, speed)
Beispiel #2
0
    def in_free_area(self, dot):
        """checks if the dot is in the free area"""
        if not self.in_game_bounds(dot):
            # first we check if the dot is within out game area
            return False

        return game_utils.in_area(dot, self.game_rects, on_line=True)
Beispiel #3
0
    def next_target(self, sprite=None):
        self.prev_x, self.prev_y = self.x, self.y

        scene = self.get_scene()
        if not scene:
            return

        game_rects, game_poly = scene.board.game_rects, scene.board.game_area

        game_lines = [(dot1, dot2) for dot1, dot2 in zip(game_poly, game_poly[1:])]

        delta_angle = 0
        angle_range = 180

        in_area, stuck = False, 0
        while not in_area and stuck < 10:
            stuck += 1
            delta_angle = self.current_angle - math.radians(angle_range / 2) + random.random() * math.radians(angle_range)

            distance = random.randint(self.min_distance, self.max_distance)

            x, y = self.x + distance * math.cos(delta_angle), self.y + distance * math.sin(delta_angle)
            x, y = int(x), int(y)

            dots = [(x, y)]
            in_area = all((game_utils.in_area(dot, game_rects) for dot in dots))

            if in_area:
                # check for overlaps
                line_pairs = ((((x, y), (self.x, self.y)), line) for line in game_lines)
                for pair in line_pairs:
                    if game_utils.intersection(*pair):
                        in_area = False
                        break


            if not in_area:
                angle_range += 60


        self.current_angle = delta_angle % math.radians(360)

        self.steps = random.randint(self.min_steps, self.max_steps)
        self.current_step = 0

        if stuck < 10:
            self.next_x, self.next_y = x, y
            self.next_distance = distance
Beispiel #4
0
    def _handle_keys(self, keys_down, game):
        x, y = self.cube.x, self.cube.y


        # if we have direction, we know that user wants to do something
        # when drawing hasn't been initiated, user can move around the game poly
        # moving around game poly means the dot is on the line at any given time


        # when drawing is started, user can move all over the place but can't bump
        # into the current drawing polygon
        # path is closed if the move ends up on the game poly
        #

        # both cases we will want to adjust the new_x or new direction so that
        # it is somewhere on the line
        game_poly_dot, non_game_poly_dot = None, None


        current_pos = (self.cube.x, self.cube.y)
        if current_pos in self.game_area:
            current_line = [game_utils.prev_dot(current_pos, self.game_area),
                            current_pos,
                            game_utils.next_dot(current_pos, self.game_area)]
        else:
            current_line = game_utils.on_line(current_pos, self.game_area)

        key_directions = {
            gdk.KEY_Left: "left",
            gdk.KEY_j: "left",
            gdk.KEY_J: "left",

            gdk.KEY_Right: "right",
            gdk.KEY_l: "right",
            gdk.KEY_L: "right",

            gdk.KEY_Up: "up",
            gdk.KEY_i: "up",
            gdk.KEY_I: "up",

            gdk.KEY_Down: "down",
            gdk.KEY_k: "down",
            gdk.KEY_K: "down",
        }

        direction = None
        for keyval in reversed(keys_down):
            if keyval in key_directions:
                direction = key_directions[keyval]
                break

        if not direction:
            return
        speed_direction = 1 if direction in ("right", "down") else -1

        # find the furthest step we can take for the next game polygon dot
        # when not drawing that's as far as we can go on current line
        # when drawing, that's the closest border within step
        for speed in reversed(range(self.cube.speed)):
            game_x = x if direction in ("up", "down") else x + (speed + 1) * speed_direction
            game_y = y if direction in ("left", "right") else y + (speed + 1) * speed_direction

            if current_line:
                if not game_poly_dot and game_utils.on_line((game_x, game_y), current_line):
                    # if we are on a line then we are looking for the max position at
                    # which we still have a hit
                    game_poly_dot = (game_x, game_y)
            else:
                # roaming around - checking if the next move is valid
                if game_utils.on_line((game_x, game_y), self.game_area):
                    game_poly_dot = (game_x, game_y)



        # look for the furthest valid non-game poly
        # we stop when we find non-poly point and then bump into an on-line point
        for speed in range(self.cube.speed):
            game_x = x if direction in ("up", "down") else x + (speed + 1) * speed_direction
            game_y = y if direction in ("left", "right") else y + (speed + 1) * speed_direction

            on_line = game_utils.on_line((game_x, game_y), self.game_area)

            if not self.in_game_bounds((game_x, game_y)):
                break

            if not on_line:
                non_game_poly_dot = (game_x, game_y)
            elif on_line and non_game_poly_dot:
                break


        space_down = any([key in keys_down for key in (gdk.KEY_space, gdk.KEY_Shift_L, gdk.KEY_Shift_R)])
        if space_down and non_game_poly_dot and not game.claiming:
            if game_utils.in_area(non_game_poly_dot, self.game_rects, on_line=True):
                game.claiming = True
                self.cube.set_drawing(True)
                self._current_direction = None


        if game.claiming and self._current_direction != direction:
            self._current_direction = direction
            if (self.cube.x, self.cube.y) not in self.current_polygon:
                self.current_polygon.append((self.cube.x, self.cube.y))


        # when we are drawing, we can move outside the claimed poly's
        # when we are moving around, we can move only within the poly
        # check if the move is valid
        # we will go through all lines and check that our path is not
        # intersecting
        if game.claiming and game_poly_dot:
            self.close_claim(self.current_polygon + [game_poly_dot],
                             self.cube.current_speed,
                             game)
            game.claiming = False
            self.cube.set_drawing(False)
            self.current_polygon = []
            self.current_polygon_path.points = []
            self.cube.x, self.cube.y = game_poly_dot
            self.cube.current_line = game_utils.on_line(game_poly_dot, self.game_area)
            return


        on_current_poly = non_game_poly_dot and game_utils.on_line(non_game_poly_dot, self.current_polygon) is not None
        if game.claiming and not on_current_poly and non_game_poly_dot:
            if game_utils.in_area(non_game_poly_dot, self.game_rects, on_line=True):
                self.cube.x, self.cube.y = non_game_poly_dot
                self.current_polygon_path.points = self.current_polygon + [non_game_poly_dot]

        if not game.claiming and game_poly_dot:
            # legal move is one where the next dot is on the same line as the prev one
            line = game_utils.on_line([self.cube.x, self.cube.y], self.game_area)
            new_line, good_lines = None, []
            if line:
                prev1, prev2 = line
                lines = [(dot1, dot2) for dot1, dot2 in zip(self.game_area, self.game_area[1:])]
                lines.append((self.game_area[-1], self.game_area[0]))
                good_lines = [line for line in lines if prev1 in line or prev2 in line]
                new_line = game_utils.on_line(game_poly_dot, self.game_area)


            if new_line in good_lines:
                self.cube.x, self.cube.y = game_poly_dot
                self.cube.current_line = new_line
Beispiel #5
0
 def in_game_bounds(self, dot):
     return game_utils.in_area(dot, [self._start_game_area])