예제 #1
0
 def __init__(self, posicao, velocidade, aceleracao, coef_elastico=0.9):
     self.raio = 10.0
     self.circulo = eu.Circle(eu.Point2(posicao.x, posicao.y), self.raio)
     self.posicao = posicao
     self.velocidade = velocidade
     self.aceleracao = aceleracao
     self.coef_elastico = coef_elastico
예제 #2
0
    def atualizar(self):
        if pyxel.btn(pyxel.KEY_LEFT_BUTTON):
            bola = Bola(eu.Point2(pyxel.mouse_x, pyxel.mouse_y),
                        eu.Vector2(0, 0), self.gravidade, 0.2)
            self.bolas.append(bola)

        for i, b in enumerate(self.bolas):
            b.atualizar()
            for s in self.segmentos:
                b.checar_colisao(s)
            for b2 in self.bolas[i + 1:]:
                b.checar_colisao(b2)
예제 #3
0
    def atualizar(self):
        if pyxel.btnr(pyxel.MOUSE_LEFT_BUTTON):
            bola = Bola(eu.Point2(pyxel.mouse_x, pyxel.mouse_y),
                        eu.Vector2(0, 0), self.gravidade, 0.8)
            self.bolas.append(bola)

        for i, b in enumerate(self.bolas):
            b.atualizar()
            if b.permanecer:
                for s in self.segmentos:
                    b.checar_colisao(s)
                for b2 in self.bolas[i + 1:]:
                    b.checar_colisao(b2)

        self.bolas = list(filter(lambda b: b.permanecer, self.bolas))
예제 #4
0
 def checar_colisao(self, objeto):
     if isinstance(objeto, Segmento):
         if self.posicao.distance(objeto.linha) <= self.raio:
             normal = self.posicao.connect(objeto.linha)
             vetor_normal = (normal.p1 - normal.p2).normalize()
             nova_posicao = normal.p2 + (vetor_normal * self.raio)
             self.posicao = eu.Point2(nova_posicao.x, nova_posicao.y)
             self.velocidade = self.velocidade.reflect(
                 vetor_normal) * self.coef_elastico
     elif isinstance(objeto, Bola):
         if self.posicao.distance(
                 objeto.posicao) <= self.raio + objeto.raio:
             diferenca = self.raio + objeto.raio - self.posicao.distance(
                 objeto.posicao)
             vetor_colisao = self.posicao - objeto.posicao
             vetor_colisao.normalize()
             self.posicao = self.posicao + vetor_colisao * (diferenca / 2)
             objeto.posicao = objeto.posicao - vetor_colisao * (diferenca /
                                                                2)
             self.velocidade = self.velocidade.reflect(
                 vetor_colisao) * self.coef_elastico
             objeto.velocidade = objeto.velocidade.reflect(
                 vetor_colisao) * self.coef_elastico
예제 #5
0
 def __init__(self, x1, y1, x2, y2):
     self.linha = eu.LineSegment2(eu.Point2(x1, y1), eu.Point2(x2, y2))
예제 #6
0
파일: ai.py 프로젝트: mkoponen/dcs-dync
def decide_move(group, game_map):

    if group.category != "vehicle":
        return None

    if "__sg__" in group.name:
        return None

    node_id = game_map.find_group_node(group)

    if node_id is None:
        logger.error("The group %s is not on the game map." % str(group))
        return None

    if game_map.red_goal_node is None or game_map.blue_goal_node is None:
        logger.error(
            "Must set goal nodes for both sides until can call decide_move.")
        return None

    if group.coalition == "red":
        correct_goal = game_map.red_goal_node
    else:
        correct_goal = game_map.blue_goal_node

    origin_coords = game_map.get_node_coords(node_id)
    origin_coords = euclid3.Point2(origin_coords[0], origin_coords[1])
    goal_coords = game_map.get_node_coords(correct_goal)
    goal_coords = euclid3.Point2(goal_coords[0], goal_coords[1])

    neighbor_paths = []
    path_pairs = []

    for neighbor in game_map.graph[node_id]:
        if neighbor == correct_goal:
            return int(correct_goal)
        shortest_path_to_goal = game_map.get_shortest_path(
            neighbor, correct_goal)

        # Ignore paths that return to the node we are in
        if shortest_path_to_goal is not None and node_id not in shortest_path_to_goal:
            neighbor_paths.append(shortest_path_to_goal)

    if len(neighbor_paths) == 0:
        logger.warning("No path to goal found for group %s" % group.name)
        return None

    if len(neighbor_paths) == 1:
        return int(neighbor_paths[0][0])

    # We try to identify the REALLY stupid choices before we randomize our actual choice
    forbidden_nodes = []

    length = len(neighbor_paths)

    # A bit complicated algorithm. Creates a list of all possible pairs of different paths and truncates them to the
    # nearest common node. The i and j -parts of the for loops are the traditional way to compare pairs with least
    # amount of work. (Don't compare item with itself, and don't compare a to b, and then b to a.
    for i in range(length - 1):
        for j in range(i + 1, length):

            # The previous two loops compared paths. The next two loops compare nodes in paths.
            found_intersection = False
            for k in range(0, len(neighbor_paths[i])):
                for l in range(0, len(neighbor_paths[j])):
                    if neighbor_paths[i][k] == neighbor_paths[j][l]:
                        path_pairs.append((neighbor_paths[i][:k + 1],
                                           neighbor_paths[j][:l + 1]))
                        found_intersection = True
                        break
                if found_intersection:
                    break

    # Compares all the pairs, and forbids all nodes where there is such a pair that the divergent part is one third
    # longer for the to-be-forbidden path, than the shorter path. This prevents any dumb detours from happening.
    for pair in path_pairs:

        # This allows us to trivially calculate the path length
        tmpgraph1 = game_map.graph.subgraph(pair[0])
        tmpgraph2 = game_map.graph.subgraph(pair[1])
        size1 = tmpgraph1.size(weight='weight')
        size2 = tmpgraph2.size(weight='weight')

        if size1 >= 1.33 * size2:
            # Found a dumb detour. Forbid.
            if pair[0][0] not in forbidden_nodes:
                forbidden_nodes.append(pair[0][0])
        elif size2 >= 1.33 * size1:
            # ditto
            if pair[1][0] not in forbidden_nodes:
                forbidden_nodes.append(pair[1][0])

    node_is_backtrack = {}
    choices = []
    allow_backtrack = True

    for path in neighbor_paths:
        if path[0] not in forbidden_nodes:
            is_backtrack = False
            dest_coords = game_map.get_node_coords(path[0])
            dest_coords = euclid3.Point2(dest_coords[0], dest_coords[1])

            if dest_coords.distance(goal_coords) > origin_coords.distance(
                    goal_coords):
                # Making this move would mean backtracking
                is_backtrack = True
            else:
                # We found at least one node which doesn't constitute backtracking. Hence we disallow all moves that do
                allow_backtrack = False
            node_is_backtrack[path[0]] = is_backtrack
            choices.append(path[0])

    if allow_backtrack is False:
        choices = [
            node for node in choices if node_is_backtrack[node] is False
        ]

    decision = np.random.choice(choices)
    extra_info = ""
    if node_is_backtrack[decision] is True:
        extra_info = " (which is backtracking)"

    logger.debug("Final decision for %s: move to node %d.%s" %
                 (group.name, decision, extra_info))

    if decision is None:
        return None
    else:
        return int(decision)