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()
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)
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()
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 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 gym_2048(): def __init__(self, size=4): self.size = size self.grid = None self.possible_new_tiles = [2, 4] self.probability = default_probability self.init_tiles = default_initial_tiles self.over = False self.action_space = 4 self.reward = 0 self.max_tile = 0 self.score = 0 pass def make(self): self.grid = Grid(self.size) for i in range(self.init_tiles): self.insert_random_tile() def get_state(self): return self.grid.map def reset(self): self.make() self.score = 0 self.max_tile = 0 self.reward = 0 def get_new_tile_value(self): if randint(0, 99) < 100 * self.probability: return self.possible_new_tiles[0] else: return self.possible_new_tiles[1] def insert_random_tile(self): tile_value = self.get_new_tile_value() cells = self.grid.getAvailableCells() if len(cells) > 0: cell = cells[randint(0, len(cells) - 1)] self.grid.setCellValue(cell, tile_value) def close(self): self.grid = None def is_done(self): return not self.grid.canMove() def render(self, mode='human'): grid = self.grid if mode == "human": for i in range(grid.size): for j in range(grid.size): print("%6d " % grid.map[i][j], end="") print("") print("") # return self.get_state() def step(self, action): move = action # print(action_dict[move]) # Validate Move if move is not None and 0 <= move < 4: moved, merge_points = self.grid.move(move) self.score = merge_points # Update maxTile self.max_tile = self.grid.getMaxTile() if moved: self.insert_random_tile() self.calculate_reward() else: print("Invalid PlayerAI Move - 1") exit(0) return self.get_state(), self.reward, self.is_done(), [] def calculate_reward(self): # weighted_sum = self.calculate_weighted_sum() # penalty = self.calculate_penalty() # self.reward = weighted_sum - penalty self.reward = self.score def calculate_weighted_sum(self): score = 0 for x in range(4): for y in range(4): score += (priority[x][y] * self.grid.map[x][y] * self.grid.map[x][y]) return score def calculate_penalty(self): # Calculate clustering penalty. # We want two same valued tiles to be present next to each other # so that it is easier to merge. # This penalty becomes large when high valued tiles are scattered across # the grid, indicating that the grid is bad. def within_bounds(position): return 0 <= position['x'] < 4 and 0 <= position['y'] < 4 penalty = 0 # Direction vectors for up, down, left and right directions = ([-1, 0], [1, 0], [0, -1], [0, 1]) for x in range(4): for y in range(4): # if grid.map[x][y] != 0: for i in range(4): pos = { "x": x + directions[i][0], "y": y + directions[i][1] } if within_bounds(pos): neighbour = self.grid.map[pos['x']][pos['y']] # if neighbour!=0: penalty += math.fabs(neighbour - self.grid.map[x][y]) return penalty
def main(): player = PlayerAI() testGrid = Grid() displayer = Displayer() displayer.display(testGrid) print(player.findPairs(testGrid)) testGrid.setCellValue([0, 0], 3) displayer.display(testGrid) print(player.findPairs(testGrid)) testGrid.setCellValue([0, 3], 3) displayer.display(testGrid) print(player.findPairs(testGrid)) testGrid.setCellValue([2, 3], 3) displayer.display(testGrid) print(player.findPairs(testGrid)) testGrid.setCellValue([0, 1], 3) displayer.display(testGrid) print(player.findPairs(testGrid)) testGrid.setCellValue([0, 2], 3) displayer.display(testGrid) print(player.findPairs(testGrid)) testGrid.setCellValue([1, 1], 3) displayer.display(testGrid) print(player.findPairs(testGrid)) #main()
def test_can_create_grid_to_design(self): sut = Grid() self.assertIsNotNone(sut) self.assertEqual(4, sut.size) sut.setCellValue((0, 0), 2) self.assertEqual(sut.getCellValue((0, 0)), 2)
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 # Load the DNN model self.model_NN = load_model("all_2048_8000games.h5") # self.result_file = open("resultRandom.txt", "a") 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) # Using NN to make move instead list_proba = self.model_NN.predict( self.generateCurrentBoard1D(self.grid.map))[0].tolist() move = list_proba.index(max(list_proba)) # availableMoves = self.grid.getAvailableMoves() # move = availableMoves[randint(0, len(availableMoves)-1)] while not self.grid.canMove([move]): # print(list_proba) list_proba[move] = -1 move = list_proba.index(max(list_proba)) # randint(0,3) print(actionDic[move]) # Validate Move if move != None and move >= 0 and move < 4: if self.grid.canMove([move]): """TODO: This line to print out the current grid and how to move for the current state""" current_board_and_move = self.generateCurrentBoardAndMoveToText( self.grid.map, move) print(current_board_and_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 """ Comment this out if do not want to have the display """ 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) # self.result_file.write(str(maxTile)+"\n") # self.result_file.close() 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 generateCurrentBoardAndMoveToText(self, map, move): """ Generate the current board situation and the AI's move decision for that situation into text to export to .csv :param map: current board situation :param move: :return: """ current_board_and_move = "" for row in map: for cell in row: current_board_and_move += str(cell) + "," current_board_and_move += str(move) + "\n" return current_board_and_move def generateCurrentBoard1D(self, map): currentBoard = [] for row in map: for cell in row: currentBoard.append(cell) return np.array([currentBoard])
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)