Пример #1
0
class HanabiGame:
    def __init__(self, players, seed, variant):
        self.players = prep_players(players)
        self.table = HanabiTable(len(players), seed, variant)
        self.variant = variant
        self.current_player = 0

    def play_game(self):
        def pretty_print_info(info):
            LOGGER.debug('Player %s sees:', self.current_player)
            LOGGER.debug('Players: %s', info.num_players)
            LOGGER.debug('Cards in deck: %s', info.deck_size)
            LOGGER.debug('Discarded: %s', info.discarded)
            LOGGER.debug('Score: %s', info.score)
            LOGGER.debug('Progress: %s', info.scored_cards)
            LOGGER.debug('Sees: %s', info.hands)
            LOGGER.debug('Knows: %s', info.known_info)
            LOGGER.debug('Disclosures left: %s', info.disclosures)
            LOGGER.debug('Mistakes left: %s', info.mistakes_left)

        player_details = 'Game with {players}'.format(
            players=[player.__class__.__name__ for player in self.players])
        LOGGER.info(player_details)

        while not self.table.is_game_over():
            player = self.players[self.current_player]
            info = self.table.info_for_player(self.current_player)
            player_move = player.do_turn(self.current_player, info)
            if player_move.is_valid(info):
                player_move.execute(self.table)
                pretty_print_info(info)
                LOGGER.debug(str(player_move))
                self.current_player = (self.current_player +
                                       1) % self.table.num_players
            else:
                self.disqualify(player_move)
        for move in self.game_history():
            LOGGER.debug(move)
        LOGGER.info('Final score: %s', self.table.score())

    def game_history(self):
        return [str(action) for action in self.table.history]

    def disqualify(self, player_move):
        LOGGER.warning('Expected format for play card:')
        LOGGER.warning('{"play_type":"play", "card":<number>}')

        LOGGER.warning('Expected format for discard card:')
        LOGGER.warning('{"play_type":"discard", "card":<number>}')

        LOGGER.warning('Expected format for disclose color:')
        LOGGER.warning(
            '{"play_type":"disclose", "disclose_type":"color, "color":<color>}'
        )
        LOGGER.warning('"color" cannot be "*" in a Variant 3 game')

        LOGGER.warning('Expected format for disclose rank:')
        LOGGER.warning(
            '{"play_type":"disclose", "disclose_type":"rank, "rank":<number>}')
        LOGGER.error('Received invalid move from player %s: %s',
                     self.current_player, player_move)
        raise InvalidHanabiMoveException('Received invalid move from player',
                                         self.current_player)
Пример #2
0
 def __init__(self, players, seed, variant):
     self.players = prep_players(players)
     self.table = HanabiTable(len(players), seed, variant)
     self.variant = variant
     self.current_player = 0
Пример #3
0
class HanabiTableVariant2Tests(unittest.TestCase):
    def setUp(self):
        self.table = HanabiTable(2, 6, HanabiVariant.sixth_suit_hard)

    def test_play_correct_rainbow(self):
        self.table.play_card(0, 2)
        for _ in range(0, 44):
            self.table.discard_card(1, 0)
        self.table.play_card(1, 4)
        self.assertEqual(2, self.table.score())

    def test_play_incorrect_rainbow(self):
        self.table.play_card(0, 2)
        self.table.play_card(0, 4)
        self.assertEqual(1, self.table.score())
        self.assertEqual(2, self.table.mistakes_left)
        self.assertTrue(
            HanabiCard(HanabiColor.RAINBOW, 2) in
            self.table.discard.discarded())

    def test_table_disclose_color(self):
        self.assertEqual(["??", "??", "??", "??", "??"],
                         self.table.info_for_player(0).hands[0])
        self.table.disclose_color(0, 0, HanabiColor.RED)
        self.assertEqual(["R?", "??", "??", "??", "??"],
                         self.table.info_for_player(0).hands[0])

    def test_table_info_for_player(self):
        info = self.table.info_for_player(1)
        self.assertEqual(info.deck_size, 45)
Пример #4
0
 def setUp(self):
     self.table = HanabiTable(2, 6, HanabiVariant.sixth_suit_hard)
Пример #5
0
 def setUp(self):
     self.table = HanabiTable(2, 9, HanabiVariant.rainbow_wild)
