Ejemplo n.º 1
0
def main():
    print("sdsdsds")
    GLogger('file', 'graph_validator_logger.txt', 'ERROR')
    Window.size = (1920, 1090)

    Utils.read_game_config_file(MAIN_CONFIG_FILE_PATH)
    Utils.read_graph_config_file(GRAPH_CONFIG_FILE)
    Utils.image_folder = path.join("..", Utils.image_folder)

    max_turns = int(Utils.game_config_data['Default']['max_turns'])
    it = itertools.product('1234', repeat=max_turns)
    number_of_successful_runs = 0
    # use line 30 to test all the graphs in SAVED_GRAPH_PATH; use line 31 to only test the graphs specified in 'graphs_names'
    # for current_graph in [item for item in listdir(SAVED_GRAPH_PATH) if item.endswith(".xml")]:
    for current_graph in graphs_names:
        curr_path = path.join(SAVED_GRAPH_PATH, current_graph)
        graph = load_graph_from_json(curr_path)
        with open("{}_saved_steps.txt".format(curr_path[:-5]), 'w') as f:
            num_of_graph_nodes = len(graph.node_list)
            f.write("The graph contains {} nodes\n".format(
                str(num_of_graph_nodes)))
            while True:
                try:
                    buttons = it.next()
                except StopIteration:
                    break
                answer, number_of_nodes_seen = run_buttons_on_graph(
                    graph, buttons)
                number_of_successful_runs += answer
                f.write("steps: {}, seen nodes: {} \n".format(
                    str(buttons), str(number_of_nodes_seen)))

            f.write("number of successful runs = {0}\n".format(
                number_of_successful_runs))
Ejemplo n.º 2
0
    def run_q_player(self, graph_file_path, log_file_path):
        Utils.read_game_config_file(CONFIG_FILE_PATH)
        Utils.read_graph_config_file(GRAPH_CONFIG_PATH)
        Utils.image_folder = path.join("..", Utils.image_folder)

        log.setLevel(Utils.game_config_data['Default']['log_level'])
        session_length = 1000

        graph = load_py_graph(graph_file_path)
        q_matrix = QMatrix(action_space=4, max_steps=int(Utils.game_config_data['Default']['max_turns']), nodes_in_graph=len(graph.node_list))

        with open(log_file_path,'w') as f:
            f.write("episode, score\n")
            for i in range(session_length):
                dummy_screen = DummyScreen(graph)
                game = GraphTabletDisplay(dummy_screen)
                data_handler = GameDataHandler(GRAPH_CONFIG_PATH, graph.size)
                data_handler.add_view_to_db(game.get_info_from_screen())

                rw = 0
                game.press_button(self.auto_first_press + 1)
                data_handler.add_view_to_db(game.get_info_from_screen())
                q_matrix.reinit(known_nodes=len(data_handler.get_real_nodes()))
                for j in range(1, int(Utils.game_config_data['Default']['max_turns'])):
                    log.debug("doing a step {}/{}".format(j, Utils.game_config_data['Default']['max_turns']))
                    btn = q_matrix.choose_action_epsilon_greedy()
                    game.press_button(btn + 1)
                    data_handler.add_view_to_db(game.get_info_from_screen())
                    rw = q_matrix.update_matrix(num_nodes=len(data_handler.get_real_nodes()), current_step=btn)
                log.info("Q session {}:{} - reword:{}".format(i, session_length, rw))
                f.write("{},{}\n".format(i + 1, rw))
Ejemplo n.º 3
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))
Ejemplo n.º 4
0
    def test_trim_data(self, mock_utils):
        mock_utils.graph_config_data = None
        mock_utils.game_config_data = {'Default': {'log_level': 'ERROR'}}
        Utils.read_game_config_file(path.join("..", CONFIG_FILE_PATH))
        Utils.read_graph_config_file(path.join("..", GRAPH_CONFIG_PATH))
        data_handler = GameDataHandler(path.join("../", "graph_config.txt"),
                                       None)
        data_handler.graph.add_node(self.node_1_real.x,
                                    self.node_1_real.y,
                                    serial=self.node_1_real.serial_num)
        data_handler.graph.add_node(self.node_2_unreal.x,
                                    self.node_2_unreal.y,
                                    serial=self.node_2_unreal.serial_num)
        data_handler.graph.add_node(self.node_2_unreal_moved.x,
                                    self.node_2_unreal_moved.y,
                                    serial=self.node_2_unreal_moved.serial_num)
        data_handler.graph.add_node(self.node_3_unreal.x,
                                    self.node_3_unreal.y,
                                    serial=self.node_3_unreal.serial_num)
        data_handler.graph.add_node(self.node_3_unreal_moved.x,
                                    self.node_3_unreal_moved.y,
                                    serial=self.node_3_unreal_moved.serial_num)
        data_handler.graph.add_node(self.node_4_real.x,
                                    self.node_4_real.y,
                                    serial=self.node_4_real.serial_num)
        edge_1 = (self.node_1_real, self.node_2_unreal_moved, 1,
                  LineEquation(slope=1,
                               const=0,
                               edge1=self.node_1_real,
                               edge2=self.node_2_unreal_moved))
        edge_2 = (self.node_2_unreal, self.node_3_unreal_moved, 1,
                  LineEquation(slope=1,
                               const=0,
                               edge1=self.node_2_unreal,
                               edge2=self.node_3_unreal_moved))
        edge_3 = (self.node_3_unreal, self.node_4_real, 1,
                  LineEquation(slope=1,
                               const=0,
                               edge1=self.node_3_unreal,
                               edge2=self.node_4_real))
        edge_4 = (self.node_1_real, self.node_4_real, 1,
                  LineEquation(slope=1,
                               const=0,
                               edge1=self.node_1_real,
                               edge2=self.node_4_real))
        data_handler.extra_edges = [edge_1, edge_2, edge_3]

        data_handler.trim_data()
        self.assertEquals(len(data_handler.edges_to_add), 1)
        self.assertEquals(data_handler.edges_to_add[0][0].serial_num,
                          edge_4[0].serial_num)
        self.assertEquals(data_handler.edges_to_add[0][1].serial_num,
                          edge_4[1].serial_num)
