Beispiel #1
0
    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))
Beispiel #2
0
 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)
Beispiel #3
0
    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))
Beispiel #4
0
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())
Beispiel #5
0
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)
Beispiel #6
0
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)
Beispiel #7
0
    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))
Beispiel #8
0
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