Пример #6
0
class HanabiTableVariant3Tests(unittest.TestCase):
    def setUp(self):
        self.table = HanabiTable(2, 9, HanabiVariant.rainbow_wild)

    def test_play_correct_rainbow(self):
        for _ in range(0, 5):
            self.table.discard_card(0, 0)
        self.table.play_card(0, 2)
        self.assertEqual(1, self.table.score())
        self.assertEqual(1, self.table.info_for_player(0).scored_cards["*"])

    def test_play_incorrect_rainbow(self):
        self.table.play_card(0, 2)
        self.table.play_card(1, 4)
        self.assertEqual(1, self.table.score())
        self.assertEqual(1, self.table.info_for_player(0).scored_cards["W"])
        self.assertEqual(2, self.table.mistakes_left)

    def test_table_disclose_color(self):
        self.table.disclose_color(0, 1, HanabiColor.WHITE)
        self.assertEqual(["W?", "W?", "??", "??", "W?"],
                         self.table.info_for_player(1).hands[1])
        self.table.disclose_color(0, 1, HanabiColor.RED)
        self.assertEqual(["*?", "W?", "??", "R?", "*?"],
                         self.table.info_for_player(1).hands[1])

    def test_cannot_disclose_rainbow(self):
        self.assertFalse(self.table.can_disclose_color(HanabiColor.RAINBOW))
        self.assertTrue(self.table.can_disclose_color(HanabiColor.RED))
Пример #7
0
 def setUp(self):
     self.table = HanabiTable(2, 1, HanabiVariant.basic)
Пример #8
0
class HanabiTableTests(unittest.TestCase):
    def setUp(self):
        self.table = HanabiTable(2, 1, HanabiVariant.basic)

    def test_table_play_card(self):
        self.assertFalse(self.table.is_game_over())
        self.assertEqual(len(self.table.deck), 40)
        self.table.play_card(0, 0)
        self.assertFalse(self.table.is_game_over())
        self.assertEqual(len(self.table.deck), 39)

    def test_table_discard_card(self):
        self.assertFalse(self.table.is_game_over())
        self.assertEqual(len(self.table.deck), 40)
        self.assertEqual(len(self.table.discard), 0)
        self.table.discard_card(0, 0)
        self.assertFalse(self.table.is_game_over())
        self.assertEqual(len(self.table.deck), 39)
        self.assertEqual(len(self.table.discard), 1)

    def test_table_disclose_color(self):
        self.assertEqual(["??", "??", "??", "??", "??"], self.table.info_for_player(0).hands[0])
        self.table.disclose_color(0, 0, HanabiColor.RED)
        self.assertEqual(["R?", "??", "R?", "??", "??"], self.table.info_for_player(0).hands[0])

    def test_table_disclose_rank(self):
        self.assertEqual(["??", "??", "??", "??", "??"], self.table.info_for_player(0).hands[0])
        self.table.disclose_rank(0, 0, 3)
        self.assertEqual(["??", "??", "??", "??", "?3"], self.table.info_for_player(0).hands[0])

    def test_table_game_over_mistakes(self):
        self.assertFalse(self.table.is_game_over())

        self.table.play_card(0, 1)
        self.assertFalse(self.table.is_game_over())
        self.assertEqual(self.table.mistakes_left, 2)

        self.table.play_card(1, 0)
        self.assertFalse(self.table.is_game_over())
        self.assertEqual(self.table.mistakes_left, 1)

        self.table.play_card(1, 0)
        self.assertTrue(self.table.is_game_over())
        self.assertEqual(self.table.mistakes_left, 0)

    def test_game_over_no_more_cards(self):
        self.assertFalse(self.table.is_game_over())
        for i in range(0, 42):
            self.assertEqual(len(self.table.discard), i)
            self.assertFalse(self.table.is_game_over())
            self.table.discard_card(0, 0)
        self.assertTrue(self.table.is_game_over())

    def test_game_over_and_won(self):
        self.table.play_card(1, 2)
        self.assertEqual(1, self.table.score())
        self.table.play_card(0, 0)
        self.assertEqual(2, self.table.score())
        self.table.play_card(0, 4)
        self.assertEqual(3, self.table.score())
        self.table.scored_cards[HanabiColor.RED] = 5
        self.table.scored_cards[HanabiColor.BLUE] = 5
        self.table.scored_cards[HanabiColor.GREEN] = 5
        self.table.scored_cards[HanabiColor.YELLOW] = 5
        self.table.scored_cards[HanabiColor.WHITE] = 5
        self.assertEqual(25, self.table.score())
        self.assertTrue(self.table.is_game_over())

    def test_table_str(self):
        self.assertEqual('Score: 0, '
                         'Cards remaining: 40, '
                         'Discarded: 0, '
                         'Disclosures left: 8, '
                         'Mistakes left: 3',
                         str(self.table))
        self.table.play_card(1, 0)
        self.assertEqual('Score: 0, '
                         'Cards remaining: 39, '
                         'Discarded: 1, '
                         'Disclosures left: 8, '
                         'Mistakes left: 2',
                         str(self.table))
        self.table.disclose_color(0, 0, HanabiColor.RED)
        self.assertEqual('Score: 0, '
                         'Cards remaining: 39, '
                         'Discarded: 1, '
                         'Disclosures left: 7, '
                         'Mistakes left: 2',
                         str(self.table))
        self.table.discard_card(0, 0)
        self.assertEqual('Score: 0, '
                         'Cards remaining: 38, '
                         'Discarded: 2, '
                         'Disclosures left: 8, '
                         'Mistakes left: 2',
                         str(self.table))

    def test_table_info_for_player(self):
        info = self.table.info_for_player(0)
        self.assertEqual(info.score, 0)
        self.assertEqual(info.deck_size, 40)
        self.assertEqual(len(info.discarded), 0)
        self.assertEqual(info.disclosures, 8)
        self.assertEqual(info.mistakes_left, 3)
        self.assertEqual(info.num_players, 2)
        self.assertEqual(info.hands[0], ["??", "??", "??", "??", "??"])
        self.assertEqual(info.hands[1], ["W4", "Y5", "B1", "G5", "W1"])
        self.assertEqual(info.known_info[0], ["??", "??", "??", "??", "??"])
        self.assertEqual(info.known_info[1], ["??", "??", "??", "??", "??"])
        self.assertEqual(info.scored_cards["R"], 0)
        self.assertEqual(info.scored_cards["B"], 0)
        self.assertEqual(info.scored_cards["G"], 0)
        self.assertEqual(info.scored_cards["Y"], 0)
        self.assertEqual(info.scored_cards["W"], 0)
        self.assertTrue("*" not in info.scored_cards)

    def test_table_score(self):
        self.assertEqual(0, self.table.score())

    def test_play_5_get_disclosure(self):
        self.play_to_white_5()
        self.table.disclose_rank(0, 0, 0)
        self.assertEqual(7, self.table.disclosures)
        self.table.play_card(0, 0)
        self.assertEqual(8, self.table.disclosures)

    def test_play_5_no_extra_disclosure(self):
        self.play_to_white_5()
        self.assertEqual(8, self.table.disclosures)
        self.table.play_card(0, 0)
        self.assertEqual(8, self.table.disclosures)

    def play_to_white_5(self):
        self.table.play_card(0, 3)
        for _ in range(0, 5):
            self.table.discard_card(0, 0)
        self.table.play_card(0, 4)
        for _ in range(0, 3):
            self.table.discard_card(0, 0)
        self.table.play_card(0, 1)
        self.table.play_card(1, 0)
