Exemple #1
0
 def __init__(self,
              rule: Rule = Rule.YAHTZEE_FREE_CHOICE_JOKER,
              game_type: GameType = GameType.RETRY_ON_WRONG_ACTION,
              seed=None):
     self.pyhtzee = Pyhtzee(seed=seed)
     self.rule = rule
     self.game_type = game_type
     self.action_space = spaces.Discrete(44)
     self.observation_space = spaces.Tuple((
         spaces.Discrete(13),  # round
         spaces.Discrete(4),  # sub-round
         spaces.Box(low=1, high=6, shape=(1,), dtype=np.uint8),  # die 1
         spaces.Box(low=1, high=6, shape=(1,), dtype=np.uint8),  # die 2
         spaces.Box(low=1, high=6, shape=(1,), dtype=np.uint8),  # die 3
         spaces.Box(low=1, high=6, shape=(1,), dtype=np.uint8),  # die 4
         spaces.Box(low=1, high=6, shape=(1,), dtype=np.uint8),  # die 5
         spaces.Box(low=-1, high=5, shape=(1,), dtype=np.int16),  # aces
         spaces.Box(low=-1, high=10, shape=(1,), dtype=np.int16),  # twos
         spaces.Box(low=-1, high=15, shape=(1,), dtype=np.int16),  # threes
         spaces.Box(low=-1, high=20, shape=(1,), dtype=np.int16),  # fours
         spaces.Box(low=-1, high=25, shape=(1,), dtype=np.int16),  # fives
         spaces.Box(low=-1, high=30, shape=(1,), dtype=np.int16),  # sixes
         spaces.Box(low=-1, high=30, shape=(1,), dtype=np.int16),  # three of a kind
         spaces.Box(low=-1, high=30, shape=(1,), dtype=np.int16),  # four of a kind
         spaces.Box(low=-1, high=25, shape=(1,), dtype=np.int16),  # full house
         spaces.Box(low=-1, high=30, shape=(1,), dtype=np.int16),  # small straight
         spaces.Box(low=-1, high=40, shape=(1,), dtype=np.int16),  # large straight
         spaces.Box(low=-1, high=30, shape=(1,), dtype=np.int16),  # chance
         spaces.Box(low=-1, high=50, shape=(1,), dtype=np.int16),  # yahtzee
         spaces.Box(low=-1, high=35, shape=(1,), dtype=np.int16),  # upper bonus
         spaces.Box(low=-1, high=1200, shape=(1,), dtype=np.int16),  # yahtzee bonus
     ))
Exemple #2
0
    def test_possible_actions_yatzy(self):
        pyhtzee = Pyhtzee(rule=Rule.YATZY)
        initial_possible_actions = pyhtzee.get_possible_actions()
        actions = [
            category_to_action_map[Category.YAHTZEE],
            category_to_action_map[Category.ACES],
            category_to_action_map[Category.TWOS],
            category_to_action_map[Category.THREES],
            category_to_action_map[Category.FOURS],
            category_to_action_map[Category.FIVES],
            category_to_action_map[Category.SIXES],
            category_to_action_map[Category.ONE_PAIR],
            category_to_action_map[Category.TWO_PAIRS],
            category_to_action_map[Category.THREE_OF_A_KIND],
            category_to_action_map[Category.FOUR_OF_A_KIND],
            category_to_action_map[Category.FULL_HOUSE],
            category_to_action_map[Category.SMALL_STRAIGHT],
            category_to_action_map[Category.LARGE_STRAIGHT],
        ]

        expected_final_possible_actions = list(initial_possible_actions)
        for action in actions:
            pyhtzee.take_action(action)
            expected_final_possible_actions.remove(action)

        final_possible_actions = pyhtzee.get_possible_actions()
        self.assertListEqual(final_possible_actions, expected_final_possible_actions)
Exemple #3
0
 def test_rolling_of_dice(self):
     pyhtzee = Pyhtzee(seed=123)
     original_dice = tuple(pyhtzee.dice)
     # This is a bad test; it is perfectly possible to get the exact
     # same dice twice despite full reroll
     action = utils.dice_roll_to_action_map[(True, True, True, True, True)]
     pyhtzee.take_action(action)
     self.assertNotEqual(original_dice, tuple(pyhtzee.dice))
     # This test makes more sense; make sure first four dice aren't rerolled
     original_dice = tuple(pyhtzee.dice)
     action = utils.dice_roll_to_action_map[(False, False, False, False, True)]
     pyhtzee.take_action(action)
     self.assertEqual(original_dice[0], pyhtzee.dice[0])
     self.assertEqual(original_dice[1], pyhtzee.dice[1])
     self.assertEqual(original_dice[2], pyhtzee.dice[2])
     self.assertEqual(original_dice[3], pyhtzee.dice[3])