Ejemplo n.º 5
0
def create_rand_graph(config_file):
    """

    :param config_file:
    :return:
    """
    new_graph = GraphObject(config_file)
    config = Utils.read_game_config_file(config_file)

    for i in range(config.getint("GeneralParams", "NodeCount")):
        while True:
            xRandom = random.randint(
                config.getint("NodeData", "NodeSize"),
                config.getint("GeneralParams", "GraphSizeX") -
                config.getint("NodeData", "NodeSize"))
            yRandom = random.randint(
                config.getint("NodeData", "NodeSize"),
                config.getint("GeneralParams", "GraphSizeY") -
                config.getint("NodeData", "NodeSize"))
            if not check_collisions(xRandom, yRandom, new_graph,
                                    config.getint("NodeData", "NodeSize"),
                                    config.getint("NodeData",
                                                  "ExtraDistance")):
                break
        randColor = random.choice(Colours.values())
        new_graph.add_node(xRandom, yRandom, randColor, Shapes['circle'],
                           config.getint("NodeData", "NodeSize"))
    connect_graph(new_graph, config.getint("NodeData", "MaxNeighbors"),
                  config.getint("NodeData", "MinNeighbors"))
    return new_graph
Ejemplo n.º 6
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
Ejemplo n.º 7
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
Ejemplo n.º 8
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")
Ejemplo n.º 9
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)))
Ejemplo n.º 10
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)
Ejemplo n.º 11
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
Ejemplo n.º 12
0

class GameType(Enum):
    VIEW_ONLY = 1
    ALLOW_PLAY = 2


def main(game_type, graph_data):
    GLogger('file', 'graph_runner_logger.txt', 'ERROR')
    if game_type == GameType.VIEW_ONLY:
        game = DisplayApp(graph_data)
    elif game_type == GameType.ALLOW_PLAY:
        button_presses = []
        # This needs to be more versatile
        test_screen = TestScreen(graph_data, button_presses, 0.2)
        test_screen.graph_config = "../GraphsData/graph_config.txt"
        game = GraphGameApp(test_screen)
    game.run()


if __name__ == "__main__":
    Utils.read_game_config_file(CONFIG_FILE_PATH)
    Utils.read_graph_config_file(GRAPH_CONFIG_PATH)
    Utils.image_folder = path.join("..", Utils.image_folder)

    # ALLOW_PLAY, VIEW_ONLY
    game_type = GameType.ALLOW_PLAY

    graph = load_graph_from_json(graph_file_path)
    main(game_type, graph)
Ejemplo n.º 13
0
    def build(self):
        self.init_communication()

        self.config = Utils.read_game_config_file(CONFIG_FILE_PATH)
        Utils.read_graph_config_file(GRAPH_CONFIG_PATH)
        self.logger = GLogger(
            self.config['Default']['logger_output_type'],
            self.config['Default']['logger_writing_location'],
            self.config['Default']['log_level'], self.user_data_dir)
        #self.init_communication(self.config['Cloud']['server_ip'])
        graph_config_path = self.config['Default']['graph_config_path']
        self.sm = ScreenManager()

        screen = ZeroScreen()
        screen.start()
        screen.ids['subject_id'].bind(
            text=screen.ids['subject_id'].on_text_change)
        self.sm.add_widget(screen)

        screen = FinalScreen()
        self.sm.add_widget(screen)

        # # Setting up the login screen separately
        # login_screen = LoginScreen(name='LoginScreen')
        # login_screen.setup(main_app=self)
        # login_screen.add_widget(login_screen.display.layout)
        # self.sm.add_widget(login_screen)

        graph_list = self.load_graphs_from_folder()

        self.current_graph = None
        self.discovered_graph = None
        self.user_answers = []
        self.question_list = []
        self.button_presses = []
        # Enumerate over all the graphs in the folder
        for i_net, graph_data in enumerate(graph_list):
            # Step 1 - Graph Game
            self.question_list = graph_data.question_object_list
            self.game_screen.append(
                GraphGameScreen(name='game_graph_' + str(i_net)))
            self.game_screen[-1].setup(
                number=i_net,
                main_app=self,
                max_turns=int(self.config['Default']['max_turns']),
                real_user=True,
                graph=graph_data,
                graph_config=graph_config_path,
                button_presses=self.button_presses)
            self.game_screen[-1].add_widget(
                self.game_screen[-1].graph_game.layout)
            # Step 2 - Questionnaire
            #Goren - run nine graphs with question and then one without
            if i_net < number_of_graphs:
                self.game_screen.append(
                    QuestionnaireScreen(name='game_questionnaire_' +
                                        str(i_net)))
                self.game_screen[-1].setup(number=i_net,
                                           main_app=self,
                                           real_user=self.real_user)
                self.game_screen[-1].add_widget(
                    self.game_screen[-1].questionnaire.the_widget)

                # Step 3 - Results
                self.game_screen.append(
                    ResultScreen(name='game_results_' + str(i_net)))
                self.game_screen[-1].setup(number=i_net,
                                           main_app=self,
                                           real_user=True)
                self.game_screen[-1].add_widget(
                    self.game_screen[-1].result_app.the_widget)

        for gs in self.game_screen:
            self.sm.add_widget(gs)

        self.sm.current = 'zero_screen'
        return self.sm