Beispiel #1
0
    def user_control(self):
        while True:
            self.action = input("Enter a command or a number to train: ")
            # Test classification percentage using both the test set and training set
            if self.action[0] == "t":
                self.test_percentage_training_and_test_set()
            # Play forever
            elif self.action[0] == "s":
                self.results_length = float('inf')
                return
            # Play 50 games, using the neural net p or a random player r
            elif self.action[0] == "p" or self.action[0] == "r":
                self.results_length = 50
                return
            # Run the grading function
            elif self.action[0] == "c":
                if len(self.results_from_nn_playing) < 50:
                    self.results_length = 50
                    return
                else:
                    self.print_comparison()
            elif self.action[0] == "l":
                self.collect_cases = not self.collect_cases
                if self.collect_cases:
                    self.neural_network_cases = load_cases()
                    self.expectimax = Expectimax()
            else:
                self.errors = self.move_classifier.do_training(
                    epochs=int(self.action), errors=self.errors)
                self.test_percentage_training_and_test_set()

            print("Total time elapsed: " +
                  str(round((time() - self.start_time) / 60, 1)) + " min")
 def __init__(self):
     Frame.__init__(self)
     self.grid()
     self.master.title('Ganesh-2048')
     self.grid_cells = []
     self.initialise_grid()
     self.initilaise_matrix()
     self.update_grid_cells()
     self.AI = Expectimax()
     self.start_game()
     self.mainloop()
Beispiel #3
0
 def start_game(self):
     print "avg", sum(self.results)/float(len(self.results) + 0.001)
     if len(self.results) < 30:
         self.game_board = Game2048(board=[[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]])
         self.board = self.game_board.board
         self.game_board.generate_new_node()
         self.depth = 4
         self.move_count = 0
         self.expectimax = Expectimax()
         self.draw_board()
         self.time = time()
         self.run_algorithm()
     else:
         print self.results
         print "avg", sum(self.results)/float(len(self.results))
def get_strategy(strategy_type):
    if strategy_type == "minimax":
        return Minimax()
    elif strategy_type == "expectimax":
        return Expectimax()
    elif strategy_type == "simple":
        return Simple()
    else:
        return Random()
Beispiel #5
0
 def __init__(self,
              collect_cases=False,
              use_merge_input_nodes=False,
              depth=3):
     self.collect_cases = collect_cases
     self.use_merge_input_nodes = use_merge_input_nodes
     self.depth = depth
     if collect_cases:
         self.neural_network_cases = load_cases()
         self.expectimax = Expectimax()
     self.results_from_nn_playing = []
     self.results_from_random_playing = []
     self.results = []
     self.results_from_random_playing = [112] * 50
     self.start_time = time()
     self.print_commands()
     self.setup_network()
     self.user_control()
     self.start_game()
