class CLIRunner: def __init__(self): self.board = GameBoard() self.ai = Expectimax() self.init_game() print_board(self.board) self.run_game() self.over = False def init_game(self): self.insert_random_tile() self.insert_random_tile() def run_game(self): moves = 0 while True and moves < 2: move = self.ai.get_move(self.board) print("Player's Turn:", end="") self.board.move(move) print(dirs[move]) print_board(self.board) print("Computer's Turn") self.insert_random_tile() print_board(self.board) if len(self.board.get_available_moves()) == 0: print("GAME OVER (max tile): " + str(self.board.get_max_tile())) break moves += 1 if DELAY: time.sleep(DELAY) def insert_random_tile(self): if randint(0,99) < 100 * 0.9: value = 2 else: 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_tile(pos, value) return pos
class Batch: def __init__(self): # MEASURES self.total_moves_time = 0 self.total_moves = 0 self.fastest_move = -1 self.longest_move = 0 self.time_to_reach = [] # setup game & ai self.board = GameBoard() self.ai = Expectimax() self.init_game() # run ai on game self.start = timer() self.run_game() end = timer() # MEASURES self.total_time = end - self.start # total time to run self.avg_move_time = self.total_moves_time / self.total_moves # moves done self.max_tile = self.board.get_max_tile() # max tile self.states_visited = self.ai.states_visited # states visited def init_game(self): self.insert_random_tile() self.insert_random_tile() def run_game(self): cur_max_tile = 8 while True: move_start = timer() move = self.ai.get_move(self.board) move_end = timer() # save move time move_time = move_end - move_start self.total_moves_time += move_time self.total_moves += 1 if self.fastest_move == -1 or move_time < self.fastest_move: self.fastest_move = move_time if move_time > self.longest_move: self.longest_move = move_time # do the actual move + the response self.board.move(move) self.insert_random_tile() # check if we got a bigger tile if cur_max_tile in self.board.grid: reached_end = timer() self.time_to_reach.append((cur_max_tile, reached_end - self.start)) cur_max_tile *= 2 # if no more moves, game over if len(self.board.get_available_moves()) == 0: break def insert_random_tile(self): if randint(0,99) < 100 * 0.9: value = 2 else: 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_tile(pos, value) return pos
class GameGrid(Frame): def __init__(self): Frame.__init__(self) self.grid() self.master.title('2048') self.grid_cells = [] self.init_grid() self.init_matrix() self.update_grid_cells() self.AI = AI() self.run_game() self.mainloop() def run_game(self): while True: self.board.move(self.AI.get_move(self.board)) self.update_grid_cells() self.add_random_tile() 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[1][1].configure(text="TOP", bg=BACKGROUND_COLOR_CELL_EMPTY) self.grid_cells[1][2].configure(text="4 TILES:", bg=BACKGROUND_COLOR_CELL_EMPTY) top_4 = list( map(int, reversed(sorted(list(self.board.grid.flatten()))))) self.grid_cells[2][0].configure(text=str(top_4[0]), bg=BACKGROUND_COLOR_DICT[2048], fg=CELL_COLOR_DICT[2048]) self.grid_cells[2][1].configure(text=str(top_4[1]), bg=BACKGROUND_COLOR_DICT[2048], fg=CELL_COLOR_DICT[2048]) self.grid_cells[2][2].configure(text=str(top_4[2]), bg=BACKGROUND_COLOR_DICT[2048], fg=CELL_COLOR_DICT[2048]) self.grid_cells[2][3].configure(text=str(top_4[3]), bg=BACKGROUND_COLOR_DICT[2048], fg=CELL_COLOR_DICT[2048]) self.update() def init_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 init_matrix(self): self.board = GameBoard() self.add_random_tile() self.add_random_tile() 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_tile(self): if randint(0, 99) < 100 * 0.9: value = 2 else: 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_tile(pos, value) return pos