예제 #1
0
    def add_view_to_db(self, view):
        """
        Go over the new view gotten from the game. For each new node add it to self.graph.node_list
        For each edge check both ends. if the node has real=False we know it's only a placeholder.
        Update the graph of BasicGamer
        :param view: A dictionary containing the data gotten from the screen
        :return: None
        """
        # Innumerate over the nodes
        for node in view['nodes']:
            if self.graph.get_node_by_serial(node.serial_num) is None:
                self.graph.add_node(node.x, node.y, node_colour=node.colour, node_size=node.size,
                                    serial=node.serial_num)
                num = self.graph.get_node_by_serial(node.serial_num).dummy_num
                #self.log.info("Adding node:  num="+ str(num)+ ", real=True", location="{}:{}".format(node.x, node.y),serial=node.serial_num)
        # Innumerate over the edges
        for edge in view['edges']:
            if self.graph.get_node_by_serial(edge[0].serial_num) is not None:
                node_0 = self.graph.get_node_by_serial(edge[0].serial_num)
            else:
                node_0 = self.graph.add_node(edge[0].x, edge[0].y, node_size=1, real=False,
                                             serial=edge[0].serial_num)
                num = self.graph.get_node_by_serial(node_0.serial_num).dummy_num
                GLogger.log(logging.DEBUG,Utils.format_log_msg("Adding node",num=num, real=False,
                              location="{}:{}".format(node_0.x, node_0.y), serial=node_0.serial_num))

            if self.graph.get_node_by_serial(edge[1].serial_num) is not None:
                node_1 = self.graph.get_node_by_serial(edge[1].serial_num)
            else:
                node_1 = self.graph.add_node(edge[1].x, edge[1].y, node_size=1, real=False,
                                             serial=edge[1].serial_num)
                num = self.graph.get_node_by_serial(node_1.serial_num).dummy_num
                GLogger.log(logging.DEBUG, Utils.format_log_msg("Adding node",num=num, real=False,
                              location="{}:{}".format(node_1.x, node_1.y), serial=node_1.serial_num))

            if node_1.serial_num not in node_0.possible_neighbors:
                node_0.possible_neighbors.add(node_1.serial_num)
            if node_0.serial_num not in node_1.possible_neighbors:
                node_1.possible_neighbors.add(node_0.serial_num)
            self.graph.connect_nodes(node_0, node_1, allow_overflow=True)

            if edge not in self.extra_edges:
                self.extra_edges.append(edge)

        self.edges_to_add = []
        GLogger.log(logging.DEBUG, "Triming data from graph")
        self.trim_data()
        GLogger.log(logging.DEBUG, "Adding extra edges to edge list")
        for item in self.edges_to_add:
            self.extra_edges.append(item)
        self.clear_empty_nodes()
        GLogger.log(logging.DEBUG, Utils.format_log_msg("Finished triming data:", num_of_node=len(self.graph.node_list),
                      num_real_node=(len([item for item in self.graph.node_list if item.is_real()])),
                      num_of_edges=len(self.extra_edges)))
        GLogger.log(logging.DEBUG, Utils.format_log_msg("edge list:", edges=self.extra_edges))
예제 #2
0
    def cleaned_graph(self):
        """
        Called at the end of a run. Cleans the graph of none real connections
        This is really just a patch because we enter bad connections. We should probably fix the source of the issue
        :return: the cleaned graph
        """
        self.graph.connections = []
        for edge in self.extra_edges:
            if edge[0].is_real() and edge[1].is_real():
                self.graph.connections.append((min(edge[0].serial_num, edge[1].serial_num),
                                               max(edge[0].serial_num, edge[1].serial_num)))
            else:
                self.clean_connection(edge[0], edge[1])
                self.clean_connection(edge[1], edge[0])
        self.extra_edges = []
        real_nodes = []
        for node in self.graph.node_list:
            if node.is_real():
                nodes_to_remove = []
                for neightbor in node.neighbors:
                    if not self.graph.get_node_by_serial(neightbor).is_real():
                        nodes_to_remove.append(self.graph.get_node_by_serial(neightbor))
                for item in nodes_to_remove:
                    self.clean_connection(node, item)
                real_nodes.append(node)

        # Make sure we see only the same edge once
        self.graph.connections = list(set(self.graph.connections))
        GLogger.log(logging.DEBUG, Utils.format_log_msg("Finished cleaning graph before continuing:", num_of_nodes=len(self.graph.node_list),
                                      num_real_nodes=(len([item for item in self.graph.node_list if item.is_real()])),
                                      num_of_connections=len(self.graph.connections)))
        self.graph.node_list = real_nodes
        return self.graph
예제 #3
0
    def two_edges_are_one(self, edge_1, edge_2):
        """
        Checks if the two edges are actually a single edge.
        :return: True if edges are 100% the same one
        """

        eq1 = LineEquation(slope=edge_1[3].slope,
                           const=edge_1[3].const,
                           edge1=edge_1[0],
                           edge2=edge_1[1])
        eq2 = LineEquation(slope=edge_2[3].slope,
                           const=edge_2[3].const,
                           edge1=edge_2[0],
                           edge2=edge_2[1])


        # Check collision point
        collision_point = LineEquation.get_equation_collision_point(eq1, eq2)
        GLogger.log(logging.DEBUG, Utils.format_log_msg("Found collision point of both edges", point=collision_point, eq1=eq1, eq2=eq2))
        if collision_point == LINES_ALWAYS_MEET:
            # Lines have the same slope + const. Big change they are the same one.
            if LineEquation.check_collision_point(eq1, eq2):
                GLogger.log(logging.DEBUG, "Lines meet and intersect with each other - They are the same line")
                return True
            else:
                GLogger.log(logging.DEBUG, "Lines have the same parameters but we are not sure if they meet")
                return False
        return False