class Game(Frame):
    def __init__(self):
        Frame.__init__(self)
        self.grid()
        self.master.title('Ganesh-2048')
        self.grid_cells = []
        self.initialise_grid()
        self.initilaise_matrix()
        self.update_grid_cells()
        self.AI = Expectimax()
        self.start_game()
        self.mainloop()

    def start_game(self):

        while True:
            self.board.move(self.AI.retrievemove(self.board))
            self.update_grid_cells()
            self.add_random_number()
            self.update_grid_cells()
            if len(self.board.get_available_moves()) == 0:
                self.game_over_display()
                break
            self.update()

    def game_over_display(self):

        for i in range(4):

            for j in range(4):
                self.grid_cells[i][j].configure(text="",
                                                bg=BACKGROUND_COLOR_CELL_EMPTY)
        self.grid_cells[0][0].configure(text="best",
                                        bg=BACKGROUND_COLOR_CELL_EMPTY)
        top_4 = list(
            map(int, reversed(sorted(list(self.board.grid.flatten())))))
        self.grid_cells[0][1].configure(text=str(top_4[0]),
                                        bg=BACKGROUND_COLOR_DICT[2048],
                                        fg=CELL_COLOR_DICT[2048])

        self.update()

    def initialise_grid(self):
        background = Frame(self,
                           bg=BACKGROUND_COLOR_GAME,
                           width=SIZE,
                           height=SIZE)
        background.grid()
        for i in range(GRID_LEN):
            grid_row = []
            for j in range(GRID_LEN):
                cell = Frame(background,
                             bg=BACKGROUND_COLOR_CELL_EMPTY,
                             width=SIZE / GRID_LEN,
                             height=SIZE / GRID_LEN)
                cell.grid(row=i,
                          column=j,
                          padx=GRID_PADDING,
                          pady=GRID_PADDING)
                # font = Font(size=FONT_SIZE, family=FONT_FAMILY, weight=FONT_WEIGHT)
                t = Label(master=cell,
                          text="",
                          bg=BACKGROUND_COLOR_CELL_EMPTY,
                          justify=CENTER,
                          font=FONT,
                          width=4,
                          height=2)
                t.grid()
                grid_row.append(t)

            self.grid_cells.append(grid_row)

    def gen(self):
        return randint(0, GRID_LEN - 1)

    def initilaise_matrix(self):
        self.board = BoardDesign()
        self.add_random_number()
        self.add_random_number()

    def update_grid_cells(self):
        for i in range(GRID_LEN):
            for j in range(GRID_LEN):

                new_number = int(self.board.grid[i][j])
                if new_number == 0:
                    self.grid_cells[i][j].configure(
                        text="", bg=BACKGROUND_COLOR_CELL_EMPTY)

                else:
                    n = new_number
                    if new_number > 2048:
                        c = 2048
                    else:
                        c = new_number
                    self.grid_cells[i][j].configure(
                        text=str(n),
                        bg=BACKGROUND_COLOR_DICT[c],
                        fg=CELL_COLOR_DICT[c])

        self.update_idletasks()

    def add_random_number(self):

        if randint(0, 99) < 90:  #90% of times we will get 2
            value = 2
        else:  #10 % of times we will get 4
            value = 4
        cells = self.board.get_available_cells()
        pos = cells[randint(0, len(cells) - 1)] if cells else None
        if pos is None:
            return None
        else:
            self.board.insert_number(pos, value)
            return pos
