def __init__(self, rollout_len=100, all_moves=False, levels=None, random_state=None): self.rollout_len = rollout_len self.random_state = random_state self.all_moves = all_moves self.levels = levels or Match3Levels(LEVELS) self.h = self.levels.h self.w = self.levels.w self.n_shapes = self.levels.n_shapes self.__episode_counter = 0 self.__game = Game( rows=self.h, columns=self.w, n_shapes=self.n_shapes, length=3, all_moves=all_moves, random_state=self.random_state) self.reset() self.renderer = Renderer(self.n_shapes) # setting observation space self.observation_space = spaces.Box( low=0, high=self.n_shapes, shape=self.__game.board.board_size, dtype=int) # setting actions space self.__match3_actions = self.__get_available_actions() self.action_space = spaces.Discrete( len(self.__match3_actions))
def setUp(self): self.game = Game(rows=3, columns=3, n_shapes=(3 * 3), length=3, random_state=1) board = np.array([[7, 1, 7], [1, 4, 6], [7, 1, 7]]) self.game.board.set_board(board)
def __init__(self, immovable_move, n_of_match_counts_immov, match_counts_add_immovable, number_of_match_counts_add_immovable, step_add_immovable, number_of_step_add_immovable, no_legal_actions_do, immovable_shape=-1, rollout_len=-1, all_moves=False, levels=None, random_state=None): self.no_legal_actions_do = no_legal_actions_do self.rollout_len = rollout_len self.random_state = random_state self.all_moves = all_moves self.levels = levels or Match3Levels(LEVELS) self.h = self.levels.h self.w = self.levels.w self.n_shapes = self.levels.n_shapes self.__episode_counter = 0 self.__game = Game(rows=self.h, columns=self.w, n_shapes=self.n_shapes, length=3, immovable_move=immovable_move, n_of_match_counts_immov=n_of_match_counts_immov, match_counts_add_immovable=match_counts_add_immovable, number_of_match_counts_add_immovable=number_of_match_counts_add_immovable, step_add_immovable=step_add_immovable, number_of_step_add_immovable=number_of_step_add_immovable, no_legal_actions_do=no_legal_actions_do, all_moves=all_moves, immovable_shape=immovable_shape, random_state=self.random_state) self.reset() self.renderer = Renderer(self.n_shapes) # setting observation space self.observation_space = spaces.Box( low=0, high=self.n_shapes, shape=self.__game.board.board_size, dtype=int) # setting actions space self.__match3_actions = self.get_available_actions() self.action_space = spaces.Discrete( len(self.__match3_actions))
class TestGame(unittest.TestCase): def setUp(self): self.game = Game(rows=3, columns=3, n_shapes=(3 * 3), length=3, random_state=1) board = np.array([[7, 1, 7], [1, 4, 6], [7, 1, 7]]) self.game.board.set_board(board) def test_bad_swap(self): old_board = self.game.board.board.copy() answer = self.game.swap(Point(0, 0), Point(0, 1)) with self.subTest(returns_zero=True): self.assertTrue(answer == 0) with self.subTest(same_board=True): self.assertEqual(old_board.tolist(), self.game.board.board.tolist())
class Match3Env(gym.Env): metadata = {'render.modes': None} def __init__(self, rollout_len=100, all_moves=False, levels=None, random_state=None): self.rollout_len = rollout_len self.random_state = random_state self.all_moves = all_moves self.levels = levels or Match3Levels(LEVELS) self.h = self.levels.h self.w = self.levels.w self.n_shapes = self.levels.n_shapes self.__episode_counter = 0 self.__game = Game( rows=self.h, columns=self.w, n_shapes=self.n_shapes, length=3, all_moves=all_moves, random_state=self.random_state) self.reset() self.renderer = Renderer(self.n_shapes) # setting observation space self.observation_space = spaces.Box( low=0, high=self.n_shapes, shape=self.__game.board.board_size, dtype=int) # setting actions space self.__match3_actions = self.__get_available_actions() self.action_space = spaces.Discrete( len(self.__match3_actions)) @staticmethod def __get_directions(board_ndim): """ get available directions for any number of dimensions """ directions = [ [[0 for _ in range(board_ndim)] for _ in range(2)] for _ in range(board_ndim) ] for ind in range(board_ndim): directions[ind][0][ind] = 1 directions[ind][1][ind] = -1 return directions def __points_generator(self): """ iterates over points on the board """ rows, cols = self.__game.board.board_size points = [Point(i, j) for i, j in product(range(rows), range(cols))] for point in points: yield point def __get_available_actions(self): """ calculate available actions for current board sizes """ actions = set() directions = self.__get_directions(board_ndim=BOARD_NDIM) for point in self.__points_generator(): for axis_dirs in directions: for dir_ in axis_dirs: dir_p = Point(*dir_) new_point = point + dir_p try: _ = self.__game.board[new_point] actions.add(frozenset((point, new_point))) except OutOfBoardError: continue return list(actions) def __get_action(self, ind): return self.__match3_actions[ind] def step(self, action): # make action m3_action = self.__get_action(action) reward = self.__swap(*m3_action) # change counter even action wasn't successful self.__episode_counter += 1 if self.__episode_counter >= self.rollout_len: episode_over = True self.__episode_counter = 0 ob = self.reset() else: episode_over = False ob = self.__get_board() return ob, reward, episode_over, {} def reset(self, *args, **kwargs): board = self.levels.sample() self.__game.start(board) return self.__get_board() def __swap(self, point1, point2): try: reward = self.__game.swap(point1, point2) except ImmovableShapeError: reward = 0 return reward def __get_board(self): return self.__game.board.board.copy() def render(self, mode='human', close=False): if close: warnings.warn("close=True isn't supported yet") self.renderer.render_board(self.__game.board)
class Match3Env(gym.Env): metadata = {'render.modes': None} def __init__(self, immovable_move, n_of_match_counts_immov, match_counts_add_immovable, number_of_match_counts_add_immovable, step_add_immovable, number_of_step_add_immovable, no_legal_actions_do, immovable_shape=-1, rollout_len=-1, all_moves=False, levels=None, random_state=None): self.no_legal_actions_do = no_legal_actions_do self.rollout_len = rollout_len self.random_state = random_state self.all_moves = all_moves self.levels = levels or Match3Levels(LEVELS) self.h = self.levels.h self.w = self.levels.w self.n_shapes = self.levels.n_shapes self.__episode_counter = 0 self.__game = Game(rows=self.h, columns=self.w, n_shapes=self.n_shapes, length=3, immovable_move=immovable_move, n_of_match_counts_immov=n_of_match_counts_immov, match_counts_add_immovable=match_counts_add_immovable, number_of_match_counts_add_immovable=number_of_match_counts_add_immovable, step_add_immovable=step_add_immovable, number_of_step_add_immovable=number_of_step_add_immovable, no_legal_actions_do=no_legal_actions_do, all_moves=all_moves, immovable_shape=immovable_shape, random_state=self.random_state) self.reset() self.renderer = Renderer(self.n_shapes) # setting observation space self.observation_space = spaces.Box( low=0, high=self.n_shapes, shape=self.__game.board.board_size, dtype=int) # setting actions space self.__match3_actions = self.get_available_actions() self.action_space = spaces.Discrete( len(self.__match3_actions)) @staticmethod def __get_directions(board_ndim): """ get available directions for any number of dimensions """ directions = [ [[0 for _ in range(board_ndim)] for _ in range(2)] for _ in range(board_ndim) ] for ind in range(board_ndim): directions[ind][0][ind] = 1 directions[ind][1][ind] = -1 return directions def __points_generator(self): """ iterates over points on the board """ rows, cols = self.__game.board.board_size points = [Point(i, j) for i, j in product(range(rows), range(cols))] for point in points: yield point def get_available_actions(self): """ calculate available actions for current board sizes """ actions = [] directions = [[1, 0], [0, 1]] for dir_ in directions: for point in self.__points_generator(): dir_p = Point(*dir_) new_point = point + dir_p try: _ = self.__game.board[new_point] actions.append((point, new_point)) except OutOfBoardError: continue return actions def get_validate_actions(self): possible = self.__game.get_all_possible_moves() validate_actions = [] for point, direction in possible: newpoint = point + Point(*direction) validate_actions.append((newpoint, point)) return validate_actions def __get_action(self, ind): return self.__match3_actions[ind] def step(self, action): # make action m3_action = self.__get_action(action) reward = self.__swap(*m3_action) ob = self.__get_board() # change counter even action wasn't successful self.__episode_counter += 1 if self.rollout_len > 0 and self.__episode_counter >= self.rollout_len: episode_over = True elif self.no_legal_actions_do == "terminal" and len(self.__game.get_all_possible_moves(False)) == 0: episode_over = True else: episode_over = False return ob, reward, episode_over, {} def simulation_step(self, action): m3_action = self.__get_action(action) reward = self.__game.simulation_swap(*m3_action) return reward def reset(self, *args, **kwargs): self.__episode_counter = 0 board = self.levels.sample() self.__game.start(board) return self.__get_board() def __swap(self, point1, point2): try: reward = self.__game.swap(point1, point2) except ImmovableShapeError: reward = 0 return reward def __get_board(self): return self.__game.board.board.copy() def render(self, mode='human', close=False): if close: warnings.warn("close=True isn't supported yet") self.renderer.render_board(self.__game.board)
def __init__(self, step_add_immovable, number_of_step_add_immovable, match_counts_add_immovable, number_of_match_counts_add_immovable, immovable_move_, n_of_match_counts_immov, train_or_test, no_legal_shuffle_or_new_, rollout_len=100, all_moves=True, levels=None, random_state=None): self.step_add_immovable = step_add_immovable self.number_of_step_add_immovable = number_of_step_add_immovable self.match_counts_add_immovable = match_counts_add_immovable self.number_of_match_counts_add_immovable = number_of_match_counts_add_immovable self.train_or_test = train_or_test self.rollout_len = rollout_len self.immovable_move = immovable_move_ self.n_of_match_counts_immov = n_of_match_counts_immov self.no_legal_shuffle_or_new = no_legal_shuffle_or_new_ self.random_state = random_state self.all_moves = all_moves self.levels = levels or Match3Levels(LEVELS) self.h = self.levels.h self.w = self.levels.w self.n_shapes = self.levels.n_shapes self.episode_counter = 0 self.possible_move = random_state self.game = Game( rows=self.h, columns=self.w, n_shapes=self.n_shapes, length=3, all_moves=all_moves, random_state=self.random_state, no_legal_shuffle_or_new=self.no_legal_shuffle_or_new, number_of_match_counts_add_immovable=self. number_of_match_counts_add_immovable, train_or_test=self.train_or_test, filler=Filler( immovable_move=self.immovable_move, n_of_match_counts_immov=self.n_of_match_counts_immov, number_of_match_counts_add_immovable=self. number_of_match_counts_add_immovable, match_counts_add_immovable=self.match_counts_add_immovable)) self.reset()[np.newaxis, :] self.renderer = Renderer(self.levels.h, self.levels.w, self.n_shapes) # setting observation space self.observation_space = spaces.Box(low=0, high=self.n_shapes, shape=(1, self.h, self.w), dtype=int) # setting actions space self.__match3_actions = self.get_available_actions() self.action_space = spaces.Discrete(len(self.__match3_actions))
class Match3Env(gym.Env): metadata = {'render.modes': ['human', 'rgb_array']} def __init__(self, step_add_immovable, number_of_step_add_immovable, match_counts_add_immovable, number_of_match_counts_add_immovable, immovable_move_, n_of_match_counts_immov, train_or_test, no_legal_shuffle_or_new_, rollout_len=100, all_moves=True, levels=None, random_state=None): self.step_add_immovable = step_add_immovable self.number_of_step_add_immovable = number_of_step_add_immovable self.match_counts_add_immovable = match_counts_add_immovable self.number_of_match_counts_add_immovable = number_of_match_counts_add_immovable self.train_or_test = train_or_test self.rollout_len = rollout_len self.immovable_move = immovable_move_ self.n_of_match_counts_immov = n_of_match_counts_immov self.no_legal_shuffle_or_new = no_legal_shuffle_or_new_ self.random_state = random_state self.all_moves = all_moves self.levels = levels or Match3Levels(LEVELS) self.h = self.levels.h self.w = self.levels.w self.n_shapes = self.levels.n_shapes self.episode_counter = 0 self.possible_move = random_state self.game = Game( rows=self.h, columns=self.w, n_shapes=self.n_shapes, length=3, all_moves=all_moves, random_state=self.random_state, no_legal_shuffle_or_new=self.no_legal_shuffle_or_new, number_of_match_counts_add_immovable=self. number_of_match_counts_add_immovable, train_or_test=self.train_or_test, filler=Filler( immovable_move=self.immovable_move, n_of_match_counts_immov=self.n_of_match_counts_immov, number_of_match_counts_add_immovable=self. number_of_match_counts_add_immovable, match_counts_add_immovable=self.match_counts_add_immovable)) self.reset()[np.newaxis, :] self.renderer = Renderer(self.levels.h, self.levels.w, self.n_shapes) # setting observation space self.observation_space = spaces.Box(low=0, high=self.n_shapes, shape=(1, self.h, self.w), dtype=int) # setting actions space self.__match3_actions = self.get_available_actions() self.action_space = spaces.Discrete(len(self.__match3_actions)) @staticmethod def get_directions(board_ndim): """ get available directions for any number of dimensions """ directions = [[[0 for _ in range(board_ndim)] for _ in range(2)] for _ in range(board_ndim)] for ind in range(board_ndim): directions[ind][0][ind] = 1 directions[ind][1][ind] = -1 return directions def points_generator(self): """ iterates over points on the board """ rows, cols = self.game.board.board_size points = [Point(i, j) for i, j in product(range(rows), range(cols))] for point in points: yield point def get_available_actions(self): """ calculate available actions for current board sizes """ actions = [] direction = [[1, 0], [0, 1]] for dir_ in direction: for point in self.points_generator(): dir_p = Point(*dir_) new_point = point + dir_p try: _ = self.game.board[new_point] actions.append((point, new_point)) except OutOfBoardError: continue return actions def get_validate_actions(self): possible = self.game.get_possible_moves() validate_actions = [] for point, direction in possible: newpoint = point + Point(*direction) validate_actions.append((newpoint, point)) return list(validate_actions) def get_action(self, ind): return self.__match3_actions[ind] def reset(self, *args, **kwargs): board = self.levels.sample() self.game.start(board) return self.get_board()[np.newaxis, :] def swap(self, point1, point2): try: reward = self.game.swap(point1, point2) except ImmovableShapeError: reward = 0 return reward def get_board(self): return self.game.board.board.copy() def render(self, mode='human'): if mode == 'human': return self.renderer.render_board(self.game.board.board) else: super(Match3Env, self).render(mode=mode) # just raise an exception def step(self, action): self.episode_counter += 1 m3_action = self.get_action(action) reward = self.swap(*m3_action) ob = self.get_board()[np.newaxis, :] self.possible_move = self.get_validate_actions() self.game.filler.immovable = False #self.match_counts_immovable() self.step_immovable() if self.train_or_test == 'train': if len(self.possible_move) == 0: episode_over = True self.episode_counter = 0 self.game.filler.immovable = False else: episode_over = False return ob, reward, episode_over, {} elif self.train_or_test == 'test': if self.episode_counter >= self.rollout_len: episode_over = True self.episode_counter = 0 self.game.filler.immovable = False else: episode_over = False return ob, reward, episode_over, {} def match_counts_immovable(self): if self.match_counts_add_immovable: if self.game.matchs_counter > self.number_of_match_counts_add_immovable: #self.generate_immovable(self.number_of_match_counts_immovable_add, Fall = parser.getboolean('gym_environment','immovable_Fall'),temp_counter = self.h ,temp_counter2 = 0) self.game.filler.immovable = True self.game.matchs_counter = 0 else: self.game.filler.immovable = False def step_immovable(self): if self.step_add_immovable: if self.episode_counter % self.number_of_step_add_immovable == 0: self.game.filler.immovable = True else: self.game.filler.immovable = False