def __init__(self, size=4, parent=None, cost=0): Grid.__init__(self, size = 4) self.cost = cost self.parent = parent self.children = [] """
def heuristic(node: Grid): score = 0 num_empty_cells = len(node.getAvailableCells()) for i in range(node.size): for j in range(node.size): val = node.getCellValue((i, j)) score += val * 10 if val else ( 1000 / num_empty_cells ) # reward empty spaces more if they are scarce val_up = node.getCellValue((i - 1, j)) val_dn = node.getCellValue((i + 1, j)) val_lt = node.getCellValue((i, j - 1)) val_rt = node.getCellValue((i, j + 1)) if val_up is not None and \ val_dn is not None and \ val != 0: if not (val_up <= val <= val_dn or val_up >= val >= val_dn): score -= 75 * (abs(val_up - val) + abs(val_dn - val)) if val_lt is not None and \ val_rt is not None and \ val != 0: if not (val_lt <= val <= val_rt or val_lt >= val >= val_rt): score -= 75 * (abs(val_lt - val) + abs(val_rt - val)) if j == 0: row = node.map[i] monotonic_row = all(x <= y for x, y in zip(row, row[1:])) monotonic_row = monotonic_row or all( x >= y for x, y in zip(row, row[1:])) if monotonic_row: score += 200 * sum(row) # big bonus if i == 0: col = [node.map[pos][j] for pos in range(node.size)] monotonic_col = all(x <= y for x, y in zip(col, col[1:])) monotonic_col = monotonic_col or all( x >= y for x, y in zip(col, col[1:])) if monotonic_col: score += 200 * sum(col) # big bonus val_order = PlayerAI.get_value_order(val) if val_order > 0: val_up_order = PlayerAI.get_value_order(val_up) val_dn_order = PlayerAI.get_value_order(val_dn) val_lt_order = PlayerAI.get_value_order(val_lt) val_rt_order = PlayerAI.get_value_order(val_rt) if val_up_order > 0: score -= abs(val_up_order - val_order) * 25 if val_dn_order > 0: score -= abs(val_dn_order - val_order) * 25 if val_lt_order > 0: score -= abs(val_lt_order - val_order) * 25 if val_rt_order > 0: score -= abs(val_rt_order - val_order) * 25 return score
def is_state_terminal(self, grid_to_check: Grid, min_max: str): if self.is_grid_depth_out_of_bound(grid_to_check.current_depth): return True if min_max == 'min': return len(grid_to_check.getAvailableCells() ) == 0 # or grid.getMaxTile() > 100 else: return not grid_to_check.canMove() # or grid.getMaxTile() > 100
def __init__(self, size = 4): self.grid = Grid(size) self.possibleNewTiles = [2, 4] self.probability = defaultProbability self.initTiles = defaultInitialTiles self.computerAI = None self.playerAI = None self.displayer = None self.over = False
def __init__(self, size=4): self.grid = Grid(size) self.possibleNewTiles = [2, 4] self.probability = defaultProbability self.initTiles = defaultInitialTiles self.computerAI = None self.playerAI = None self.displayer = None self.over = False # Load the DNN model self.model_NN = load_model("all_2048_8000games.h5")
def __init__(self, size=4, playerAI=None, computerAI=None, displayer=None): self.grid = Grid(size) self.possibleNewTiles = [2, 4] self.probability = defaultProbability self.initTiles = defaultInitialTiles self.over = False # Initialize the AI players self.computerAI = computerAI or ComputerAI() self.playerAI = playerAI or PlayerAI() self.displayer = displayer or Displayer()
def __init__(self, size=4): self.grid = Grid(size) self.possibleNewTiles = [2, 4] self.probability = defaultProbability self.initTiles = defaultInitialTiles self.computerAI = None self.playerAI = None self.displayer = None self.over = False self.max_time_for_get_move = 0 self.next_move_counter = 0 self.MAX_NEXT_MOVE_COUNTER = 10000
def main(): grid1 = Grid() node1 = Node(grid1, 0) grid1.map[0][0] = 64 grid1.map[1][0] = 2 grid1.map[3][0] = 4 grid1.map[0][1] = 0 grid1.map[1][1] = 0 grid1.map[3][1] = 0 grid1.map[2][1] = 0 grid1.map[2][2] = 0 strategy = MiniMax(node1) alpha_beta = strategy.alpha_beta(5) print("\nMiniMax: ", node1.h_value, "\nDirection: ", alpha_beta)
def get_children(self, grid: Grid, min_or_max: str): grid_children = [] if min_or_max == 'max': moves = grid.getAvailableMoves() for move in moves: child_grid = self.get_grid_for_move(grid, move) child_grid.current_depth = grid.current_depth + 1 grid_children.append(child_grid) else: cells = grid.getAvailableCells() values = [2, 4] for cell in cells: for value in values: grid_copy = grid.clone() grid_copy.setCellValue(cell, value) grid_copy.current_depth = grid.current_depth + 1 grid_children.append(grid_copy) return grid_children
def minimizing(self, alpha, beta, node: Grid, depth): if depth == 0: return self.heuristic(node) cells = node.getAvailableCells() if not cells: return self.get_terminal_node_value(node) value = math.inf for cell in cells: for i in range(2, 5, 2): child = node.clone() child.insertTile(cell, i) value = min(value, self.maximizing(alpha, beta, child, depth - 1)[0]) beta = min(beta, value) if alpha >= beta: break return value
def main4(): grid1 = Grid() node1 = Node(grid1, 0) grid1.map[0][0] = 64 grid1.map[1][0] = 2 grid1.map[3][0] = 4 grid1.map[0][1] = 0 grid1.map[1][1] = 0 grid1.map[3][1] = 0 grid1.map[2][1] = 0 grid1.map[2][2] = 0 my_tree = SearchTree(node1) my_tree.build_tree(4) strategy = MiniMax(node1) alpha_beta = strategy.alpha_beta(5) print("\nMiniMax: ", node1.h_value, "\nDirection: ", alpha_beta)
def maximizing(self, alpha, beta, node: Grid, depth): maximizing_move = None if depth == 0: return self.heuristic(node), maximizing_move moves = node.getAvailableMoves() if not moves: return self.get_terminal_node_value(node), maximizing_move value = -math.inf for move in moves: child = node.clone() child.move(move) opponent_value = self.minimizing(alpha, beta, child, depth - 1) maximizing_move = move if opponent_value >= value else maximizing_move value = max(value, opponent_value) alpha = max(alpha, value) if alpha >= beta: break return value, maximizing_move
def main2(): # my_node = Node(Grid(),0) # my_node.grid.setCellValue((3,3), 1) # my_node.print_grid() grid1 = Grid() grid1.setCellValue((0, 0), 1) grid2 = grid1.clone() grid2.setCellValue((0, 1), 1) # child of node1 grid3 = grid1.clone() grid3.setCellValue((0, 1), 2) # child of node1 grid4 = grid2.clone() grid4.setCellValue((0, 2), 1) # child of node2 grid5 = grid3.clone() grid5.setCellValue((0, 2), 1) # child of node3 node1 = Node(grid1, 0) node2 = Node(grid2, 0) node3 = Node(grid3, 0) node4 = Node(grid4, 0) node5 = Node(grid5, 0) node1.push_children(node2) node1.push_children(node3) node2.push_children(node4) node3.push_children(node5) my_tree = SearchTree(node1) my_tree.print_tree()
def main3(): grid1 = Grid() node1 = Node(grid1, 0) grid1.map[0][0] = 2 grid1.map[1][0] = 2 grid1.map[3][0] = 4 grid1.map[0][1] = 0 grid1.map[1][1] = 0 grid1.map[3][1] = 0 grid1.map[2][1] = 0 grid1.map[2][2] = 0 my_tree = SearchTree(node1) my_tree.build_tree(4) my_tree.print_tree() strategy = MiniMax(node1) alpha_beta = strategy.alpha_beta(4) print("\nMiniMax: {0:.4f}".format(alpha_beta)) print("---------> ", node1.h_value)
def get_grid_value(grid: Grid): number_cells = grid.size**2 sum_tiles = 0 neigbors_equal = 0 for x in range(grid.size): for y in range(grid.size): sum_tiles += grid.map[x][y] if (x < grid.size - 1) and grid.map[x][y] == grid.map[x + 1][y]: neigbors_equal += 1 if (y < grid.size - 1) and grid.map[x][y] == grid.map[x][y + 1]: neigbors_equal += 1 average = sum_tiles / number_cells number_zero_cells = len(grid.getAvailableCells()) return 2 * number_zero_cells / number_cells + average / 2048 + neigbors_equal / number_cells
def set_grid_cell_numbers(self, grid: Grid): self.number_grid_cells = grid.size**2 self.number_grid_cells_zero = len(grid.getAvailableCells()) if self.number_grid_cells_zero == 0: self.number_grid_cells_zero = 1 # to avoid problems self.level_number_branches.update({ '0': 1 }) # default value for 0 - which is only used for this calculation for k in range(1, 100): if k % 2 == 1: # on that level the computer's values are added to each branch self.level_number_branches.update({ str(k): self.level_number_branches.get(str(k - 1)) * self.number_grid_cells_zero * 2 }) else: # on that level the movements are added to each branch self.level_number_branches.update( {str(k): self.level_number_branches.get(str(k - 1)) * 4})
def get_decision_move(self, grid: Grid) -> Grid: # print('get_decision_move (input): {}'.format(grid.map)) moves = grid.getAvailableMoves() max_value = -math.inf self.sort_moves_for_alpha_beta_pruning(moves) for move in moves: grid_after_move = self.get_grid_for_move(grid, move) grid_after_move.current_depth = grid.current_depth + 1 a = -math.inf b = math.inf (child, utility) = self.minimize( grid_after_move, a, b) # the first move was already done in this function # print('get_decision_move: {} with utility_value (min) = {} for move {}'.format(grid_after_move.map, utility, move)) if utility > max_value: move_return = move max_value = utility return move_return
class GameManager: def __init__(self, size=4): self.grid = Grid(size) self.possibleNewTiles = [2, 4] self.probability = defaultProbability self.initTiles = defaultInitialTiles self.computerAI = None self.playerAI = None self.displayer = None self.over = False def setComputerAI(self, computerAI): self.computerAI = computerAI def setPlayerAI(self, playerAI): self.playerAI = playerAI def setDisplayer(self, displayer): self.displayer = displayer def updateAlarm(self, currTime): if currTime - self.prevTime > timeLimit + allowance: #self.over = True print("Time over!!") print(currTime - self.prevTime) else: while time.clock() - self.prevTime < timeLimit + allowance: pass self.prevTime = time.clock() def start(self): for i in range(self.initTiles): self.insertRandonTile() self.displayer.display(self.grid) # Player AI Goes First turn = PLAYER_TURN maxTile = 0 self.prevTime = time.clock() while not self.isGameOver() and not self.over: # Copy to Ensure AI Cannot Change the Real Grid to Cheat gridCopy = self.grid.clone() move = None if turn == PLAYER_TURN: print("Player's Turn:", end="") move = self.playerAI.getMove(gridCopy) print(actionDic[move]) # Validate Move if move != None and move >= 0 and move < 4: if self.grid.canMove([move]): self.grid.move(move) # Update maxTile maxTile = self.grid.getMaxTile() else: print("Invalid PlayerAI Move") self.over = True else: print("Invalid PlayerAI Move - 1") self.over = True else: print("Computer's turn:") move = self.computerAI.getMove(gridCopy) # Validate Move if move and self.grid.canInsert(move): self.grid.setCellValue(move, self.getNewTileValue()) else: print("Invalid Computer AI Move") self.over = True if not self.over: self.displayer.display(self.grid) # Exceeding the Time Allotted for Any Turn Terminates the Game self.updateAlarm(time.clock()) turn = 1 - turn print(maxTile) def isGameOver(self): return not self.grid.canMove() def getNewTileValue(self): if randint(0, 99) < 100 * self.probability: return self.possibleNewTiles[0] else: return self.possibleNewTiles[1] def insertRandonTile(self): tileValue = self.getNewTileValue() cells = self.grid.getAvailableCells() cell = cells[randint(0, len(cells) - 1)] self.grid.setCellValue(cell, tileValue)
class GameManager: def __init__(self, size=4, playerAI=None, computerAI=None, displayer=None): self.grid = Grid(size) self.possibleNewTiles = [2, 4] self.probability = defaultProbability self.initTiles = defaultInitialTiles self.over = False # Initialize the AI players self.computerAI = computerAI or ComputerAI() self.playerAI = playerAI or PlayerAI() self.displayer = displayer or Displayer() self.timedOut = False def updateAlarm(self) -> None: """ Checks if move exceeded the time limit and updates the alarm """ if time.process_time() - self.prevTime > maxTime: print("timed out") self.over = True self.timedOut = True self.prevTime = time.process_time() def getNewTileValue(self) -> int: """ Returns 2 with probability 0.95 and 4 with 0.05 """ return self.possibleNewTiles[random.random() > self.probability] def insertRandomTiles(self, numTiles: int): """ Insert numTiles number of random tiles. For initialization """ for i in range(numTiles): tileValue = self.getNewTileValue() cells = self.grid.getAvailableCells() cell = random.choice(cells) if cells else None self.grid.setCellValue(cell, tileValue) def start(self) -> int: """ Main method that handles running the game of 2048 """ # Initialize the game self.insertRandomTiles(self.initTiles) self.displayer.display(self.grid) turn = PLAYER_TURN # Player AI Goes First self.prevTime = time.process_time() while self.grid.canMove() and not self.over: # Copy to Ensure AI Cannot Change the Real Grid to Cheat gridCopy = self.grid.clone() #time.sleep(.1) move = None if turn == PLAYER_TURN: print("Player's Turn: ", end="") move = self.playerAI.getMove(gridCopy) print(actionDic[move]) # If move is valid, attempt to move the grid if move != None and 0 <= move < 4: if self.grid.canMove([move]): self.grid.move(move) else: print("Invalid PlayerAI Move - Cannot move") self.over = True else: print("Invalid PlayerAI Move - Invalid input") self.over = True else: print("Computer's turn: ") move = self.computerAI.getMove(gridCopy) # Validate Move if move and self.grid.canInsert(move): self.grid.setCellValue(move, self.getNewTileValue()) else: print("Invalid Computer AI Move") self.over = True # Comment out during heuristing optimizations to increase runtimes. # Printing slows down computation time. self.displayer.display(self.grid) # Exceeding the Time Allotted for Any Turn Terminates the Game self.updateAlarm() turn = 1 - turn return self.grid.getMaxTile() def start_no_disp(self) -> int: """ Main method that handles running the game of 2048 """ # Initialize the game self.insertRandomTiles(self.initTiles) #self.displayer.display(self.grid) turn = PLAYER_TURN # Player AI Goes First self.prevTime = time.process_time() while self.grid.canMove() and not self.over: # Copy to Ensure AI Cannot Change the Real Grid to Cheat gridCopy = self.grid.clone() #time.sleep(.1) move = None if turn == PLAYER_TURN: #print("Player's Turn: ", end="") move = self.playerAI.getMove(gridCopy) #print(actionDic[move]) # If move is valid, attempt to move the grid if move != None and 0 <= move < 4: if self.grid.canMove([move]): self.grid.move(move) else: #print("Invalid PlayerAI Move - Cannot move") self.over = True else: #print("Invalid PlayerAI Move - Invalid input") self.over = True else: #print("Computer's turn: ") move = self.computerAI.getMove(gridCopy) # Validate Move if move and self.grid.canInsert(move): self.grid.setCellValue(move, self.getNewTileValue()) else: #print("Invalid Computer AI Move") self.over = True # Comment out during heuristing optimizations to increase runtimes. # Printing slows down computation time. #self.displayer.display(self.grid) # Exceeding the Time Allotted for Any Turn Terminates the Game self.updateAlarm() turn = 1 - turn return self.grid.getMaxTile() def start_training(self) -> int: """ Main method that handles running the game of 2048 """ # Initialize the game self.insertRandomTiles(self.initTiles) #self.displayer.display(self.grid) turn = PLAYER_TURN # Player AI Goes First self.prevTime = time.process_time() while self.grid.canMove() and not self.over: # Copy to Ensure AI Cannot Change the Real Grid to Cheat gridCopy = self.grid.clone() #time.sleep(.1) move = None if turn == PLAYER_TURN: #print("Player's Turn: ", end="") move = self.playerAI.getMoveLearning(gridCopy) #print(actionDic[move]) # If move is valid, attempt to move the grid if move != None and 0 <= move < 4: if self.grid.canMove([move]): self.grid.move(move) else: #print("Invalid PlayerAI Move - Cannot move") self.over = True else: #print("Invalid PlayerAI Move - Invalid input") self.over = True else: #print("Computer's turn: ") move = self.computerAI.getMove(gridCopy) # Validate Move if move and self.grid.canInsert(move): self.grid.setCellValue(move, self.getNewTileValue()) else: #print("Invalid Computer AI Move") self.over = True # Comment out during heuristing optimizations to increase runtimes. # Printing slows down computation time. #self.displayer.display(self.grid) # Exceeding the Time Allotted for Any Turn Terminates the Game self.updateAlarm() turn = 1 - turn return self.grid.getMaxTile() def start_reinforce(self) -> int: """ Main method that handles running the game of 2048 """ # Initialize the game self.insertRandomTiles(self.initTiles) #self.displayer.display(self.grid) turn = PLAYER_TURN # Player AI Goes First self.prevTime = time.process_time() while self.grid.canMove() and not self.over: # Copy to Ensure AI Cannot Change the Real Grid to Cheat gridCopy = self.grid.clone() #time.sleep(.1) move = None if turn == PLAYER_TURN: #print("Player's Turn: ", end="") move = self.playerAI.getMove(gridCopy) #print(actionDic[move]) # If move is valid, attempt to move the grid if move != None and 0 <= move < 4: if self.grid.canMove([move]): self.grid.move(move) else: #print("Invalid PlayerAI Move - Cannot move") self.over = True else: #print("Invalid PlayerAI Move - Invalid input") self.over = True else: #print("Computer's turn: ") move = self.computerAI.getMove(gridCopy) # Validate Move if move and self.grid.canInsert(move): self.grid.setCellValue(move, self.getNewTileValue()) else: #print("Invalid Computer AI Move") self.over = True # Comment out during heuristing optimizations to increase runtimes. # Printing slows down computation time. #self.displayer.display(self.grid) # Exceeding the Time Allotted for Any Turn Terminates the Game self.updateAlarm() turn = 1 - turn return self.grid.getMaxTile()
def get_grid_for_move(self, grid: Grid, move: int): clone = grid.clone() clone.move(move) return clone
u *= child.factor # Even index corresponds to a weight of 0.1 utility += u if utility < min_utility: min_child, min_utility = child, utility if min_utility <= alpha: break if min_utility < beta: beta = min_utility return min_child, min_utility if __name__ == '__main__': g = Grid() g.map[0][0] = 2 g.map[0][1] = 2 g.map[0][2] = 4 g.map[0][3] = 4 g.map[1][0] = 4 g.map[1][1] = 2 g.map[1][2] = 4 g.map[1][3] = 2 g.map[2][0] = 2 g.map[2][1] = 4 g.map[2][2] = 2 g.map[2][3] = 4
def create_slowgrid_from(self, val) -> Grid: sut = Grid() for row in range(4): for col in range(4): sut.setCellValue((row, col), val[row][col]) return sut
class GameManager: def __init__(self, size=4): self.grid = Grid(size) self.possibleNewTiles = [2, 4] self.probability = defaultProbability self.initTiles = defaultInitialTiles self.computerAI = None self.playerAI = None self.displayer = None self.over = False self.max_time_for_get_move = 0 self.next_move_counter = 0 self.MAX_NEXT_MOVE_COUNTER = 10000 def setComputerAI(self, computerAI): self.computerAI = computerAI def setPlayerAI(self, playerAI): self.playerAI = playerAI def setDisplayer(self, displayer): self.displayer = displayer def updateAlarm(self, currTime): if currTime - self.prevTime > timeLimit + allowance: self.over = False else: while time.clock() - self.prevTime < timeLimit + allowance: pass self.prevTime = time.clock() def start(self): for i in range(self.initTiles): self.insertRandonTile() # self.grid.map = [[4, 128, 4, 2], [64, 4, 32, 4], [8, 64, 8, 16], [16, 4, 2, 2]] # self.grid.map = [[2, 32, 2, 4], [4, 256, 32, 8], [16, 64, 16, 0], [4, 16, 8, 4]] # self.grid.map = [[2, 32, 2, 4], [4, 256, 32, 8], [2, 32, 64, 16], [4, 0, 8, 4]] # with utility_value (min) = -inf for move 0 # self.grid.map = [[2, 32, 2, 4], [4, 256, 32, 8], [2, 32, 64, 16], [2, 4, 8, 4]] # for move 0 => -inf - WHY self.displayer.display(self.grid) # Player AI Goes First turn = PLAYER_TURN maxTile = 0 self.prevTime = time.clock() while not self.isGameOver() and not self.over: # Copy to Ensure AI Cannot Change the Real Grid to Cheat gridCopy = self.grid.clone() move = None if turn == PLAYER_TURN: print("Player's Turn:", end="") move = self.playerAI.getMove(gridCopy) if self.playerAI.run_time > self.max_time_for_get_move: self.max_time_for_get_move = self.playerAI.run_time print(actionDic[move]) # Validate Move if move != None and move >= 0 and move < 4: if self.grid.canMove([move]): self.grid.move(move) # Update maxTile maxTile = self.grid.getMaxTile() else: print("Invalid PlayerAI Move") self.over = True else: print("Invalid PlayerAI Move - 1") self.over = True self.next_move_counter += 1 if self.next_move_counter > self.MAX_NEXT_MOVE_COUNTER: self.over = True break else: print("Computer's turn:") move = self.computerAI.getMove(gridCopy) # Validate Move if move and self.grid.canInsert(move): self.grid.setCellValue(move, self.getNewTileValue()) else: print("Invalid Computer AI Move") self.over = True if not self.over: self.displayer.display(self.grid) # Exceeding the Time Allotted for Any Turn Terminates the Game self.updateAlarm(time.clock()) turn = 1 - turn print( 'maxTile = {0} - max_time_for_get_move = {1:5.4f} - number_players_moves = {2}' .format(maxTile, self.max_time_for_get_move, self.next_move_counter)) self.plot_move_times() def plot_move_times(self): x = np.array([i for i in range(len(self.playerAI.run_time_list))]) y = np.array(self.playerAI.run_time_list) plt.plot(x, y) plt.show() # plot with various axes scales plt.figure(1) # linear plt.subplot(221) plt.plot(x, y) plt.yscale('linear') plt.title('linear') plt.grid(True) def isGameOver(self): return not self.grid.canMove() def getNewTileValue(self): if randint(0, 99) < 100 * self.probability: return self.possibleNewTiles[0] else: return self.possibleNewTiles[1] def insertRandonTile(self): tileValue = self.getNewTileValue() cells = self.grid.getAvailableCells() cell = cells[randint(0, len(cells) - 1)] self.grid.setCellValue(cell, tileValue)
def to_slowgrid(self): g = Grid() g.map = Util.array_to_2dlist(self.board) return g
from random import randint from BaseAI_3 import BaseAI from Grid_3 import Grid from PlayerAI_3 import PlayerAI grid = Grid() grid.map = [[4, 64, 8, 4], [32, 8, 64, 8], [256, 512, 32, 4], [4, 8, 4, 2]] moves = [1, 2, 3, 4] print(moves) moves[2] = 7 print(moves) print(len(grid.getAvailableCells())) print(grid.map) print(PlayerAI.is_state_terminal(grid, 'min'))
neighbours = self.get_neighbours(pos) for n in neighbours: if pos_value == grid.getCellValue(n): merges += 1 return merges def grid_eval(self, grid): gradients = [[[3, 2, 1, 0], [2, 1, 0, -1], [1, 0, -1, -2], [0, -1, -2, -3]], [[0, 1, 2, 3], [-1, 0, 1, 2], [-2, -1, 0, 1], [-3, -2, -1, -0]], [[0, -1, -2, -3], [1, 0, -1, -2], [2, 1, 0, -1], [3, 2, 1, 0]], [[-3, -2, -1, 0], [-2, -1, 0, 1], [-1, 0, 1, 2], [0, 1, 2, 3]]] values = [0, 0, 0, 0] for i in range(4): for x in range(4): for y in range(4): values[i] += gradients[i][x][y] * grid.map[x][y] return max(values) if __name__ == "__main__": grid = Grid() a = grid.getAvailableCells() print(len(a))
#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Created on Mon Jun 11 16:36:48 2018 @author: jinzhao """ from Grid_3 import Grid g = Grid() g.map[0][0] = 2 g.map[1][0] = 2 g.map[3][0] = 4 empty = g.getAvailableCells() print(empty) def test_fun(): return 1, 2 b = test_fun()[1] print(b) class test_class(): def __init__(self): self.val = 100
class GameManager: def __init__(self, size = 4): self.grid = Grid(size) self.possibleNewTiles = [2, 4] self.probability = defaultProbability self.initTiles = defaultInitialTiles self.computerAI = None self.playerAI = None self.displayer = None self.over = False def setComputerAI(self, computerAI): self.computerAI = computerAI def setPlayerAI(self, playerAI): self.playerAI = playerAI def setDisplayer(self, displayer): self.displayer = displayer def updateAlarm(self, currTime): if currTime - self.prevTime > timeLimit + allowance: self.over = True else: while time.clock() - self.prevTime < timeLimit + allowance: pass self.prevTime = time.clock() def gridAverage(self, grid): cells = [] for x in range(4): for y in range(4): if grid.map[x][y] > 0: cells.append((x,y)) sum = 0 for c in cells: sum += grid.map[c[0]][c[1]] return sum / len(cells) def play_one(self, model, tmodel, eps, gamma, copy_period): for i in range(self.initTiles): self.insertRandonTile() grid_array = np.array(self.grid.map).ravel() #observation = grid_array / np.linalg.norm(grid_array) observation = grid_array / 2048 done = False totalreward = 0 iters = 0 ##self.displayer.display(self.grid) # Player AI Goes First turn = PLAYER_TURN maxTile = 2 self.prevTime = time.clock() #while not self.isGameOver() and not self.over: while not self.isGameOver(): # Copy to Ensure AI Cannot Change the Real Grid to Cheat gridCopy = self.grid.clone() move = None if turn == PLAYER_TURN: ##print("Player's Turn:", end="") #move = self.playerAI.getMove(gridCopy) move = model.sample_action(observation, eps, gridCopy) gridAvg = self.gridAverage(gridCopy) #lastMax = gridCopy.getMaxTile() prev_observation = observation last_maxTile = maxTile ##print(actionDic[move]) # Validate Move if move != None and move >= 0 and move < 4: if self.grid.canMove([move]): self.grid.move(move) maxTile = self.grid.getMaxTile() #observation, reward, done, info = env.step(action) grid_array = np.array(self.grid.map).ravel() #observation = grid_array / np.linalg.norm(grid_array) observation = grid_array / maxTile gridNewAvg = self.gridAverage(self.grid) #newMax = self.grid.getMaxTile() reward = gridNewAvg - gridAvg # Update maxTile #reward = maxTile - last_maxTile #reward = 1 done = self.isGameOver() if done: reward = -100 # update the model model.add_experience(prev_observation, move, reward, observation, done) model.train(tmodel) if iters % copy_period == 0: tmodel.copy_from(model) if reward == 1: totalreward += reward iters += 1 else: print("Invalid PlayerAI Move") self.over = True else: print("Invalid PlayerAI Move - 1") self.over = True else: ##print("Computer's turn:") move = self.computerAI.getMove(gridCopy) # Validate Move if move and self.grid.canInsert(move): self.grid.setCellValue(move, self.getNewTileValue()) else: print("Invalid Computer AI Move") self.over = True #if not self.over: #self.displayer.display(self.grid) # Exceeding the Time Allotted for Any Turn Terminates the Game # self.updateAlarm(time.clock()) turn = 1 - turn self.maxTile = self.grid.getMaxTile() print(maxTile) return maxTile def isGameOver(self): return not self.grid.canMove() def getNewTileValue(self): if randint(0,99) < 100 * self.probability: return self.possibleNewTiles[0] else: return self.possibleNewTiles[1]; def insertRandonTile(self): tileValue = self.getNewTileValue() cells = self.grid.getAvailableCells() cell = cells[randint(0, len(cells) - 1)] self.grid.setCellValue(cell, tileValue)
def make(self): self.grid = Grid(self.size) for i in range(self.init_tiles): self.insert_random_tile()
class GameManager: def __init__(self, size = 4): self.grid = Grid(size) self.possibleNewTiles = [2, 4] self.probability = defaultProbability self.initTiles = defaultInitialTiles self.computerAI = None self.playerAI = None self.displayer = None self.over = False def setComputerAI(self, computerAI): self.computerAI = computerAI def setPlayerAI(self, playerAI): self.playerAI = playerAI def setDisplayer(self, displayer): self.displayer = displayer def updateAlarm(self, currTime): if currTime - self.prevTime > timeLimit + allowance: self.over = True else: while time.clock() - self.prevTime < timeLimit + allowance: pass self.prevTime = time.clock() def start(self): for i in range(self.initTiles): self.insertRandonTile() #self.displayer.display(self.grid) # Player AI Goes First turn = PLAYER_TURN maxTile = 0 #self.prevTime = time.clock() while not self.isGameOver() and not self.over: # Copy to Ensure AI Cannot Change the Real Grid to Cheat gridCopy = self.grid.clone() move = None if turn == PLAYER_TURN: #print("Player's Turn:", end="") move = self.playerAI.getMove(gridCopy) #print(actionDic[move]) # Validate Move if move != None and move >= 0 and move < 4: if self.grid.canMove([move]): self.grid.move(move) # Update maxTile maxTile = self.grid.getMaxTile() else: #print("Invalid PlayerAI Move") self.over = True else: #print("Invalid PlayerAI Move - 1") self.over = True else: #print("Computer's turn:") move = self.computerAI.getMove(gridCopy) # Validate Move if move and self.grid.canInsert(move): self.grid.setCellValue(move, self.getNewTileValue()) else: #print("Invalid Computer AI Move") self.over = True #if not self.over: # self.displayer.display(self.grid) # Exceeding the Time Allotted for Any Turn Terminates the Game #self.updateAlarm(time.clock()) turn = 1 - turn print(maxTile) def isGameOver(self): return not self.grid.canMove() def getNewTileValue(self): if randint(0,99) < 100 * self.probability: return self.possibleNewTiles[0] else: return self.possibleNewTiles[1]; def insertRandonTile(self): tileValue = self.getNewTileValue() cells = self.grid.getAvailableCells() cell = cells[randint(0, len(cells) - 1)] self.grid.setCellValue(cell, tileValue)
def create_slowgrid_from_list(self, l, size=4) -> FastGrid: sut = Grid() sut.map = l sut.size = size return sut