Beispiel #7
0
class GameController():

    NR_OF_TRAINING_CASES = 7000
    NR_OF_TEST_CASES = 833
    NR_OF_OUTPUT_NODES = 4

    def __init__(self,
                 collect_cases=False,
                 use_merge_input_nodes=False,
                 depth=3):
        self.collect_cases = collect_cases
        self.use_merge_input_nodes = use_merge_input_nodes
        self.depth = depth
        if collect_cases:
            self.neural_network_cases = load_cases()
            self.expectimax = Expectimax()
        self.results_from_nn_playing = []
        self.results_from_random_playing = []
        self.results = []
        self.results_from_random_playing = [112] * 50
        self.start_time = time()
        self.print_commands()
        self.setup_network()
        self.user_control()
        self.start_game()

    def start_game(self):
        if len(self.results) < self.results_length:
            print("run nr", len(self.results))
            self.game_board = Game2048(
                board=[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]])
            self.board = self.game_board.board
            self.game_board.generate_new_node()
            self.move_count = 0
            #self.draw_board()
            self.time = time()
            self.run_algorithm()
        else:
            print(self.results)
            print("Largest tile", max(self.results))
            print("Average tile", sum(self.results) / float(len(self.results)))
            if self.action[0] == "p":
                self.results_from_nn_playing = copy.copy(self.results)
            elif self.action[0] == "r":
                self.results_from_random_playing = copy.copy(self.results)
            elif self.action[0] == "c":
                self.results_from_nn_playing = copy.copy(self.results)
                self.print_comparison()
            self.results = []
            self.user_control()
            self.start_game()

    def setup_network(self):
        if self.use_merge_input_nodes:
            number_of_input_nodes = 24
        else:
            number_of_input_nodes = 16
        use_default = input("Use default [y/n]: ")
        if use_default[0] == "y":
            nodes_in_each_layer = [700]
            activation_functions = [3, 4]
            learning_rate = 0.02
            bulk_size = 1
        else:
            nodes_in_each_layer = list(
                map(
                    int,
                    input("Hidden nodes in each layer: ").replace(
                        " ", "").split(",")))
            print("TanH: 1, Sigmoid: 2, Rectify: 3, Softmax: 4")
            activation_functions = list(
                map(
                    int,
                    input("Select activation functions: ").replace(
                        " ", "").split(",")))
            learning_rate = float(input("learning rate: "))
            bulk_size = int(input("Bulk size: "))

        self.move_classifier = MoveClassifier(
            nr_of_training_cases=GameController.NR_OF_TRAINING_CASES,
            nr_of_test_cases=GameController.NR_OF_TEST_CASES,
            nr_of_nodes_in_layers=nodes_in_each_layer,
            act_functions=activation_functions,
            lr=learning_rate,
            number_of_input_nodes=number_of_input_nodes,
            number_of_output_nodes=GameController.NR_OF_OUTPUT_NODES,
            bulk_size=bulk_size)

        self.move_classifier.preprocessing(boards=self.move_classifier.boards,
                                           labels=self.move_classifier.labels)
        self.move_classifier.preprocessing(
            boards=self.move_classifier.test_boards,
            labels=self.move_classifier.test_labels)
        #self.move_classifier.test_preprocessing(boards=self.move_classifier.boards, labels=self.move_classifier.labels)

        if self.use_merge_input_nodes:
            self.move_classifier.boards = self.move_classifier.preprocessing_row_column(
                boards=self.move_classifier.boards)
            self.move_classifier.test_boards = self.move_classifier.preprocessing_row_column(
                boards=self.move_classifier.test_boards)
            #self.move_classifier.add_extra_nodes(self.move_classifier.boards, extra_nodes)
            #self.move_classifier.add_extra_nodes(self.move_classifier.test_boards, extra_test_nodes)

        self.errors = []

    def user_control(self):
        while True:
            self.action = input("Enter a command or a number to train: ")
            # Test classification percentage using both the test set and training set
            if self.action[0] == "t":
                self.test_percentage_training_and_test_set()
            # Play forever
            elif self.action[0] == "s":
                self.results_length = float('inf')
                return
            # Play 50 games, using the neural net p or a random player r
            elif self.action[0] == "p" or self.action[0] == "r":
                self.results_length = 50
                return
            # Run the grading function
            elif self.action[0] == "c":
                if len(self.results_from_nn_playing) < 50:
                    self.results_length = 50
                    return
                else:
                    self.print_comparison()
            elif self.action[0] == "l":
                self.collect_cases = not self.collect_cases
                if self.collect_cases:
                    self.neural_network_cases = load_cases()
                    self.expectimax = Expectimax()
            else:
                self.errors = self.move_classifier.do_training(
                    epochs=int(self.action), errors=self.errors)
                self.test_percentage_training_and_test_set()

            print("Total time elapsed: " +
                  str(round((time() - self.start_time) / 60, 1)) + " min")

    def run_algorithm(self):
        self.continuing = True
        if self.game_board.is_game_over():
            self.conclude_game()
            return self.start_game()
        current_node = State(self.game_board, self.depth)
        self.move_count += 1
        flat_board = current_node.board.board[3] + current_node.board.board[
            2] + current_node.board.board[1] + current_node.board.board[0]
        if self.collect_cases:
            self.gather_case_and_result_using_expectimax(
                current_node, flat_board)
        if self.action[0] == "r":
            chosen_move = self.choose_legal_random_move()
        else:
            flat_board = [flat_board]
            self.move_classifier.preprocessing(boards=flat_board, labels=None)
            if self.use_merge_input_nodes:
                flat_board = self.move_classifier.preprocessing_row_column(
                    boards=flat_board)