Exemple #4
0
class YahtzeeSingleEnv(Env):
    metadata = {'render.modes': ['human']}

    def __init__(self,
                 rule: Rule = Rule.YAHTZEE_FREE_CHOICE_JOKER,
                 game_type: GameType = GameType.RETRY_ON_WRONG_ACTION,
                 seed=None):
        self.pyhtzee = Pyhtzee(seed=seed)
        self.rule = rule
        self.game_type = game_type
        self.action_space = spaces.Discrete(44)
        self.observation_space = spaces.Tuple((
            spaces.Discrete(13),  # round
            spaces.Discrete(4),  # sub-round
            spaces.Box(low=1, high=6, shape=(1,), dtype=np.uint8),  # die 1
            spaces.Box(low=1, high=6, shape=(1,), dtype=np.uint8),  # die 2
            spaces.Box(low=1, high=6, shape=(1,), dtype=np.uint8),  # die 3
            spaces.Box(low=1, high=6, shape=(1,), dtype=np.uint8),  # die 4
            spaces.Box(low=1, high=6, shape=(1,), dtype=np.uint8),  # die 5
            spaces.Box(low=-1, high=5, shape=(1,), dtype=np.int16),  # aces
            spaces.Box(low=-1, high=10, shape=(1,), dtype=np.int16),  # twos
            spaces.Box(low=-1, high=15, shape=(1,), dtype=np.int16),  # threes
            spaces.Box(low=-1, high=20, shape=(1,), dtype=np.int16),  # fours
            spaces.Box(low=-1, high=25, shape=(1,), dtype=np.int16),  # fives
            spaces.Box(low=-1, high=30, shape=(1,), dtype=np.int16),  # sixes
            spaces.Box(low=-1, high=30, shape=(1,), dtype=np.int16),  # three of a kind
            spaces.Box(low=-1, high=30, shape=(1,), dtype=np.int16),  # four of a kind
            spaces.Box(low=-1, high=25, shape=(1,), dtype=np.int16),  # full house
            spaces.Box(low=-1, high=30, shape=(1,), dtype=np.int16),  # small straight
            spaces.Box(low=-1, high=40, shape=(1,), dtype=np.int16),  # large straight
            spaces.Box(low=-1, high=30, shape=(1,), dtype=np.int16),  # chance
            spaces.Box(low=-1, high=50, shape=(1,), dtype=np.int16),  # yahtzee
            spaces.Box(low=-1, high=35, shape=(1,), dtype=np.int16),  # upper bonus
            spaces.Box(low=-1, high=1200, shape=(1,), dtype=np.int16),  # yahtzee bonus
        ))

    def get_observation_space(self):
        pyhtzee = self.pyhtzee
        return (
            pyhtzee.round,
            pyhtzee.sub_round,
            pyhtzee.dice[0],
            pyhtzee.dice[1],
            pyhtzee.dice[2],
            pyhtzee.dice[3],
            pyhtzee.dice[4],
            get_score(pyhtzee.scores.get(Category.ACES)),
            get_score(pyhtzee.scores.get(Category.TWOS)),
            get_score(pyhtzee.scores.get(Category.THREES)),
            get_score(pyhtzee.scores.get(Category.FOURS)),
            get_score(pyhtzee.scores.get(Category.FIVES)),
            get_score(pyhtzee.scores.get(Category.SIXES)),
            get_score(pyhtzee.scores.get(Category.THREE_OF_A_KIND)),
            get_score(pyhtzee.scores.get(Category.FOUR_OF_A_KIND)),
            get_score(pyhtzee.scores.get(Category.FULL_HOUSE)),
            get_score(pyhtzee.scores.get(Category.SMALL_STRAIGHT)),
            get_score(pyhtzee.scores.get(Category.LARGE_STRAIGHT)),
            get_score(pyhtzee.scores.get(Category.CHANCE)),
            get_score(pyhtzee.scores.get(Category.YAHTZEE)),
            get_score(pyhtzee.scores.get(Category.UPPER_SECTION_BONUS)),
            get_score(pyhtzee.scores.get(Category.YAHTZEE_BONUS)),
        )

    def sample_action(self):
        action = self.pyhtzee.sample_action()
        log.info(f'Sampled action: {action}')
        return action

    def step(self, action: int):
        pyhtzee = self.pyhtzee
        try:
            reward = pyhtzee.take_action(action)
            finished = pyhtzee.is_finished()
            valid_move = True
        except PyhtzeeException:
            valid_move = False
            reward = 0
            if self.game_type == GameType.SUDDEN_DEATH:
                log.info('Invalid action, terminating round.')
                finished = True
            else:  # retry on wrong action
                log.info('Invalid action, step ignored.')
                finished = False

        log.info(f'Finished step. Reward: {reward}, Finished: {finished}')
        debug_info = {
            'valid_move': valid_move,
        }
        return self.get_observation_space(), reward, finished, debug_info

    def reset(self):
        self.pyhtzee = Pyhtzee()

    def render(self, mode='human', close=False):
        dice = self.pyhtzee.dice
        outfile = sys.stdout
        outfile.write(f'Dice: {dice[0]} {dice[1]} {dice[2]} {dice[3]} {dice[4]} '
                      f'Round: {self.pyhtzee.round}.{self.pyhtzee.sub_round} '
                      f'Score: {self.pyhtzee.get_total_score()}\n')