Пример #9
0
class HanabiTableVariant1Tests(unittest.TestCase):
    def setUp(self):
        self.table = HanabiTable(2, 1, HanabiVariant.sixth_suit)

    def test_play_correct_rainbow(self):
        for _ in range(0, 15):
            self.table.discard_card(0, 0)
        self.table.play_card(0, 0)
        self.assertEqual(1, self.table.score())

    def test_play_incorrect_rainbow(self):
        for _ in range(0, 5):
            self.table.discard_card(0, 4)
        self.table.play_card(0, 4)
        self.table.play_card(1, 1)
        self.table.play_card(0, 2)
        self.table.play_card(1, 1)
        self.assertEqual(4, self.table.score())
        self.table.play_card(0, 1)
        self.assertEqual(4, self.table.score())
        self.assertEqual(2, self.table.mistakes_left)
        self.assertTrue(
            HanabiCard(HanabiColor.RAINBOW, 5) in
            self.table.discard.discarded())

    def test_table_disclose_color(self):
        self.assertEqual(["??", "??", "??", "??", "??"],
                         self.table.info_for_player(0).hands[0])
        self.table.disclose_color(0, 0, HanabiColor.RAINBOW)
        self.assertEqual(["??", "*?", "??", "??", "??"],
                         self.table.info_for_player(0).hands[0])

    def test_table_info_for_player(self):
        info = self.table.info_for_player(0)
        self.assertEqual(info.deck_size, 50)

    def test_can_disclose_color(self):
        self.assertTrue(self.table.can_disclose_color('R'))
        self.assertTrue(self.table.can_disclose_color('G'))
        self.assertTrue(self.table.can_disclose_color('B'))
        self.assertTrue(self.table.can_disclose_color('W'))
        self.assertTrue(self.table.can_disclose_color('Y'))
        self.assertTrue(self.table.can_disclose_color('*'))
        self.assertFalse(self.table.can_disclose_color('A'))

    def test_table_with_rainbow_deck(self):
        self.table.play_card(0, 3)
        self.assertEqual(1, self.table.score())
        for _ in range(0, 11):
            self.table.discard_card(0, 0)
        self.table.play_card(0, 4)
        self.table.play_card(0, 3)
        self.assertEqual(2, self.table.score())
        self.assertEqual(12, len(self.table.discard))
        self.assertEqual(1, self.table.info_for_player(0).scored_cards["*"])