#               flat_board = self.move_classifier.add_extra_nodes([flat_board], extra_nodes)[0]

            output_activations = self.move_classifier.predictor(flat_board)
            chosen_move = self.choose_legal_move_from_nn(output_activations)

        self.do_move(chosen_move)
        self.game_board.generate_new_node()

    def do_move(self, chosen_move):
        if chosen_move == 0:
            self.game_board.move_left()
        elif chosen_move == 1:
            self.game_board.move_right()
        elif chosen_move == 2:
            self.game_board.move_up()
        elif chosen_move == 3:
            self.game_board.move_down()

    def conclude_game(self):
        self.continuing = False
        largest_tile = self.game_board.get_largest_tile()
        print("Largest tile", largest_tile)
        self.results.append(largest_tile)
        print("Average tile", sum(self.results) / float(len(self.results)))
        if self.collect_cases:
            print("size of training data", len(self.neural_network_cases))
            dump_cases(self.neural_network_cases)

    def choose_legal_random_move(self):
        while True:
            r = randint(0, 3)
            if self.game_board.is_move_legal(r):
                return r

    def choose_legal_move_from_nn(self, result):
        chosen_move = None

        while chosen_move == None or not self.game_board.is_move_legal(
                chosen_move):
            if chosen_move != None:
                result[0][chosen_move] = -1
            chosen_move = np.argmax(result[0])
        return chosen_move

    def gather_case_and_result_using_expectimax(self, current_node,
                                                flat_board):
        self.expectimax.run_expectimax(current_node, self.depth, -float("inf"),
                                       float("inf"), None)
        self.neural_network_cases[str(flat_board)] = self.expectimax.result

    def welch(self, list1, list2):
        params = {"results": str(list1) + " " + str(list2), "raw": "1"}
        resp = requests.post('http://folk.ntnu.no/valerijf/6/', data=params)
        return resp.text

    def test_percentage_training_and_test_set(self):
        output_activations = self.move_classifier.do_testing(
            boards=self.move_classifier.test_boards)
        print(
            "Statistics (test set): \t\t",
            self.move_classifier.check_result(
                output_activations, labels=self.move_classifier.test_labels),
            "%")
        output_activations = self.move_classifier.do_testing(
            boards=self.move_classifier.boards)
        print(
            "Statistics (training set):\t ",
            self.move_classifier.check_result(
                output_activations, labels=self.move_classifier.labels), "%")

    def print_comparison(self):
        print("NN results:\t", self.results_from_nn_playing)
        print("Random results:\t", self.results_from_random_playing)
        print("largest tiles", max(self.results_from_nn_playing),
              max(self.results_from_random_playing))
        print(
            "average tiles",
            sum(self.results_from_nn_playing) /
            float(len(self.results_from_nn_playing)),
            sum(self.results_from_random_playing) /
            float(len(self.results_from_random_playing)))
        points = self.welch(self.results_from_random_playing,
                            self.results_from_nn_playing)
        print("points", points)

    def print_commands(self):
        print("Commands")
        print(
            "t: Test the network classification using both the test set and the training set"
        )
        print("l toggle case collection. Currently: ", self.collect_cases)
        print("s: Run infinite times using NN")
        print("p: Run 50 games using NN")
        print("r: Run 50 games using a random player")
        print("c: Compare the two runs of 50")