Exemple #5
0
 def reset(self):
     self.pyhtzee = Pyhtzee()
Exemple #6
0
 def test_upper_section_bonus(self):
     pyhtzee = Pyhtzee()
     pyhtzee.dice = [1, 1, 1, 1, 1]
     pyhtzee.take_action(category_to_action_map[Category.ACES])
     pyhtzee.dice = [2, 2, 2, 2, 2]
     pyhtzee.take_action(category_to_action_map[Category.TWOS])
     pyhtzee.dice = [3, 3, 3, 3, 3]
     pyhtzee.take_action(category_to_action_map[Category.THREES])
     pyhtzee.dice = [4, 4, 4, 4, 4]
     pyhtzee.take_action(category_to_action_map[Category.FOURS])
     pyhtzee.dice = [5, 5, 5, 5, 5]
     pyhtzee.take_action(category_to_action_map[Category.FIVES])
     pyhtzee.dice = [6, 6, 6, 6, 6]
     action = category_to_action_map[Category.SIXES]
     reward = pyhtzee.take_action(action)
     self.assertEqual(reward, 65)
     self.assertEqual(pyhtzee.scores[Category.SIXES], 30)
     self.assertEqual(pyhtzee.scores[Category.UPPER_SECTION_BONUS], 35)
Exemple #7
0
 def test_dice_values(self):
     pyhtzee = Pyhtzee()
     for die in pyhtzee.dice:
         self.assertTrue(1 <= die <= 6)
Exemple #8
0
 def test_invalid_action(self):
     pyhtzee = Pyhtzee()
     action = dice_roll_to_action_map[(True, True, True, True, True)]
     pyhtzee.take_action(action)
     pyhtzee.take_action(action)
     self.assertRaises(PyhtzeeException, pyhtzee.take_action, action)
Exemple #9
0
 def test_perfect_yahztee_score_with_yatzy_rules(self):
     pyhtzee = Pyhtzee(rule=Rule.YATZY)
     pyhtzee.dice = [6, 6, 6, 6, 6]
     pyhtzee.take_action(category_to_action_map[Category.YAHTZEE])
     pyhtzee.dice = [1, 1, 1, 1, 1]
     pyhtzee.take_action(category_to_action_map[Category.ACES])
     pyhtzee.dice = [2, 2, 2, 2, 2]
     pyhtzee.take_action(category_to_action_map[Category.TWOS])
     pyhtzee.dice = [3, 3, 3, 3, 3]
     pyhtzee.take_action(category_to_action_map[Category.THREES])
     pyhtzee.dice = [4, 4, 4, 4, 4]
     pyhtzee.take_action(category_to_action_map[Category.FOURS])
     pyhtzee.dice = [5, 5, 5, 5, 5]
     pyhtzee.take_action(category_to_action_map[Category.FIVES])
     pyhtzee.dice = [6, 6, 6, 6, 6]
     pyhtzee.take_action(category_to_action_map[Category.SIXES])
     pyhtzee.dice = [6, 6, 6, 6, 6]
     pyhtzee.take_action(category_to_action_map[Category.THREE_OF_A_KIND])
     pyhtzee.dice = [6, 6, 6, 6, 6]
     pyhtzee.take_action(category_to_action_map[Category.FOUR_OF_A_KIND])
     pyhtzee.dice = [6, 6, 6, 5, 5]
     pyhtzee.take_action(category_to_action_map[Category.FULL_HOUSE])
     pyhtzee.dice = [6, 6, 6, 6, 6]
     pyhtzee.take_action(category_to_action_map[Category.SMALL_STRAIGHT])
     pyhtzee.dice = [6, 6, 6, 6, 6]
     pyhtzee.take_action(category_to_action_map[Category.LARGE_STRAIGHT])
     pyhtzee.dice = [6, 6, 6, 6, 6]
     pyhtzee.take_action(category_to_action_map[Category.CHANCE])
     self.assertEqual(pyhtzee.get_total_score(), 305)
     self.assertTrue(pyhtzee.is_finished())
Exemple #10
0
 def test_sample_action(self):
     pyhtzee = Pyhtzee()
     action = pyhtzee.sample_action()
     self.assertIn(action, pyhtzee.get_possible_actions())