예제 #4
0
 def connect_nodes(self, node1, node2, allow_overflow=False):
     """
     Connects both nodes, remove each from the list of  possible neighbors of the other and adds to the list of
     neighbors.
     :param allow_overflow: If node can have more than max connections
     :return: True if nodes were connected,
     Raise exception if problem accrued
     """
     GLogger.log(
         logging.DEBUG,
         Utils.format_log_msg("Creating edge",
                              edge="{}:{} - {}:{}".format(
                                  node1.x, node1.y, node2.x, node2.y)))
     if (len(node1.neighbors) >= self.max_neighbors or
                 len(node2.neighbors) >= self.max_neighbors) \
             and not allow_overflow:
         raise Exception("One of the nodes has too many neighbors")
     if node1.serial_num in node2.possible_neighbors and node2.serial_num in node1.possible_neighbors:
         # Connect nodes
         node1.neighbors.add(node2.serial_num)
         node2.neighbors.add(node1.serial_num)
         # Removes from future possible connections
         node1.possible_neighbors.remove(node2.serial_num)
         node2.possible_neighbors.remove(node1.serial_num)
         self.connections.append((min(node1.serial_num, node2.serial_num),
                                  max(node1.serial_num, node2.serial_num)))
         return True
     else:
         raise Exception("Connection between the two nodes is not possible")
예제 #5
0
 def clear_empty_nodes(self):
     """
     Go over node list and see if two nodes are the same.
     :return: 
     """
     remove_list = []
     GLogger.log(logging.DEBUG, "removing nodes with no neighbors")
     for node in self.graph.node_list:
         if len(node.neighbors) == 0:
             GLogger.log(logging.DEBUG, Utils.format_log_msg("Found node with no neighbors - deleting:", serial=node.serial_num, real=node.is_real()))
             remove_list.append(node.serial_num)
     for serial in remove_list:
         self.graph.node_list.remove(self.graph.get_node_by_serial(serial))
     GLogger.log(logging.DEBUG, "removed {} nodes".format(len(remove_list)))
예제 #6
0
 def clean_connection(self, main_node, node_to_remove):
     """
     Removed all connection from main_node regarding node_to_remove
     :param node_to_remove: The node to remove - node object
     :param main_node: The node we want to remove data from - node object
     :return: 
     """
     GLogger.log(logging.DEBUG, Utils.format_log_msg("Cleaning connection to another node", main_node=main_node.dummy_num,
                    node_to_remove=node_to_remove.dummy_num))
     node = self.graph.get_node_by_serial(main_node.serial_num)
     if node is None:
         raise Exception("Node '{}' was not found in node list. Node list = {}"
                         .format(main_node.dummy_num,
                                 [found_nodes.dummy_num for found_nodes in self.graph.node_list]))
     if node_to_remove.serial_num in node.neighbors:
         node.neighbors.remove(node_to_remove.serial_num)
     if node_to_remove.serial_num in node.possible_neighbors:
         node.possible_neighbors.remove(node_to_remove.serial_num)
예제 #7
0
    def trim_data(self):
        """
        Goes over all of the data that is saved and trims nodes and edges.
        Connects fake nodes to real ones if we found the actual node
        connects open edges together if possible
        """
        slope_set = set()
        for edge in self.extra_edges:
            slope_set.add(edge[3].slope)

        sorted(slope_set)
        GLogger.log(logging.DEBUG,"Number of slops found = {}".format(len(slope_set)))
        for slope in list(slope_set):
            edges_to_check = []
            for edge in self.extra_edges:
                if edge[3].slope == slope:
                    edges_to_check.append(edge)
            GLogger.log(logging.DEBUG,Utils.format_log_msg("Number of edges in slope: ",slope="{} = {}".format(slope, len(edges_to_check)), edges=edges_to_check))
            if len(edges_to_check) > 1:
                # we have two edges with the same slope!
                # Removing all edges from list. We add only the relevant ones later on
                for item in edges_to_check:
                    self.extra_edges.remove(item)
                while True:
                    first_edge = edges_to_check.pop()
                    edge_reconstructed = False
                    for second_edge in edges_to_check:
                        if self.two_edges_are_one(first_edge, second_edge):
                            GLogger.log(logging.DEBUG, "two edges are one")
                            edge_reconstructed = True
                            edges_to_check.remove(second_edge)
                            edges_to_check.append(self.connect_edges(first_edge, second_edge))
                            break
                    if not edge_reconstructed:
                        # edge does not match any other on the list. We can leave it alone
                        self.edges_to_add.append(first_edge)
                    if len(edges_to_check) <= 1:
                        self.edges_to_add.append(edges_to_check[0])
                        break