Beispiel #8
0
class Gui(tk.Tk):
    def __init__(self, delay, diagonal=False, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        self.title("2048-solver")
        self.cell_width = self.cell_height = 100
        self.dim = (4, 4)
        self.delay=delay
        screen_width = self.dim[0]*self.cell_width+1
        screen_height = self.dim[1]*self.cell_height+1
        self.canvas = tk.Canvas(self, width=screen_width, height=screen_height, borderwidth=0, highlightthickness=0)
        self.canvas.pack(side="top", fill="both", expand="true")
        self.old_nr_of_cases = 0

        #self.bind_keys()

        self.color_dict = self.fill_color_dict()
        self.results = []
        self.start_game()
        #self.game_board = Game2048(board=[[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]])
        #self.board = self.game_board.board
        #self.game_board.generate_new_node()
        #self.draw_board()

    def start_game(self):
        print "avg", sum(self.results)/float(len(self.results) + 0.001)
        if len(self.results) < 30:
            self.game_board = Game2048(board=[[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]])
            self.board = self.game_board.board
            self.game_board.generate_new_node()
            self.depth = 4
            self.move_count = 0
            self.expectimax = Expectimax()
            self.draw_board()
            self.time = time()
            self.run_algorithm()
        else:
            print self.results
            print "avg", sum(self.results)/float(len(self.results))


    def run_algorithm(self):
        if self.game_board.open_cells_count() < 4:
            self.depth = 3
        else:
            self.depth = 3
        continuing = True
        if self.game_board.is_game_over():
            largest_tile = self.game_board.get_largest_tile()
            print "largest tile", largest_tile
            print "time elapsed: " + str(round((time() - self.time)/60, 1)) + " min"
            self.results.append(largest_tile)
            continuing = False
            print "move count", self.move_count
            return self.start_game()
        current_node = State(self.game_board, self.depth)
        self.move_count += 1
        chosen_move = self.expectimax.run_expectimax(current_node, self.depth, -float("inf"), float("inf"), None)
        expectimax_result = self.expectimax.result
        flat_board = current_node.board.board[3] + current_node.board.board[2] + current_node.board.board[1] + current_node.board.board[0]
        #TODO what is this? Continuing
        if chosen_move == None:
            Continuing = False
        elif chosen_move == 0:
            Continuing = False
        elif chosen_move == "left":
            self.game_board.move_left()
        elif chosen_move == "right":
            self.game_board.move_right()
        elif chosen_move == "up":
            self.game_board.move_up()
        elif chosen_move == "down":
            self.game_board.move_down()
        else:
            print "finished because of error in minimax chosen move"
        self.game_board.generate_new_node()
        self.draw_board()
        if continuing:
            self.after(self.delay, lambda: self.run_algorithm())

    def bind_keys(self):
        self.bind('<Up>', lambda event: self.move(self, self.game_board.move_up(), 0))
        self.bind('<Right>', lambda event: self.move(self, self.game_board.move_right(), 1))
        self.bind('<Down>', lambda event: self.move(self, self.game_board.move_down(), 2))
        self.bind('<Left>', lambda event: self.move(self, self.game_board.move_left(), 3))

    def move(self, event, is_moved, direction):
        if is_moved:
            self.game_board.generate_new_node()
            self.draw_board()
            self.f = open('/Users/hakon0601/Dropbox/Python/AIProg/AIProg_Module_5/2048trainingdata.txt', 'a')
            board = ""
            for i in range(3,-1,-1):
                board += (str(self.game_board.board[i][0])) + " "
                board += (str(self.game_board.board[i][1])) + " "
                board += (str(self.game_board.board[i][2])) + " "
                board += (str(self.game_board.board[i][3])) + " "
            board += " "
            board += str(direction)
            self.f.write(board)
            self.f.write("\n")
            self.f.close()

    def draw_board(self):
        self.canvas.delete("all")
        for y in range(self.dim[1]):
                for x in range(self.dim[0]):
                    x1 = x * self.cell_width
                    y1 = self.dim[1]*self.cell_height - y * self.cell_height
                    x2 = x1 + self.cell_width
                    y2 = y1 - self.cell_height
                    cell_type = self.board[y][x]
                    text = str(self.board[y][x])
                    color = self.color_dict[str(self.board[y][x])]
                    self.canvas.create_rectangle(x1, y1, x2, y2, fill=color, tags="rect")
                    if cell_type != 0:
                        self.canvas.create_text(x1+self.cell_width/2, y1-self.cell_height/2, text=text)

    def fill_color_dict(self):
        color_dict = {
            '0': "white",
            '2': "lemon chiffon",
            '4': "peach puff",
            '8': "sandy brown",
            '16': "dark orange",
            '32': "salmon",
            '64': "tomato",
            '128': "khaki",
            '256': "khaki",
            '512': "red",
            '1024': "light goldenrod",
            '2048': "firebrick",
            '4096': "dim grey",
            '8192': "light goldenrod",
        }
        return color_dict
Beispiel #9
0
def run_game(game_class=Game2048, title='2048: In Python!', data_dir=None, **kwargs):
    pygame.init()
    pygame.display.set_caption(title)

    AI_type = kwargs["AI_type"]

    # Try to set the game icon.
    try:
        pygame.display.set_icon(game_class.icon(32))
    except pygame.error:
        # On windows, this can fail, so use GDI to draw then.
        print('Consider getting a newer card or drivers.')
        os.environ['SDL_VIDEODRIVER'] = 'windib'

    if data_dir is None:
        data_dir = user_data_dir(appauthor='Quantum', appname='2048', roaming=True)
        try:
            os.makedirs(data_dir)
        except OSError as e:
            if e.errno != errno.EEXIST:
                raise

    score_file_prefix = os.path.join(data_dir, '2048')
    state_file_prefix = os.path.join(data_dir, '2048')

    if AI_type:
        score_file_prefix += '_' + AI_type
        state_file_prefix += '_' + AI_type

    if AI_type in ["heuristic", "rollout", "MCTS"]:
        if AI_type == "rollout" and kwargs["type"] is None or kwargs["type"] == 'None':
            type_str = "random"
        else:
            type_str = kwargs["type"]
        score_file_prefix += '_' + type_str
        state_file_prefix += '_' + type_str

    screen = pygame.display.set_mode((game_class.WIDTH, game_class.HEIGHT))
    manager = GameManager(Game2048, screen,
                          score_file_prefix + '.score',
                          state_file_prefix + '.%d.state', **kwargs)
    if not AI_type:
        try:
            while True:
                event = pygame.event.wait()
                manager.dispatch(event)
                for event in pygame.event.get():
                    manager.dispatch(event)
                manager.draw()

        finally:
            pygame.quit()
            manager.close()

    else:
        try:
            pygame.event.set_blocked([pygame.KEYDOWN, pygame.MOUSEBUTTONUP])
            manager.new_game(**kwargs)
            game_scores = []
            best_tiles = []
            condition = True
            tree = None

            if AI_type in ["rollout", "MCTS"]:
                num_rollouts = kwargs["num_rollouts"]
                max_depth = kwargs["max_depth"]
                epsilon = kwargs["epsilon"]
                if epsilon < 0 or epsilon > 1:
                    raise ValueError("Epsilon must be in the interval [0, 1].")
                if AI_type == "MCTS":
                    UCT = kwargs["UCT"]
                    tree = AI.GameTree(np.array(manager.game.grid), max_search_depth=max_depth,
                                       num_rollouts=num_rollouts, epsilon=epsilon, UCT=UCT,
                                       use_expert_score=kwargs["use_expert"])

            while condition:
                if manager.game.lost:
                    event = pygame.event.Event(pygame.MOUSEBUTTONUP, {"pos": manager.game.lost_try_again_pos})
                    game_scores.append(manager.game.score)
                    best_tiles.append(np.max(manager.game.grid))
                    print(len(game_scores))
                    if AI_type in ["random", "heuristic", "MCTS", "rollout", "expectimax"]:
                        condition = kwargs["num_games"] > len(game_scores)
                elif manager.game.won == 1:
                    event = pygame.event.Event(pygame.MOUSEBUTTONUP, {"pos": manager.game.keep_going_pos})
                elif AI_type == "random":
                    event = AI.random_move_event(np.array(manager.game.grid))
                elif AI_type == "heuristic":
                    event = AI.heuristic_move_event(np.array(manager.game.grid), kwargs["type"])
                elif AI_type == "rollout":
                    event = AI.rollouts(np.array(manager.game.grid), manager.game.score, kwargs["type"],
                                        max_search_depth=max_depth, num_rollouts=num_rollouts, epsilon=epsilon,
                                        use_expert_score=kwargs["use_expert"])
                elif AI_type == "MCTS":
                    event = tree.MCTS(np.array(manager.game.grid), manager.game.score)
                elif AI_type == "expectimax":
                    event = Expectimax(kwargs['max_depth']).get_best_move(np.array(manager.game.grid))
                else:
                    raise ValueError("AI mode selected but invalid AI type was supplied!")
                manager.dispatch(event)
                manager.draw()

            print("Number of games played:", len(game_scores))
            print("Game Scores:")
            print(game_scores)
            print("Best Tiles:")
            print(best_tiles)
            print("Max Score:", max(game_scores))
            print("Max Tile:", max(best_tiles))
            print("Average Score:", stats.mean(game_scores))

        finally:
            if "simulate" not in kwargs:
                pygame.quit()
                manager.close()

        if "simulate" in kwargs:
            results = {
                "game_scores": game_scores,
                "best_tiles": best_tiles,
                "max_score": max(game_scores),
                "max_tile": max(best_tiles),
                "avg_score": stats.mean(game_scores)
            }
            return results