def test_add_random_tile(self): tab = np.array( [[0,0,0,0], [0,0,0,0], [0,0,0,0], [0,0,0,0]] ) grid = GameGrid(0, 0, tab) grid.add_random_tile() self.assertTrue(grid.matrix.sum() > 0) tab = np.array( [[2,2,2,2], [2,2,2,2], [2,2,2,2], [2,2,2,2]] ) grid = GameGrid(0, 0, tab) grid.add_random_tile() self.assertTrue(array2DEquals(tab, grid.matrix)) tab = np.array( [[1,1,1,1], [1,1,1,1], [1,1,1,1], [1,1,1,1]] ) for row in range(4): for column in range(4): grid = GameGrid(0, 0, tab) grid.matrix[row, column] = 0 grid.add_random_tile() self.assertTrue(grid.matrix.sum() > 15)
def GetMove(self, current_grid : GameGrid2048): available_moves = [move for move in self._moves_list if current_grid.canMove(move)] self._logger.debug('Available moves : %s', available_moves) if len(available_moves) == 1: return available_moves[0] # Don't waste time running AI if len(available_moves) == 0: return self._moves_list[0] # whatever, it wont't move ! if (self.epsilon > 0) and (random.uniform(0, 1) < self.epsilon): # self._logger.debug("Randomly choose move") return random.choice(available_moves) current_state = self.qval_container.get_state(current_grid.matrix) current_q_val = self.qval_container.get_qvals(current_state)[available_moves] max_val = current_q_val.max() optimal_moves = current_q_val[current_q_val == max_val].index.tolist() # if not(self.file_history is None): # nb_cell = current_grid.matrix.shape[0] * current_grid.matrix.shape[1] # line = '|'.join(map(str, current_grid.matrix.reshape(nb_cell))) # for move in optimal_moves: # self.file_history.write(line + '|' + move + '\n') if len(optimal_moves) == 0: # shouldn't happen raise Exception("No optimal move in Get move function") elif len(optimal_moves) == 1: return optimal_moves[0] else: return random.choice(optimal_moves)
def init_end_states(self): self._logger.debug("Start init end states") for grid in GameGrid2048.get_final_states(): grid.to_min_state() state = self.qval_container.get_state(grid.matrix) self.qval_container.set_qvals(state, [REWARD_END_GAME] * 4) self._logger.debug("Init end states done")
def test_is_full(self): tab = np.array( [[0,0,0,0], [0,0,0,0], [0,0,0,0], [0,0,0,0]] ) grid = GameGrid(0,0,tab) self.assertFalse(grid.is_full()) tab = np.array( [[2,2,2,2], [2,2,2,2], [2,2,2,2], [2,2,2,2]] ) grid = GameGrid(0,0,tab) self.assertTrue(grid.is_full()) tab = np.array( [[2,4,2,4], [2,4,2,4], [2,4,2,4], [2,4,2,4]] ) grid = GameGrid(0,0,tab) self.assertTrue(grid.is_full()) tab = np.array( [[1,1,3,4], [5,6,7,8], [1,2,3,4], [5,6,7,8]] ) grid = GameGrid(0, 0, tab) self.assertTrue(grid.is_full()) for row in range(4): for col in range(4): loc_tab = np.array(tab) loc_tab[row, col] = 0 grid = GameGrid(0, 0, loc_tab) self.assertFalse(grid.is_full(), "Error at ({0}, {1})\n{2}".format(row, col, grid.matrix))
def get_state_to_min_state(self): state_mapping = np.zeros(self.nb_states) - 1 for grid in GameGrid2048.get_all_states(): current_state = self.get_state(grid.matrix) if state_mapping[current_state] >= 0: continue eq_states = self.get_state_equivalence(grid, current_state) min_state = min(eq_states) for s in eq_states: state_mapping[s] = min_state return state_mapping
def test_MoveRight(self): tab = np.array( [[2,2,0,0], [2,0,2,0], [2,0,0,2], [0,2,0,2]] ) target = np.array( [[0,0,0,3], [0,0,0,3], [0,0,0,3], [0,0,0,3]] ) grid = GameGrid(0, 0, tab) score, has_moved = grid.moveRight() self.assertTrue(array2DEquals(grid.matrix, target), str(grid.matrix) + "\n" + str(target)) self.assertTrue(has_moved) self.assertEqual(32, score) tab = np.array( [[2,2,0,2], [2,0,3,2], [0,2,0,3], [3,0,2,2]] ) target = np.array( [[0,0,2,3], [0,2,3,2], [0,0,2,3], [0,0,3,3]] ) grid = GameGrid(0, 0, tab) score, has_moved = grid.moveRight() self.assertTrue(array2DEquals(grid.matrix, target), str(grid.matrix) + "\n" + str(target)) self.assertTrue(has_moved) self.assertEqual(16, score)
def playGame(self): current_grid = GameGrid2048(nb_rows=constants.NB_ROWS, nb_columns=constants.NB_COLS) current_grid.to_min_state() current_state = current_grid.GetState() nb_iter = 0 is_game_over = False diff_update = 0 while not is_game_over: nb_iter += 1 self._logger.debug('') self._logger.debug("=" * 30) self._logger.debug("New loop") self._logger.debug("=" * 30) current_grid.print(logging.DEBUG) old_state = current_state move_dir = self._ai.GetMove(current_grid) current_grid.moveTo(move_dir) current_state = current_grid.GetState() self._logger.debug("Moving %s, from %d to %d", move_dir, old_state, current_state) current_grid.print(logging.DEBUG) current_grid.add_random_tile() current_grid.print(logging.DEBUG) current_state = current_grid.to_min_state().GetState() if current_grid.matrix.max() >= constants.GRID_MAX_VAL: # self._logger.info("Stop iterations, values too big for the model") is_game_over = True else: diff_update += self._ai.RecordState(old_state, current_state, move_dir) is_game_over = current_grid.is_game_over() return nb_iter, diff_update
def playGame(self): self.grid = GameGrid2048(nbRows=3, nbColumns=3) self.grid.add_random_tile() self.grid.add_random_tile() i = 0 nextMove = 'up' nb_itera_without_moving = 0 while nb_itera_without_moving == 0: i += 1 # Add history (grid and score) data self._scoreHistory.append(self.totalScore) self._gridHistory.append(self.grid.matrix) # self._actionHistory ? # Get next move : 'left', 'right', 'up' or 'down' nextMove = self._ai.move_next(self, self._gridHistory, self._scoreHistory) if len(nextMove) == 0: print("null direction") print(self.grid) nb_itera_without_moving += 1 continue score, has_moved = self.grid.moveTo(nextMove) self.grid.add_random_tile() score -= self.totalScore self.totalScore += score print("Move {0:<5}, add score {1:>5}, total score {2:>5}".format( nextMove, score, self.totalScore)) if not has_moved: print("did not moved") nb_itera_without_moving += 1 print(self.grid) print("Game over in {0} iterations, score = {1}".format( i + 1, self.totalScore))
def test_is_game_over_column(self): tab = np.array( [[1,5,1,5], [1,6,2,6], [3,7,3,7], [4,8,4,8]] ) grid = GameGrid(0, 0, tab) self.assertFalse(grid.is_game_over()) tab = np.array( [[1,5,1,5], [2,6,2,6], [2,7,3,7], [4,8,4,8]] ) grid = GameGrid(0, 0, tab) self.assertFalse(grid.is_game_over()) tab = np.array( [[1,5,1,5], [2,6,2,6], [3,7,3,7], [3,8,4,8]] ) grid = GameGrid(0, 0, tab) self.assertFalse(grid.is_game_over()) tab = np.array( [[1,5,1,5], [2,5,2,6], [3,7,3,7], [4,8,4,8]] ) grid = GameGrid(0, 0, tab) self.assertFalse(grid.is_game_over()) tab = np.array( [[1,5,1,5], [2,6,2,6], [3,6,3,7], [4,8,4,8]] ) grid = GameGrid(0, 0, tab) self.assertFalse(grid.is_game_over()) tab = np.array( [[1,5,1,5], [2,6,2,6], [3,7,3,7], [4,7,4,8]] ) grid = GameGrid(0, 0, tab) self.assertFalse(grid.is_game_over()) tab = np.array( [[1,5,1,5], [2,6,1,6], [3,7,3,7], [4,8,4,8]] ) grid = GameGrid(0, 0, tab) self.assertFalse(grid.is_game_over()) tab = np.array( [[1,5,1,5], [2,6,2,6], [3,7,2,7], [4,8,4,8]] ) grid = GameGrid(0, 0, tab) self.assertFalse(grid.is_game_over()) tab = np.array( [[1,5,1,5], [2,6,2,6], [3,7,3,7], [4,8,3,8]] ) grid = GameGrid(0, 0, tab) self.assertFalse(grid.is_game_over()) tab = np.array( [[1,5,1,5], [2,6,2,5], [3,7,3,7], [4,8,4,8]] ) grid = GameGrid(0, 0, tab) self.assertFalse(grid.is_game_over()) tab = np.array( [[1,5,1,5], [2,6,2,6], [3,7,3,6], [4,8,4,8]] ) grid = GameGrid(0, 0, tab) self.assertFalse(grid.is_game_over()) tab = np.array( [[1,5,1,5], [2,6,2,6], [3,7,3,7], [4,8,4,7]] ) grid = GameGrid(0, 0, tab) self.assertFalse(grid.is_game_over())
def test_is_game_over_lines(self): tab = np.array( [[0,0,0,0], [0,0,0,0], [0,0,0,0], [0,0,0,0]] ) grid = GameGrid(0, 0, tab) self.assertFalse(grid.is_game_over()) tab = np.array( [[2,2,2,2], [2,2,2,2], [2,2,2,2], [2,2,2,2]] ) grid = GameGrid(0, 0, tab) self.assertFalse(grid.is_game_over()) tab = np.array( [[1,2,1,2], [3,4,3,4], [1,2,1,2], [3,4,3,4]] ) grid = GameGrid(0, 0, tab) self.assertTrue(grid.is_game_over()) tab = np.array( [[1,1,3,4], [5,6,7,8], [1,2,3,4], [5,6,7,8]] ) grid = GameGrid(0, 0, tab) self.assertFalse(grid.is_game_over()) tab = np.array( [[1,2,2,4], [5,6,7,8], [1,2,3,4], [5,6,7,8]] ) grid = GameGrid(0, 0, tab) self.assertFalse(grid.is_game_over()) tab = np.array( [[1,2,3,3], [5,6,7,8], [1,2,3,4], [5,6,7,8]] ) grid = GameGrid(0, 0, tab) self.assertFalse(grid.is_game_over()) tab = np.array( [[1,2,3,4], [5,5,7,8], [1,2,3,4], [5,6,7,8]] ) grid = GameGrid(0, 0, tab) self.assertFalse(grid.is_game_over()) tab = np.array( [[1,2,3,4], [5,6,6,8], [1,2,3,4], [5,6,7,8]] ) grid = GameGrid(0, 0, tab) self.assertFalse(grid.is_game_over()) tab = np.array( [[1,2,3,4], [5,6,7,7], [1,2,3,4], [5,6,7,8]] ) grid = GameGrid(0, 0, tab) self.assertFalse(grid.is_game_over()) tab = np.array( [[1,2,3,4], [5,6,7,8], [1,1,3,4], [5,6,7,8]] ) grid = GameGrid(0, 0, tab) self.assertFalse(grid.is_game_over()) tab = np.array( [[1,2,3,4], [5,6,7,8], [1,2,2,4], [5,6,7,8]] ) grid = GameGrid(0, 0, tab) self.assertFalse(grid.is_game_over()) tab = np.array( [[1,2,3,4], [5,6,7,8], [1,2,3,3], [5,6,7,8]] ) grid = GameGrid(0, 0, tab) self.assertFalse(grid.is_game_over()) tab = np.array( [[1,2,3,4], [5,6,7,8], [1,2,3,4], [5,5,7,8]] ) grid = GameGrid(0, 0, tab) self.assertFalse(grid.is_game_over()) tab = np.array( [[1,2,3,4], [5,6,7,8], [1,2,3,4], [5,6,6,8]] ) grid = GameGrid(0, 0, tab) self.assertFalse(grid.is_game_over()) tab = np.array( [[1,2,3,4], [5,6,7,8], [1,2,3,4], [5,6,7,7]] ) grid = GameGrid(0, 0, tab) self.assertFalse(grid.is_game_over())
def test_canMoveLeft(self): # Set a number at the left of each column => can't move left tab = np.zeros([4,4]) for row in range(4): grid = GameGrid(matrix=tab) grid.matrix[row, 0] = 2 self.assertFalse(grid.canMoveLeft(), "Can move left ! \n" + str(grid.matrix)) # Set a number everywhere but at the left of each column => can move left tab = np.zeros([4,4]) for row in range(4): for column in range(1, 4): grid = GameGrid(matrix=tab) grid.matrix[row, column] = 2 self.assertTrue(grid.canMoveLeft()) # Set an empty tile everywhere but at the right of each column => can move left tab = np.array( [[1,2,3,4], [5,6,7,8], [1,2,3,4], [5,6,7,8]] ) grid = GameGrid(matrix=tab) self.assertFalse(grid.canMoveLeft()) for row in range(4): for column in range(0, 3): grid = GameGrid(matrix=tab) grid.matrix[row, column] = 0 self.assertTrue(grid.canMoveLeft()) tab = np.array( [[1,2,3,4], [5,6,7,8], [1,2,3,4], [5,6,7,8]] ) grid = GameGrid(matrix=tab) self.assertFalse(grid.canMoveLeft()) for row in range(4): for column in range(1, 4): grid = GameGrid(matrix=tab) grid.matrix[row, column] = grid.matrix[row, column-1] # copy cell from the one above self.assertTrue(grid.canMoveLeft(), "should move left\n" + str(grid.matrix)) # merge cells
def test_canMoveDown(self): # Set a number at the bottom of each column => can't move down tab = np.zeros([4,4]) for column in range(4): grid = GameGrid(matrix=tab) grid.matrix[3,column] = 2 self.assertFalse(grid.canMoveDown(), "Can move down \n" + str(grid.matrix)) # Set a number everywhere but at the bottom of each column => can move down tab = np.zeros([4,4]) for row in range(0, 3): for column in range(4): grid = GameGrid(matrix=tab) grid.matrix[row, column] = 2 self.assertTrue(grid.canMoveDown()) # Set an empty tile everywhere but at the top of each column => can move down tab = np.array( [[1,2,3,4], [5,6,7,8], [1,2,3,4], [5,6,7,8]] ) grid = GameGrid(matrix=tab) self.assertFalse(grid.canMoveDown()) for row in range(1, 4): for column in range(4): grid = GameGrid(matrix=tab) grid.matrix[row, column] = 0 self.assertTrue(grid.canMoveDown()) # Set 2 identical consecutive tile in a column => merge cells tab = np.array( [[1,2,3,4], [5,6,7,8], [1,2,3,4], [5,6,7,8]] ) grid = GameGrid(matrix=tab) self.assertFalse(grid.canMoveDown()) for row in range(1, 4): for column in range(4): grid = GameGrid(matrix=tab) grid.matrix[row, column] = grid.matrix[row -1, column] # copy cell from the one above self.assertTrue(grid.canMoveDown()) # merge cells
def test_canMergeUpDown(self): # Only one value, assert can't merge tab = np.array( [[0,0,0,0], [0,0,0,0], [0,0,0,0], [0,0,0,0]] ) for row in range(4): for column in range(4): grid = GameGrid(matrix=tab) grid.matrix[row, column] = 2 self.assertFalse(grid.canMergeUpDown(), "Can merge : \n" + str(grid.matrix)) tab = np.array( [[2,0,0,0], [2,0,0,0], [0,0,0,0], [0,0,0,0]] ) grid = GameGrid(matrix=tab) self.assertTrue(grid.canMergeUpDown()) tab = np.array( [[0,2,0,0], [0,2,0,0], [0,0,0,0], [0,0,0,0]] ) grid = GameGrid(matrix=tab) self.assertTrue(grid.canMergeUpDown()) tab = np.array( [[0,0,0,2], [0,0,0,2], [0,0,0,0], [0,0,0,0]] ) grid = GameGrid(matrix=tab) self.assertTrue(grid.canMergeUpDown()) tab = np.array( [[0,0,0,0], [0,0,0,0], [0,0,0,2], [0,0,0,2]] ) grid = GameGrid(matrix=tab) self.assertTrue(grid.canMergeUpDown()) tab = np.array( [[3,0,0,0], [2,0,0,0], [0,0,0,0], [0,0,0,0]] ) grid = GameGrid(matrix=tab) self.assertFalse(grid.canMergeUpDown()) tab = np.array( [[0,0,0,3], [2,3,0,0], [0,0,0,3], [0,0,0,4]] ) grid = GameGrid(matrix=tab) self.assertFalse(grid.canMergeUpDown())