Exemplo n.º 1
0
                               ante_amount=0)
        players_info = {
            "uuid-1": {
                "name": "player1",
                "stack": 1000
            },
            #"uuid-2": { "name": "player2", "stack": 1000 },
            quuid: {
                "name": "q-learning",
                "stack": 1000
            }
        }
        initial_state = emulator.generate_initial_game_state(players_info)
        game_state, events = emulator.start_new_round(initial_state)

        game_finish_state, events = emulator.run_until_game_finish(game_state)
        qlearner_player.clear_stack()
        #[{'uuid': 'uuid-3', 'stack': 789}]
        win_ratio_dict = {"uuid-1": 0, "uuid-2": 0, "uuid-3": 0, quuid: 0}
        final_stack_dict = {"uuid-1": 0, "uuid-2": 0, "uuid-3": 0, quuid: 0}
        rounds_occ = 0
        for event in events:
            if (event['type'] == "event_round_finish"):
                rounds_occ += 1
                for winner in event['winners']:
                    win_ratio_dict[winner['uuid']] += 1
        for player in events[-1]['players']:
            final_stack_dict[player['uuid']] = player['stack']

        #df1=df1.append({'uuid' : "uuid-1" , 'win_ratio' : win_ratio_dict["uuid-1"]/(rounds_occ + 0.0), 'stack-diff' : j}, ignore_index=True)
        #df2=df2.append({'uuid' : "uuid-2" , 'win_ratio' : win_ratio_dict["uuid-2"]/(max_round + 0.0), 'stack_diff' : final_stack_dict['uuid-2']-1000}, ignore_index=True)
Exemplo n.º 2
0
class EmulatorTest(BaseUnitTest):
    def setUp(self):
        self.emu = Emulator()

    def test_set_game_rule(self):
        self.emu.set_game_rule(2, 8, 5, 3)
        self.eq(2, self.emu.game_rule['player_num'])
        self.eq(8, self.emu.game_rule['max_round'])
        self.eq(5, self.emu.game_rule['sb_amount'])
        self.eq(3, self.emu.game_rule['ante'])

    def test_register_and_fetch_player(self):
        p1, p2 = FoldMan(), FoldMan()
        self.emu.register_player('uuid-1', p1)
        self.emu.register_player('uuid-2', p2)
        self.eq(p1, self.emu.fetch_player('uuid-1'))
        self.eq(p2, self.emu.fetch_player('uuid-2'))

    @raises(TypeError)
    def test_register_invalid_player(self):
        self.emu.register_player('uuid', 'hoge')

    def test_blind_structure(self):
        game_state = restore_game_state(TwoPlayerSample.round_state)
        game_state = attach_hole_card_from_deck(game_state,
                                                'tojrbxmkuzrarnniosuhct')
        game_state = attach_hole_card_from_deck(game_state,
                                                'pwtwlmfciymjdoljkhagxa')
        self.emu.set_game_rule(2, 10, 5, 0)
        self.emu.set_blind_structure({5: {'ante': 5, 'small_blind': 60}})
        p1 = TestPlayer([('fold', 0), ('raise', 55), ('call', 0)])
        p2 = TestPlayer([('call', 15), ('call', 55), ('fold', 0)])
        self.emu.register_player('tojrbxmkuzrarnniosuhct', p1)
        self.emu.register_player('pwtwlmfciymjdoljkhagxa', p2)

        game_state, events = self.emu.run_until_round_finish(game_state)
        self.eq(65, game_state['table'].seats.players[0].stack)
        self.eq(135, game_state['table'].seats.players[1].stack)

        game_state, events = self.emu.start_new_round(game_state)
        game_state, events = self.emu.run_until_round_finish(game_state)
        self.eq(120, game_state['table'].seats.players[0].stack)
        self.eq(80, game_state['table'].seats.players[1].stack)

        game_state, events = self.emu.start_new_round(game_state)
        self.eq('event_game_finish', events[0]['type'])
        self.eq(0, game_state['table'].seats.players[0].stack)
        self.eq(80, game_state['table'].seats.players[1].stack)

    def test_blind_structure_update(self):
        self.emu.set_game_rule(2, 8, 5, 3)
        p1, p2 = FoldMan(), FoldMan()
        self.emu.register_player('uuid-1', p1)
        self.emu.register_player('uuid-2', p2)
        blind_structure = {
            3: {
                'ante': 5,
                'small_blind': 10
            },
            5: {
                'ante': 10,
                'small_blind': 20
            }
        }
        self.emu.set_blind_structure(blind_structure)
        players_info = {
            'uuid-1': {
                'name': 'hoge',
                'stack': 100
            },
            'uuid-2': {
                'name': 'fuga',
                'stack': 100
            }
        }
        state = self.emu.generate_initial_game_state(players_info)
        self.eq(5, state['small_blind_amount'])
        state, _ = self.emu.start_new_round(state)
        state, _ = self.emu.apply_action(state, 'fold')
        self.eq(5, state['small_blind_amount'])
        state, _ = self.emu.apply_action(state, 'fold')
        self.eq(5, state['small_blind_amount'])
        state, _ = self.emu.apply_action(state, 'fold')
        self.eq(10, state['small_blind_amount'])
        state, _ = self.emu.apply_action(state, 'fold')
        self.eq(10, state['small_blind_amount'])
        state, _ = self.emu.apply_action(state, 'fold')
        self.eq(20, state['small_blind_amount'])
        state, _ = self.emu.apply_action(state, 'fold')
        self.eq(20, state['small_blind_amount'])

    def test_apply_action(self):
        game_state = restore_game_state(TwoPlayerSample.round_state)
        game_state = attach_hole_card_from_deck(game_state,
                                                'tojrbxmkuzrarnniosuhct')
        game_state = attach_hole_card_from_deck(game_state,
                                                'pwtwlmfciymjdoljkhagxa')
        self.emu.set_game_rule(2, 10, 5, 0)
        p1, p2 = FoldMan(), FoldMan()
        self.emu.register_player('tojrbxmkuzrarnniosuhct', FoldMan())
        self.emu.register_player('pwtwlmfciymjdoljkhagxa', FoldMan())

        game_state, events = self.emu.apply_action(game_state, 'call', 15)
        self.eq(Const.Street.RIVER, game_state['street'])
        self.eq(
            TwoPlayerSample.p1_action_histories,
            game_state['table'].seats.players[0].round_action_histories[
                Const.Street.TURN])
        self.eq(2, len(events))
        self.eq('event_new_street', events[0]['type'])
        self.eq('event_ask_player', events[1]['type'])

        game_state, events = self.emu.apply_action(game_state, 'call', 0)
        self.eq(1, len(events))
        self.eq('event_ask_player', events[0]['type'])

        game_state, events = self.emu.apply_action(game_state, 'call', 0)
        self.eq(1, len(events))
        self.eq('event_round_finish', events[0]['type'])

    def test_apply_action_game_finish_detect(self):
        game_state = restore_game_state(TwoPlayerSample.round_state)
        game_state = attach_hole_card_from_deck(game_state,
                                                'tojrbxmkuzrarnniosuhct')
        game_state = attach_hole_card_from_deck(game_state,
                                                'pwtwlmfciymjdoljkhagxa')
        self.emu.set_game_rule(2, 3, 5, 0)
        p1, p2 = FoldMan(), FoldMan()
        self.emu.register_player('tojrbxmkuzrarnniosuhct', FoldMan())
        self.emu.register_player('pwtwlmfciymjdoljkhagxa', FoldMan())

        game_state, events = self.emu.apply_action(game_state, 'fold')
        self.eq('event_game_finish', events[-1]['type'])

    def test_apply_action_start_next_round(self):
        game_state = restore_game_state(TwoPlayerSample.round_state)
        game_state = attach_hole_card_from_deck(game_state,
                                                'tojrbxmkuzrarnniosuhct')
        game_state = attach_hole_card_from_deck(game_state,
                                                'pwtwlmfciymjdoljkhagxa')
        self.emu.set_game_rule(2, 4, 5, 0)
        p1, p2 = FoldMan(), FoldMan()
        self.emu.register_player('tojrbxmkuzrarnniosuhct', FoldMan())
        self.emu.register_player('pwtwlmfciymjdoljkhagxa', FoldMan())

        game_state, events = self.emu.apply_action(game_state, 'fold')
        self.eq(120, game_state['table'].seats.players[0].stack)
        self.eq(80, game_state['table'].seats.players[1].stack)

        game_state, events = self.emu.apply_action(game_state, 'raise', 20)
        self.eq('event_ask_player', events[-1]['type'])
        self.eq(100, game_state['table'].seats.players[0].stack)
        self.eq(70, game_state['table'].seats.players[1].stack)

    @raises(Exception)
    def test_apply_action_when_game_finished(self):
        game_state = restore_game_state(TwoPlayerSample.round_state)
        game_state = attach_hole_card_from_deck(game_state,
                                                'tojrbxmkuzrarnniosuhct')
        game_state = attach_hole_card_from_deck(game_state,
                                                'pwtwlmfciymjdoljkhagxa')
        self.emu.set_game_rule(2, 3, 5, 0)
        p1, p2 = FoldMan(), FoldMan()
        self.emu.register_player('tojrbxmkuzrarnniosuhct', FoldMan())
        self.emu.register_player('pwtwlmfciymjdoljkhagxa', FoldMan())

        game_state, events = self.emu.apply_action(game_state, 'fold')
        self.emu.apply_action(game_state, 'fold')

    def test_run_until_round_finish(self):
        game_state = restore_game_state(TwoPlayerSample.round_state)
        game_state = attach_hole_card_from_deck(game_state,
                                                'tojrbxmkuzrarnniosuhct')
        game_state = attach_hole_card_from_deck(game_state,
                                                'pwtwlmfciymjdoljkhagxa')
        self.emu.set_game_rule(2, 10, 5, 0)
        p1 = TestPlayer([('fold', 0)])
        p2 = TestPlayer([('call', 15)])
        self.emu.register_player('tojrbxmkuzrarnniosuhct', p1)
        self.emu.register_player('pwtwlmfciymjdoljkhagxa', p2)

        game_state, events = self.emu.run_until_round_finish(game_state)
        self.eq('event_new_street', events[0]['type'])
        self.eq('event_ask_player', events[1]['type'])
        self.eq('event_round_finish', events[2]['type'])

    def test_run_until_round_finish_when_already_finished(self):
        game_state = restore_game_state(TwoPlayerSample.round_state)
        game_state = attach_hole_card_from_deck(game_state,
                                                'tojrbxmkuzrarnniosuhct')
        game_state = attach_hole_card_from_deck(game_state,
                                                'pwtwlmfciymjdoljkhagxa')
        self.emu.set_game_rule(2, 10, 5, 0)
        p1 = TestPlayer([('fold', 0)])
        p2 = TestPlayer([('call', 15)])
        self.emu.register_player('tojrbxmkuzrarnniosuhct', p1)
        self.emu.register_player('pwtwlmfciymjdoljkhagxa', p2)
        game_state, events = self.emu.run_until_round_finish(game_state)
        game_state, events = self.emu.run_until_round_finish(game_state)
        self.eq(0, len(events))

    def test_run_until_round_finish_game_finish_detect(self):
        uuids = ['tojrbxmkuzrarnniosuhct', 'pwtwlmfciymjdoljkhagxa']
        holecards = [[Card.from_str(s) for s in ss]
                     for ss in [['Ac', '2d'], ['8c', '5h']]]
        game_state = restore_game_state(TwoPlayerSample.round_state)
        game_state = reduce(lambda a, e: attach_hole_card(a, e[0], e[1]),
                            zip(uuids, holecards), game_state)
        game_state = attach_hole_card_from_deck(game_state,
                                                'pwtwlmfciymjdoljkhagxa')
        self.emu.set_game_rule(2, 10, 5, 0)
        p1 = TestPlayer([('raise', 65)])
        p2 = TestPlayer([('call', 15), ('call', 65)])
        self.emu.register_player('tojrbxmkuzrarnniosuhct', p1)
        self.emu.register_player('pwtwlmfciymjdoljkhagxa', p2)
        game_state['table'].deck.deck.append(Card.from_str('7c'))

        game_state, events = self.emu.run_until_round_finish(game_state)
        self.eq('event_new_street', events[0]['type'])
        self.eq('event_ask_player', events[1]['type'])
        self.eq('event_ask_player', events[2]['type'])
        self.eq('event_round_finish', events[3]['type'])
        self.eq('event_game_finish', events[4]['type'])
        self.eq(0, events[4]['players'][0]['stack'])
        self.eq(200, events[4]['players'][1]['stack'])

    def test_run_until_game_finish(self):
        game_state = restore_game_state(TwoPlayerSample.round_state)
        game_state = attach_hole_card_from_deck(game_state,
                                                'tojrbxmkuzrarnniosuhct')
        game_state = attach_hole_card_from_deck(game_state,
                                                'pwtwlmfciymjdoljkhagxa')
        self.emu.set_game_rule(2, 10, 5, 1)
        self.emu.register_player('tojrbxmkuzrarnniosuhct', FoldMan())
        self.emu.register_player('pwtwlmfciymjdoljkhagxa', FoldMan())

        game_state, events = self.emu.run_until_game_finish(game_state)
        self.eq('event_game_finish', events[-1]['type'])
        self.eq(114, game_state['table'].seats.players[0].stack)
        self.eq(86, game_state['table'].seats.players[1].stack)

    def test_run_until_game_finish_when_one_player_is_left(self):
        uuids = [
            'ruypwwoqwuwdnauiwpefsw', 'sqmfwdkpcoagzqxpxnmxwm',
            'uxrdiwvctvilasinweqven'
        ]
        holecards = [[Card.from_str(s) for s in ss]
                     for ss in [['2c', '3c'], ['Ah', 'Ac'], ['5d', '6d']]]
        game_state = restore_game_state(ThreePlayerGameStateSample.round_state)
        game_state = reduce(
            lambda state, item: attach_hole_card(state, item[0], item[1]),
            zip(uuids, holecards), game_state)
        sb_amount, ante = 5, 7
        self.emu.set_game_rule(3, 10, sb_amount, ante)
        p1_acts = [('fold', 0), ('call', 10), ('call', 0), ('call', 10),
                   ('fold', 0)]
        p2_acts = []
        p3_acts = [('raise', 10)]
        players = [TestPlayer(acts) for acts in [p1_acts, p2_acts, p3_acts]]
        [
            self.emu.register_player(uuid, player)
            for uuid, player in zip(uuids, players)
        ]
        game_state['table'].deck.deck.append(Card.from_str('7c'))
        game_state, events = self.emu.run_until_game_finish(game_state)
        self.eq('event_game_finish', events[-1]['type'])
        self.eq(0, game_state['table'].seats.players[0].stack)
        self.eq(0, game_state['table'].seats.players[1].stack)
        self.eq(292, game_state['table'].seats.players[2].stack)

    def test_run_until_game_finish_when_final_round(self):
        uuids = [
            'ruypwwoqwuwdnauiwpefsw', 'sqmfwdkpcoagzqxpxnmxwm',
            'uxrdiwvctvilasinweqven'
        ]
        holecards = [[Card.from_str(s) for s in ss]
                     for ss in [['2c', '3c'], ['Ah', 'Ac'], ['5d', '6d']]]
        game_state = restore_game_state(ThreePlayerGameStateSample.round_state)
        game_state = reduce(
            lambda state, item: attach_hole_card(state, item[0], item[1]),
            zip(uuids, holecards), game_state)
        sb_amount, ante = 5, 7
        self.emu.set_game_rule(3, 10, sb_amount, ante)
        [self.emu.register_player(uuid, FoldMan()) for uuid in uuids]
        game_state['table'].deck.deck.append(Card.from_str('7c'))
        game_state, events = self.emu.run_until_game_finish(game_state)
        self.eq('event_game_finish', events[-1]['type'])
        self.eq(10, game_state['round_count'])
        self.eq(35, game_state['table'].seats.players[0].stack)
        self.eq(0, game_state['table'].seats.players[1].stack)
        self.eq(265, game_state['table'].seats.players[2].stack)

    def test_last_round_judge(self):
        game_state = restore_game_state(TwoPlayerSample.round_state)
        self.emu.set_game_rule(2, 3, 5, 0)
        self.false(self.emu._is_last_round(game_state, self.emu.game_rule))
        game_state['street'] = Const.Street.FINISHED
        self.true(self.emu._is_last_round(game_state, self.emu.game_rule))
        game_state['round_count'] = 2
        self.false(self.emu._is_last_round(game_state, self.emu.game_rule))
        game_state['table'].seats.players[0].stack = 0
        self.true(self.emu._is_last_round(game_state, self.emu.game_rule))

    def test_start_new_round(self):
        game_state = restore_game_state(TwoPlayerSample.round_state)
        game_state = attach_hole_card_from_deck(game_state,
                                                'tojrbxmkuzrarnniosuhct')
        game_state = attach_hole_card_from_deck(game_state,
                                                'pwtwlmfciymjdoljkhagxa')
        p1, p2 = FoldMan(), FoldMan()
        self.emu.set_game_rule(2, 10, 5, 0)
        self.emu.register_player('tojrbxmkuzrarnniosuhct', FoldMan())
        self.emu.register_player('pwtwlmfciymjdoljkhagxa', FoldMan())

        # run until round finish
        game_state, event = self.emu.apply_action(game_state, 'call', 15)
        game_state, event = self.emu.apply_action(game_state, 'call', 0)
        game_state, event = self.emu.apply_action(game_state, 'call', 0)

        game_state, events = self.emu.start_new_round(game_state)
        self.eq(4, game_state['round_count'])
        self.eq(1, game_state['table'].dealer_btn)
        self.eq(0, game_state['street'])
        self.eq(0, game_state['next_player'])
        self.eq('event_new_street', events[0]['type'])
        self.eq('event_ask_player', events[1]['type'])
        self.eq('preflop', events[0]['street'])
        self.eq('tojrbxmkuzrarnniosuhct', events[1]['uuid'])

    def test_start_new_round_exclude_no_money_players(self):
        uuids = [
            'ruypwwoqwuwdnauiwpefsw', 'sqmfwdkpcoagzqxpxnmxwm',
            'uxrdiwvctvilasinweqven'
        ]
        game_state = restore_game_state(ThreePlayerGameStateSample.round_state)
        original = reduce(
            lambda state, uuid: attach_hole_card_from_deck(state, uuid), uuids,
            game_state)
        sb_amount, ante = 5, 7
        self.emu.set_game_rule(3, 10, sb_amount, ante)
        [self.emu.register_player(uuid, FoldMan()) for uuid in uuids]

        # case1: second player cannot pay small blind
        finish_state, events = self.emu.apply_action(original, 'fold')
        finish_state['table'].seats.players[0].stack = 11
        stacks = [p.stack for p in finish_state['table'].seats.players]
        game_state, events = self.emu.start_new_round(finish_state)
        self.eq(2, game_state['table'].dealer_btn)
        self.eq(1, game_state['next_player'])
        self.eq(stacks[1] - sb_amount - ante,
                game_state['table'].seats.players[1].stack)
        self.eq(stacks[2] - sb_amount * 2 - ante,
                game_state['table'].seats.players[2].stack)
        self.eq(PayInfo.FOLDED,
                game_state['table'].seats.players[0].pay_info.status)
        self.eq(
            sb_amount * 3 + ante * 2,
            GameEvaluator.create_pot(
                game_state['table'].seats.players)[0]['amount'])

        # case2: third player cannot pay big blind
        finish_state, events = self.emu.apply_action(original, 'fold')
        finish_state['table'].seats.players[1].stack = 16
        stacks = [p.stack for p in finish_state['table'].seats.players]
        game_state, events = self.emu.start_new_round(finish_state)
        self.eq(2, game_state['table'].dealer_btn)
        self.eq(0, game_state['next_player'])
        self.eq(stacks[0] - sb_amount - ante,
                game_state['table'].seats.players[0].stack)
        self.eq(stacks[2] - sb_amount * 2 - ante,
                game_state['table'].seats.players[2].stack)
        self.eq(PayInfo.FOLDED,
                game_state['table'].seats.players[1].pay_info.status)
        self.eq(PayInfo.PLAY_TILL_END,
                game_state['table'].seats.players[0].pay_info.status)
        self.eq(
            sb_amount * 3 + ante * 2,
            GameEvaluator.create_pot(
                game_state['table'].seats.players)[0]['amount'])

    def test_start_new_round_exclude_no_money_players2(self):
        uuids = [
            'ruypwwoqwuwdnauiwpefsw', 'sqmfwdkpcoagzqxpxnmxwm',
            'uxrdiwvctvilasinweqven'
        ]
        game_state = restore_game_state(ThreePlayerGameStateSample.round_state)
        original = reduce(
            lambda state, uuid: attach_hole_card_from_deck(state, uuid), uuids,
            game_state)
        sb_amount, ante = 5, 7
        self.emu.set_game_rule(3, 10, sb_amount, ante)
        [self.emu.register_player(uuid, FoldMan()) for uuid in uuids]

        # case1: second player cannot pay small blind
        finish_state, events = self.emu.apply_action(original, 'fold')
        finish_state['table'].seats.players[2].stack = 6
        stacks = [p.stack for p in finish_state['table'].seats.players]
        game_state, events = self.emu.start_new_round(finish_state)
        self.eq(0, game_state['table'].dealer_btn)
        self.eq(1, game_state['table'].sb_pos())
        self.eq(1, game_state['next_player'])

    def test_start_new_round_game_finish_judge(self):
        uuids = [
            'ruypwwoqwuwdnauiwpefsw', 'sqmfwdkpcoagzqxpxnmxwm',
            'uxrdiwvctvilasinweqven'
        ]
        game_state = restore_game_state(ThreePlayerGameStateSample.round_state)
        original = reduce(
            lambda state, uuid: attach_hole_card_from_deck(state, uuid), uuids,
            game_state)
        sb_amount, ante = 5, 7
        self.emu.set_game_rule(3, 10, sb_amount, ante)
        [self.emu.register_player(uuid, FoldMan()) for uuid in uuids]

        finish_state, events = self.emu.apply_action(original, 'fold')
        finish_state['table'].seats.players[2].stack = 11
        finish_state['table'].seats.players[1].stack = 16
        game_state, events = self.emu.start_new_round(finish_state)
        self.eq(1, len(events))
        self.eq('event_game_finish', events[0]['type'])

    def test_generate_initial_game_state(self):
        self.emu.set_game_rule(2, 8, 5, 3)
        p1, p2 = FoldMan(), FoldMan()

        players_info = OrderedDict()
        players_info['uuid-1'] = {'name': 'hoge', 'stack': 100}
        players_info['uuid-2'] = {'name': 'fuga', 'stack': 100}
        state = self.emu.generate_initial_game_state(players_info)
        table = state['table']
        self.eq(0, state['round_count'])
        self.eq(5, state['small_blind_amount'])
        self.eq(100, table.seats.players[0].stack)
        self.eq('uuid-1', table.seats.players[0].uuid)
        self.eq(100, table.seats.players[1].stack)
        self.eq('uuid-2', table.seats.players[1].uuid)
        self.eq(1, table.dealer_btn)

        state, events = self.emu.start_new_round(state)
        self.eq(0, state['table'].dealer_btn)
        self.eq(1, state['table'].sb_pos())
        self.eq(0, state['table'].bb_pos())
        self.eq(1, state['next_player'])
        state, events = self.emu.apply_action(state, 'call', 10)
        self.eq(1, state['next_player'])

    def test_generate_possible_actions(self):
        state1 = restore_game_state(TwoPlayerSample.round_state)
        self.eq(TwoPlayerSample.valid_actions,
                self.emu.generate_possible_actions(state1))
        state2 = restore_game_state(ThreePlayerGameStateSample.round_state)
        self.eq(ThreePlayerGameStateSample.valid_actions,
                self.emu.generate_possible_actions(state2))
Exemplo n.º 3
0
class EmulatorTest(BaseUnitTest):

    def setUp(self):
        self.emu = Emulator()

    def test_set_game_rule(self):
        self.emu.set_game_rule(2, 8, 5, 3)
        self.eq(2, self.emu.game_rule["player_num"])
        self.eq(8, self.emu.game_rule["max_round"])
        self.eq(5, self.emu.game_rule["sb_amount"])
        self.eq(3, self.emu.game_rule["ante"])

    def test_register_and_fetch_player(self):
        p1, p2 = FoldMan(), FoldMan()
        self.emu.register_player("uuid-1", p1)
        self.emu.register_player("uuid-2", p2)
        self.eq(p1, self.emu.fetch_player("uuid-1"))
        self.eq(p2, self.emu.fetch_player("uuid-2"))

    @raises(TypeError)
    def test_register_invalid_player(self):
        self.emu.register_player("uuid", "hoge")

    def test_blind_structure(self):
        game_state = restore_game_state(TwoPlayerSample.round_state)
        game_state = attach_hole_card_from_deck(game_state, "tojrbxmkuzrarnniosuhct")
        game_state = attach_hole_card_from_deck(game_state, "pwtwlmfciymjdoljkhagxa")
        self.emu.set_game_rule(2, 10, 5, 0)
        self.emu.set_blind_structure({5: { "ante": 5, "small_blind": 60 } })
        p1 = TestPlayer([("fold", 0), ('raise', 55), ('call', 0)])
        p2 = TestPlayer([("call", 15), ("call", 55), ('fold', 0)])
        self.emu.register_player("tojrbxmkuzrarnniosuhct", p1)
        self.emu.register_player("pwtwlmfciymjdoljkhagxa", p2)

        game_state, events = self.emu.run_until_round_finish(game_state)
        self.eq(65, game_state["table"].seats.players[0].stack)
        self.eq(135, game_state["table"].seats.players[1].stack)

        game_state, events = self.emu.start_new_round(game_state)
        game_state, events = self.emu.run_until_round_finish(game_state)
        self.eq(120, game_state["table"].seats.players[0].stack)
        self.eq(80, game_state["table"].seats.players[1].stack)

        game_state, events = self.emu.start_new_round(game_state)
        self.eq("event_game_finish", events[0]["type"])
        self.eq(0, game_state["table"].seats.players[0].stack)
        self.eq(80, game_state["table"].seats.players[1].stack)

    def test_blind_structure_update(self):
        self.emu.set_game_rule(2, 8, 5, 3)
        p1, p2 = FoldMan(), FoldMan()
        self.emu.register_player("uuid-1", p1)
        self.emu.register_player("uuid-2", p2)
        blind_structure = {
                3: { "ante": 5, "small_blind": 10 },
                5: {"ante": 10, "small_blind": 20 }
                }
        self.emu.set_blind_structure(blind_structure)
        players_info = {
                "uuid-1": { "name": "hoge", "stack": 100 },
                "uuid-2": { "name": "fuga", "stack": 100 }
                }
        state = self.emu.generate_initial_game_state(players_info)
        self.eq(5, state["small_blind_amount"])
        state, _ = self.emu.start_new_round(state)
        state, _ = self.emu.apply_action(state, "fold")
        self.eq(5, state["small_blind_amount"])
        state, _ = self.emu.apply_action(state, "fold")
        self.eq(5, state["small_blind_amount"])
        state, _ = self.emu.apply_action(state, "fold")
        self.eq(10, state["small_blind_amount"])
        state, _ = self.emu.apply_action(state, "fold")
        self.eq(10, state["small_blind_amount"])
        state, _ = self.emu.apply_action(state, "fold")
        self.eq(20, state["small_blind_amount"])
        state, _ = self.emu.apply_action(state, "fold")
        self.eq(20, state["small_blind_amount"])

    def test_apply_action(self):
        game_state = restore_game_state(TwoPlayerSample.round_state)
        game_state = attach_hole_card_from_deck(game_state, "tojrbxmkuzrarnniosuhct")
        game_state = attach_hole_card_from_deck(game_state, "pwtwlmfciymjdoljkhagxa")
        self.emu.set_game_rule(2, 10, 5, 0)
        p1, p2 = FoldMan(), FoldMan()
        self.emu.register_player("tojrbxmkuzrarnniosuhct", FoldMan())
        self.emu.register_player("pwtwlmfciymjdoljkhagxa", FoldMan())

        game_state, events = self.emu.apply_action(game_state, "call", 15)
        self.eq(Const.Street.RIVER, game_state["street"])
        self.eq(TwoPlayerSample.p1_action_histories, \
                game_state["table"].seats.players[0].round_action_histories[Const.Street.TURN])
        self.eq(2, len(events))
        self.eq("event_new_street", events[0]["type"])
        self.eq("event_ask_player", events[1]["type"])

        game_state, events = self.emu.apply_action(game_state, "call", 0)
        self.eq(1, len(events))
        self.eq("event_ask_player", events[0]["type"])

        game_state, events = self.emu.apply_action(game_state, "call", 0)
        self.eq(1, len(events))
        self.eq("event_round_finish", events[0]["type"])

    def test_apply_action_game_finish_detect(self):
        game_state = restore_game_state(TwoPlayerSample.round_state)
        game_state = attach_hole_card_from_deck(game_state, "tojrbxmkuzrarnniosuhct")
        game_state = attach_hole_card_from_deck(game_state, "pwtwlmfciymjdoljkhagxa")
        self.emu.set_game_rule(2, 3, 5, 0)
        p1, p2 = FoldMan(), FoldMan()
        self.emu.register_player("tojrbxmkuzrarnniosuhct", FoldMan())
        self.emu.register_player("pwtwlmfciymjdoljkhagxa", FoldMan())

        game_state, events = self.emu.apply_action(game_state, "fold")
        self.eq("event_game_finish", events[-1]["type"])

    def test_apply_action_start_next_round(self):
        game_state = restore_game_state(TwoPlayerSample.round_state)
        game_state = attach_hole_card_from_deck(game_state, "tojrbxmkuzrarnniosuhct")
        game_state = attach_hole_card_from_deck(game_state, "pwtwlmfciymjdoljkhagxa")
        self.emu.set_game_rule(2, 4, 5, 0)
        p1, p2 = FoldMan(), FoldMan()
        self.emu.register_player("tojrbxmkuzrarnniosuhct", FoldMan())
        self.emu.register_player("pwtwlmfciymjdoljkhagxa", FoldMan())

        game_state, events = self.emu.apply_action(game_state, "fold")
        self.eq(120, game_state["table"].seats.players[0].stack)
        self.eq(80, game_state["table"].seats.players[1].stack)

        game_state, events = self.emu.apply_action(game_state, "raise", 20)
        self.eq("event_ask_player", events[-1]["type"])
        self.eq(100, game_state["table"].seats.players[0].stack)
        self.eq(70, game_state["table"].seats.players[1].stack)

    @raises(Exception)
    def test_apply_action_when_game_finished(self):
        game_state = restore_game_state(TwoPlayerSample.round_state)
        game_state = attach_hole_card_from_deck(game_state, "tojrbxmkuzrarnniosuhct")
        game_state = attach_hole_card_from_deck(game_state, "pwtwlmfciymjdoljkhagxa")
        self.emu.set_game_rule(2, 3, 5, 0)
        p1, p2 = FoldMan(), FoldMan()
        self.emu.register_player("tojrbxmkuzrarnniosuhct", FoldMan())
        self.emu.register_player("pwtwlmfciymjdoljkhagxa", FoldMan())

        game_state, events = self.emu.apply_action(game_state, "fold")
        self.emu.apply_action(game_state, "fold")


    def test_run_until_round_finish(self):
        game_state = restore_game_state(TwoPlayerSample.round_state)
        game_state = attach_hole_card_from_deck(game_state, "tojrbxmkuzrarnniosuhct")
        game_state = attach_hole_card_from_deck(game_state, "pwtwlmfciymjdoljkhagxa")
        self.emu.set_game_rule(2, 10, 5, 0)
        p1 = TestPlayer([("fold", 0)])
        p2 = TestPlayer([("call", 15)])
        self.emu.register_player("tojrbxmkuzrarnniosuhct", p1)
        self.emu.register_player("pwtwlmfciymjdoljkhagxa", p2)

        game_state, events = self.emu.run_until_round_finish(game_state)
        self.eq("event_new_street", events[0]["type"])
        self.eq("event_ask_player", events[1]["type"])
        self.eq("event_round_finish", events[2]["type"])

    def test_run_until_round_finish_when_already_finished(self):
        game_state = restore_game_state(TwoPlayerSample.round_state)
        game_state = attach_hole_card_from_deck(game_state, "tojrbxmkuzrarnniosuhct")
        game_state = attach_hole_card_from_deck(game_state, "pwtwlmfciymjdoljkhagxa")
        self.emu.set_game_rule(2, 10, 5, 0)
        p1 = TestPlayer([("fold", 0)])
        p2 = TestPlayer([("call", 15)])
        self.emu.register_player("tojrbxmkuzrarnniosuhct", p1)
        self.emu.register_player("pwtwlmfciymjdoljkhagxa", p2)
        game_state, events = self.emu.run_until_round_finish(game_state)
        game_state, events = self.emu.run_until_round_finish(game_state)
        self.eq(0, len(events))

    def test_run_until_round_finish_game_finish_detect(self):
        uuids = ["tojrbxmkuzrarnniosuhct", "pwtwlmfciymjdoljkhagxa"]
        holecards = [[Card.from_str(s) for s in ss] for ss in [["CA", "D2"], ["C8", "H5"]]]
        game_state = restore_game_state(TwoPlayerSample.round_state)
        game_state = reduce(lambda a,e: attach_hole_card(a, e[0], e[1]), zip(uuids, holecards), game_state)
        game_state = attach_hole_card_from_deck(game_state, "pwtwlmfciymjdoljkhagxa")
        self.emu.set_game_rule(2, 10, 5, 0)
        p1 = TestPlayer([("raise", 65)])
        p2 = TestPlayer([("call", 15), ("call", 65)])
        self.emu.register_player("tojrbxmkuzrarnniosuhct", p1)
        self.emu.register_player("pwtwlmfciymjdoljkhagxa", p2)
        game_state["table"].deck.deck.append(Card.from_str("C7"))

        game_state, events = self.emu.run_until_round_finish(game_state)
        self.eq("event_new_street", events[0]["type"])
        self.eq("event_ask_player", events[1]["type"])
        self.eq("event_ask_player", events[2]["type"])
        self.eq("event_round_finish", events[3]["type"])
        self.eq("event_game_finish", events[4]["type"])
        self.eq(0, events[4]["players"][0]["stack"])
        self.eq(200, events[4]["players"][1]["stack"])

    def test_run_until_game_finish(self):
        game_state = restore_game_state(TwoPlayerSample.round_state)
        game_state = attach_hole_card_from_deck(game_state, "tojrbxmkuzrarnniosuhct")
        game_state = attach_hole_card_from_deck(game_state, "pwtwlmfciymjdoljkhagxa")
        self.emu.set_game_rule(2, 10, 5, 1)
        self.emu.register_player("tojrbxmkuzrarnniosuhct", FoldMan())
        self.emu.register_player("pwtwlmfciymjdoljkhagxa", FoldMan())

        game_state, events = self.emu.run_until_game_finish(game_state)
        self.eq("event_game_finish", events[-1]["type"])
        self.eq(114, game_state["table"].seats.players[0].stack)
        self.eq(86, game_state["table"].seats.players[1].stack)

    def test_run_until_game_finish_when_one_player_is_left(self):
        uuids = ["ruypwwoqwuwdnauiwpefsw", "sqmfwdkpcoagzqxpxnmxwm", "uxrdiwvctvilasinweqven"]
        holecards = [[Card.from_str(s) for s in ss] for ss in [["C2","C3"],["HA","CA"],["D5","H6"]]]
        game_state = restore_game_state(ThreePlayerGameStateSample.round_state)
        game_state = reduce(lambda state, item: attach_hole_card(state, item[0], item[1]), zip(uuids, holecards), game_state)
        sb_amount, ante = 5, 7
        self.emu.set_game_rule(3, 10, sb_amount, ante)
        p1_acts = [("fold",0), ("call", 10), ('call', 0), ('call', 10), ("fold",0)]
        p2_acts = []
        p3_acts = [("raise", 10)]
        players = [TestPlayer(acts) for acts in [p1_acts, p2_acts, p3_acts]]
        [self.emu.register_player(uuid, player) for uuid, player in zip(uuids, players)]
        game_state["table"].deck.deck.append(Card.from_str("C7"))
        game_state, events = self.emu.run_until_game_finish(game_state)
        self.eq("event_game_finish", events[-1]["type"])
        self.eq(0, game_state["table"].seats.players[0].stack)
        self.eq(0, game_state["table"].seats.players[1].stack)
        self.eq(292, game_state["table"].seats.players[2].stack)

    def test_run_until_game_finish_when_final_round(self):
        uuids = ["ruypwwoqwuwdnauiwpefsw", "sqmfwdkpcoagzqxpxnmxwm", "uxrdiwvctvilasinweqven"]
        holecards = [[Card.from_str(s) for s in ss] for ss in [["C2","C3"],["HA","CA"],["D5","H6"]]]
        game_state = restore_game_state(ThreePlayerGameStateSample.round_state)
        game_state = reduce(lambda state, item: attach_hole_card(state, item[0], item[1]), zip(uuids, holecards), game_state)
        sb_amount, ante = 5, 7
        self.emu.set_game_rule(3, 10, sb_amount, ante)
        [self.emu.register_player(uuid, FoldMan()) for uuid in uuids]
        game_state["table"].deck.deck.append(Card.from_str("C7"))
        game_state, events = self.emu.run_until_game_finish(game_state)
        self.eq("event_game_finish", events[-1]["type"])
        self.eq(10, game_state["round_count"])
        self.eq(35, game_state["table"].seats.players[0].stack)
        self.eq(0, game_state["table"].seats.players[1].stack)
        self.eq(265, game_state["table"].seats.players[2].stack)

    def test_last_round_judge(self):
        game_state = restore_game_state(TwoPlayerSample.round_state)
        self.emu.set_game_rule(2, 3, 5, 0)
        self.false(self.emu._is_last_round(game_state, self.emu.game_rule))
        game_state["street"] = Const.Street.FINISHED
        self.true(self.emu._is_last_round(game_state, self.emu.game_rule))
        game_state["round_count"] = 2
        self.false(self.emu._is_last_round(game_state, self.emu.game_rule))
        game_state["table"].seats.players[0].stack = 0
        self.true(self.emu._is_last_round(game_state, self.emu.game_rule))

    def test_start_new_round(self):
        game_state = restore_game_state(TwoPlayerSample.round_state)
        game_state = attach_hole_card_from_deck(game_state, "tojrbxmkuzrarnniosuhct")
        game_state = attach_hole_card_from_deck(game_state, "pwtwlmfciymjdoljkhagxa")
        p1, p2 = FoldMan(), FoldMan()
        self.emu.set_game_rule(2, 10, 5, 0)
        self.emu.register_player("tojrbxmkuzrarnniosuhct", FoldMan())
        self.emu.register_player("pwtwlmfciymjdoljkhagxa", FoldMan())

        # run until round finish
        game_state, event = self.emu.apply_action(game_state, "call", 15)
        game_state, event = self.emu.apply_action(game_state, "call", 0)
        game_state, event = self.emu.apply_action(game_state, "call", 0)

        game_state, events = self.emu.start_new_round(game_state)
        self.eq(4, game_state["round_count"])
        self.eq(1, game_state["table"].dealer_btn)
        self.eq(0, game_state["street"])
        self.eq(0, game_state["next_player"])
        self.eq("event_new_street", events[0]["type"])
        self.eq("event_ask_player", events[1]["type"])
        self.eq("preflop", events[0]["street"])
        self.eq("tojrbxmkuzrarnniosuhct", events[1]["uuid"])

    def test_start_new_round_exclude_no_money_players(self):
        uuids = ["ruypwwoqwuwdnauiwpefsw", "sqmfwdkpcoagzqxpxnmxwm", "uxrdiwvctvilasinweqven"]
        game_state = restore_game_state(ThreePlayerGameStateSample.round_state)
        original = reduce(lambda state, uuid: attach_hole_card_from_deck(state, uuid), uuids, game_state)
        sb_amount, ante = 5, 7
        self.emu.set_game_rule(3, 10, sb_amount, ante)
        [self.emu.register_player(uuid, FoldMan()) for uuid in uuids]

        # case1: second player cannot pay small blind
        finish_state, events = self.emu.apply_action(original, "fold")
        finish_state["table"].seats.players[0].stack = 11
        stacks = [p.stack for p in finish_state["table"].seats.players]
        game_state, events = self.emu.start_new_round(finish_state)
        self.eq(2, game_state["table"].dealer_btn)
        self.eq(1, game_state["next_player"])
        self.eq(stacks[1]-sb_amount-ante, game_state["table"].seats.players[1].stack)
        self.eq(stacks[2]-sb_amount*2-ante, game_state["table"].seats.players[2].stack)
        self.eq(PayInfo.FOLDED, game_state["table"].seats.players[0].pay_info.status)
        self.eq(sb_amount*3 + ante*2, GameEvaluator.create_pot(game_state["table"].seats.players)[0]["amount"])

        # case2: third player cannot pay big blind
        finish_state, events = self.emu.apply_action(original, "fold")
        finish_state["table"].seats.players[1].stack = 16
        stacks = [p.stack for p in finish_state["table"].seats.players]
        game_state, events = self.emu.start_new_round(finish_state)
        self.eq(2, game_state["table"].dealer_btn)
        self.eq(0, game_state["next_player"])
        self.eq(stacks[0]-sb_amount-ante, game_state["table"].seats.players[0].stack)
        self.eq(stacks[2]-sb_amount*2-ante, game_state["table"].seats.players[2].stack)
        self.eq(PayInfo.FOLDED, game_state["table"].seats.players[1].pay_info.status)
        self.eq(PayInfo.PAY_TILL_END, game_state["table"].seats.players[0].pay_info.status)
        self.eq(sb_amount*3 + ante*2, GameEvaluator.create_pot(game_state["table"].seats.players)[0]["amount"])

    def test_start_new_round_exclude_no_money_players2(self):
        uuids = ["ruypwwoqwuwdnauiwpefsw", "sqmfwdkpcoagzqxpxnmxwm", "uxrdiwvctvilasinweqven"]
        game_state = restore_game_state(ThreePlayerGameStateSample.round_state)
        original = reduce(lambda state, uuid: attach_hole_card_from_deck(state, uuid), uuids, game_state)
        sb_amount, ante = 5, 7
        self.emu.set_game_rule(3, 10, sb_amount, ante)
        [self.emu.register_player(uuid, FoldMan()) for uuid in uuids]

        # case1: second player cannot pay small blind
        finish_state, events = self.emu.apply_action(original, "fold")
        finish_state["table"].seats.players[2].stack = 6
        stacks = [p.stack for p in finish_state["table"].seats.players]
        game_state, events = self.emu.start_new_round(finish_state)
        self.eq(0, game_state["table"].dealer_btn)
        self.eq(1, game_state["table"].sb_pos())
        self.eq(1, game_state["next_player"])


    def test_start_new_round_game_finish_judge(self):
        uuids = ["ruypwwoqwuwdnauiwpefsw", "sqmfwdkpcoagzqxpxnmxwm", "uxrdiwvctvilasinweqven"]
        game_state = restore_game_state(ThreePlayerGameStateSample.round_state)
        original = reduce(lambda state, uuid: attach_hole_card_from_deck(state, uuid), uuids, game_state)
        sb_amount, ante = 5, 7
        self.emu.set_game_rule(3, 10, sb_amount, ante)
        [self.emu.register_player(uuid, FoldMan()) for uuid in uuids]

        finish_state, events = self.emu.apply_action(original, "fold")
        finish_state["table"].seats.players[2].stack = 11
        finish_state["table"].seats.players[1].stack = 16
        game_state, events = self.emu.start_new_round(finish_state)
        self.eq(1, len(events))
        self.eq("event_game_finish", events[0]["type"])

    def test_generate_initial_game_state(self):
        self.emu.set_game_rule(2, 8, 5, 3)
        p1, p2 = FoldMan(), FoldMan()

        players_info = OrderedDict()
        players_info["uuid-1"] = { "name": "hoge", "stack": 100 }
        players_info["uuid-2"] = { "name": "fuga", "stack": 100 }
        state = self.emu.generate_initial_game_state(players_info)
        table = state["table"]
        self.eq(0, state["round_count"])
        self.eq(5, state["small_blind_amount"])
        self.eq(100, table.seats.players[0].stack)
        self.eq("uuid-1", table.seats.players[0].uuid)
        self.eq(100, table.seats.players[1].stack)
        self.eq("uuid-2", table.seats.players[1].uuid)
        self.eq(1, table.dealer_btn)

        state, events = self.emu.start_new_round(state)
        self.eq(0, state["table"].dealer_btn)
        self.eq(1, state["table"].sb_pos())
        self.eq(0, state["table"].bb_pos())
        self.eq(1, state["next_player"])
        state, events = self.emu.apply_action(state, "call", 10)
        self.eq(1, state["next_player"])

    def test_generate_possible_actions(self):
        state1 = restore_game_state(TwoPlayerSample.round_state)
        self.eq(TwoPlayerSample.valid_actions, self.emu.generate_possible_actions(state1))
        state2 = restore_game_state(ThreePlayerGameStateSample.round_state)
        self.eq(ThreePlayerGameStateSample.valid_actions, self.emu.generate_possible_actions(state2))
Exemplo n.º 4
0
class EmulatorTest(BaseUnitTest):
    def setUp(self):
        self.emu = Emulator()

    def test_set_game_rule(self):
        self.emu.set_game_rule(2, 8, 5, 3)
        self.eq(2, self.emu.game_rule["player_num"])
        self.eq(8, self.emu.game_rule["max_round"])
        self.eq(5, self.emu.game_rule["sb_amount"])
        self.eq(3, self.emu.game_rule["ante"])

    def test_register_and_fetch_player(self):
        p1, p2 = FoldMan(), FoldMan()
        self.emu.register_player("uuid-1", p1)
        self.emu.register_player("uuid-2", p2)
        self.eq(p1, self.emu.fetch_player("uuid-1"))
        self.eq(p2, self.emu.fetch_player("uuid-2"))

    @raises(TypeError)
    def test_register_invalid_player(self):
        self.emu.register_player("uuid", "hoge")

    def test_blind_structure(self):
        game_state = restore_game_state(TwoPlayerSample.round_state)
        game_state = attach_hole_card_from_deck(game_state,
                                                "tojrbxmkuzrarnniosuhct")
        game_state = attach_hole_card_from_deck(game_state,
                                                "pwtwlmfciymjdoljkhagxa")
        self.emu.set_game_rule(2, 10, 5, 0)
        self.emu.set_blind_structure({5: {"ante": 5, "small_blind": 60}})
        p1 = TestPlayer([("fold", 0), ('raise', 55), ('call', 0)])
        p2 = TestPlayer([("call", 15), ("call", 55), ('fold', 0)])
        self.emu.register_player("tojrbxmkuzrarnniosuhct", p1)
        self.emu.register_player("pwtwlmfciymjdoljkhagxa", p2)

        game_state, events = self.emu.run_until_round_finish(game_state)
        self.eq(65, game_state["table"].seats.players[0].stack)
        self.eq(135, game_state["table"].seats.players[1].stack)

        game_state, events = self.emu.start_new_round(game_state)
        game_state, events = self.emu.run_until_round_finish(game_state)
        self.eq(120, game_state["table"].seats.players[0].stack)
        self.eq(80, game_state["table"].seats.players[1].stack)

        game_state, events = self.emu.start_new_round(game_state)
        self.eq("event_game_finish", events[0]["type"])
        self.eq(0, game_state["table"].seats.players[0].stack)
        self.eq(80, game_state["table"].seats.players[1].stack)

    def test_blind_structure_update(self):
        self.emu.set_game_rule(2, 8, 5, 3)
        p1, p2 = FoldMan(), FoldMan()
        self.emu.register_player("uuid-1", p1)
        self.emu.register_player("uuid-2", p2)
        blind_structure = {
            3: {
                "ante": 5,
                "small_blind": 10
            },
            5: {
                "ante": 10,
                "small_blind": 20
            }
        }
        self.emu.set_blind_structure(blind_structure)
        players_info = {
            "uuid-1": {
                "name": "hoge",
                "stack": 100
            },
            "uuid-2": {
                "name": "fuga",
                "stack": 100
            }
        }
        state = self.emu.generate_initial_game_state(players_info)
        self.eq(5, state["small_blind_amount"])
        state, _ = self.emu.start_new_round(state)
        state, _ = self.emu.apply_action(state, "fold")
        self.eq(5, state["small_blind_amount"])
        state, _ = self.emu.apply_action(state, "fold")
        self.eq(5, state["small_blind_amount"])
        state, _ = self.emu.apply_action(state, "fold")
        self.eq(10, state["small_blind_amount"])
        state, _ = self.emu.apply_action(state, "fold")
        self.eq(10, state["small_blind_amount"])
        state, _ = self.emu.apply_action(state, "fold")
        self.eq(20, state["small_blind_amount"])
        state, _ = self.emu.apply_action(state, "fold")
        self.eq(20, state["small_blind_amount"])

    def test_apply_action(self):
        game_state = restore_game_state(TwoPlayerSample.round_state)
        game_state = attach_hole_card_from_deck(game_state,
                                                "tojrbxmkuzrarnniosuhct")
        game_state = attach_hole_card_from_deck(game_state,
                                                "pwtwlmfciymjdoljkhagxa")
        self.emu.set_game_rule(2, 10, 5, 0)
        p1, p2 = FoldMan(), FoldMan()
        self.emu.register_player("tojrbxmkuzrarnniosuhct", FoldMan())
        self.emu.register_player("pwtwlmfciymjdoljkhagxa", FoldMan())

        game_state, events = self.emu.apply_action(game_state, "call", 15)
        self.eq(Const.Street.RIVER, game_state["street"])
        self.eq(TwoPlayerSample.p1_action_histories, \
                game_state["table"].seats.players[0].round_action_histories[Const.Street.TURN])
        self.eq(2, len(events))
        self.eq("event_new_street", events[0]["type"])
        self.eq("event_ask_player", events[1]["type"])

        game_state, events = self.emu.apply_action(game_state, "call", 0)
        self.eq(1, len(events))
        self.eq("event_ask_player", events[0]["type"])

        game_state, events = self.emu.apply_action(game_state, "call", 0)
        self.eq(1, len(events))
        self.eq("event_round_finish", events[0]["type"])

    def test_apply_action_game_finish_detect(self):
        game_state = restore_game_state(TwoPlayerSample.round_state)
        game_state = attach_hole_card_from_deck(game_state,
                                                "tojrbxmkuzrarnniosuhct")
        game_state = attach_hole_card_from_deck(game_state,
                                                "pwtwlmfciymjdoljkhagxa")
        self.emu.set_game_rule(2, 3, 5, 0)
        p1, p2 = FoldMan(), FoldMan()
        self.emu.register_player("tojrbxmkuzrarnniosuhct", FoldMan())
        self.emu.register_player("pwtwlmfciymjdoljkhagxa", FoldMan())

        game_state, events = self.emu.apply_action(game_state, "fold")
        self.eq("event_game_finish", events[-1]["type"])

    def test_apply_action_start_next_round(self):
        game_state = restore_game_state(TwoPlayerSample.round_state)
        game_state = attach_hole_card_from_deck(game_state,
                                                "tojrbxmkuzrarnniosuhct")
        game_state = attach_hole_card_from_deck(game_state,
                                                "pwtwlmfciymjdoljkhagxa")
        self.emu.set_game_rule(2, 4, 5, 0)
        p1, p2 = FoldMan(), FoldMan()
        self.emu.register_player("tojrbxmkuzrarnniosuhct", FoldMan())
        self.emu.register_player("pwtwlmfciymjdoljkhagxa", FoldMan())

        game_state, events = self.emu.apply_action(game_state, "fold")
        self.eq(120, game_state["table"].seats.players[0].stack)
        self.eq(80, game_state["table"].seats.players[1].stack)

        game_state, events = self.emu.apply_action(game_state, "raise", 20)
        self.eq("event_ask_player", events[-1]["type"])
        self.eq(100, game_state["table"].seats.players[0].stack)
        self.eq(70, game_state["table"].seats.players[1].stack)

    @raises(Exception)
    def test_apply_action_when_game_finished(self):
        game_state = restore_game_state(TwoPlayerSample.round_state)
        game_state = attach_hole_card_from_deck(game_state,
                                                "tojrbxmkuzrarnniosuhct")
        game_state = attach_hole_card_from_deck(game_state,
                                                "pwtwlmfciymjdoljkhagxa")
        self.emu.set_game_rule(2, 3, 5, 0)
        p1, p2 = FoldMan(), FoldMan()
        self.emu.register_player("tojrbxmkuzrarnniosuhct", FoldMan())
        self.emu.register_player("pwtwlmfciymjdoljkhagxa", FoldMan())

        game_state, events = self.emu.apply_action(game_state, "fold")
        self.emu.apply_action(game_state, "fold")

    def test_run_until_round_finish(self):
        game_state = restore_game_state(TwoPlayerSample.round_state)
        game_state = attach_hole_card_from_deck(game_state,
                                                "tojrbxmkuzrarnniosuhct")
        game_state = attach_hole_card_from_deck(game_state,
                                                "pwtwlmfciymjdoljkhagxa")
        self.emu.set_game_rule(2, 10, 5, 0)
        p1 = TestPlayer([("fold", 0)])
        p2 = TestPlayer([("call", 15)])
        self.emu.register_player("tojrbxmkuzrarnniosuhct", p1)
        self.emu.register_player("pwtwlmfciymjdoljkhagxa", p2)

        game_state, events = self.emu.run_until_round_finish(game_state)
        self.eq("event_new_street", events[0]["type"])
        self.eq("event_ask_player", events[1]["type"])
        self.eq("event_round_finish", events[2]["type"])

    def test_run_until_round_finish_when_already_finished(self):
        game_state = restore_game_state(TwoPlayerSample.round_state)
        game_state = attach_hole_card_from_deck(game_state,
                                                "tojrbxmkuzrarnniosuhct")
        game_state = attach_hole_card_from_deck(game_state,
                                                "pwtwlmfciymjdoljkhagxa")
        self.emu.set_game_rule(2, 10, 5, 0)
        p1 = TestPlayer([("fold", 0)])
        p2 = TestPlayer([("call", 15)])
        self.emu.register_player("tojrbxmkuzrarnniosuhct", p1)
        self.emu.register_player("pwtwlmfciymjdoljkhagxa", p2)
        game_state, events = self.emu.run_until_round_finish(game_state)
        game_state, events = self.emu.run_until_round_finish(game_state)
        self.eq(0, len(events))

    def test_run_until_round_finish_game_finish_detect(self):
        uuids = ["tojrbxmkuzrarnniosuhct", "pwtwlmfciymjdoljkhagxa"]
        holecards = [[Card.from_str(s) for s in ss]
                     for ss in [["CA", "D2"], ["C8", "H5"]]]
        game_state = restore_game_state(TwoPlayerSample.round_state)
        game_state = reduce(lambda a, e: attach_hole_card(a, e[0], e[1]),
                            zip(uuids, holecards), game_state)
        game_state = attach_hole_card_from_deck(game_state,
                                                "pwtwlmfciymjdoljkhagxa")
        self.emu.set_game_rule(2, 10, 5, 0)
        p1 = TestPlayer([("raise", 65)])
        p2 = TestPlayer([("call", 15), ("call", 65)])
        self.emu.register_player("tojrbxmkuzrarnniosuhct", p1)
        self.emu.register_player("pwtwlmfciymjdoljkhagxa", p2)
        game_state["table"].deck.deck.append(Card.from_str("C7"))

        game_state, events = self.emu.run_until_round_finish(game_state)
        self.eq("event_new_street", events[0]["type"])
        self.eq("event_ask_player", events[1]["type"])
        self.eq("event_ask_player", events[2]["type"])
        self.eq("event_round_finish", events[3]["type"])
        self.eq("event_game_finish", events[4]["type"])
        self.eq(0, events[4]["players"][0]["stack"])
        self.eq(200, events[4]["players"][1]["stack"])

    def test_run_until_game_finish(self):
        game_state = restore_game_state(TwoPlayerSample.round_state)
        game_state = attach_hole_card_from_deck(game_state,
                                                "tojrbxmkuzrarnniosuhct")
        game_state = attach_hole_card_from_deck(game_state,
                                                "pwtwlmfciymjdoljkhagxa")
        self.emu.set_game_rule(2, 10, 5, 1)
        self.emu.register_player("tojrbxmkuzrarnniosuhct", FoldMan())
        self.emu.register_player("pwtwlmfciymjdoljkhagxa", FoldMan())

        game_state, events = self.emu.run_until_game_finish(game_state)
        self.eq("event_game_finish", events[-1]["type"])
        self.eq(114, game_state["table"].seats.players[0].stack)
        self.eq(86, game_state["table"].seats.players[1].stack)

    def test_run_until_game_finish_when_one_player_is_left(self):
        uuids = [
            "ruypwwoqwuwdnauiwpefsw", "sqmfwdkpcoagzqxpxnmxwm",
            "uxrdiwvctvilasinweqven"
        ]
        holecards = [[Card.from_str(s) for s in ss]
                     for ss in [["C2", "C3"], ["HA", "CA"], ["D5", "H6"]]]
        game_state = restore_game_state(ThreePlayerGameStateSample.round_state)
        game_state = reduce(
            lambda state, item: attach_hole_card(state, item[0], item[1]),
            zip(uuids, holecards), game_state)
        sb_amount, ante = 5, 7
        self.emu.set_game_rule(3, 10, sb_amount, ante)
        p1_acts = [("fold", 0), ("call", 10), ('call', 0), ('call', 10),
                   ("fold", 0)]
        p2_acts = []
        p3_acts = [("raise", 10)]
        players = [TestPlayer(acts) for acts in [p1_acts, p2_acts, p3_acts]]
        [
            self.emu.register_player(uuid, player)
            for uuid, player in zip(uuids, players)
        ]
        game_state["table"].deck.deck.append(Card.from_str("C7"))
        game_state, events = self.emu.run_until_game_finish(game_state)
        self.eq("event_game_finish", events[-1]["type"])
        self.eq(0, game_state["table"].seats.players[0].stack)
        self.eq(0, game_state["table"].seats.players[1].stack)
        self.eq(292, game_state["table"].seats.players[2].stack)

    def test_run_until_game_finish_when_final_round(self):
        uuids = [
            "ruypwwoqwuwdnauiwpefsw", "sqmfwdkpcoagzqxpxnmxwm",
            "uxrdiwvctvilasinweqven"
        ]
        holecards = [[Card.from_str(s) for s in ss]
                     for ss in [["C2", "C3"], ["HA", "CA"], ["D5", "H6"]]]
        game_state = restore_game_state(ThreePlayerGameStateSample.round_state)
        game_state = reduce(
            lambda state, item: attach_hole_card(state, item[0], item[1]),
            zip(uuids, holecards), game_state)
        sb_amount, ante = 5, 7
        self.emu.set_game_rule(3, 10, sb_amount, ante)
        [self.emu.register_player(uuid, FoldMan()) for uuid in uuids]
        game_state["table"].deck.deck.append(Card.from_str("C7"))
        game_state, events = self.emu.run_until_game_finish(game_state)
        self.eq("event_game_finish", events[-1]["type"])
        self.eq(10, game_state["round_count"])
        self.eq(35, game_state["table"].seats.players[0].stack)
        self.eq(0, game_state["table"].seats.players[1].stack)
        self.eq(265, game_state["table"].seats.players[2].stack)

    def test_last_round_judge(self):
        game_state = restore_game_state(TwoPlayerSample.round_state)
        self.emu.set_game_rule(2, 3, 5, 0)
        self.false(self.emu._is_last_round(game_state, self.emu.game_rule))
        game_state["street"] = Const.Street.FINISHED
        self.true(self.emu._is_last_round(game_state, self.emu.game_rule))
        game_state["round_count"] = 2
        self.false(self.emu._is_last_round(game_state, self.emu.game_rule))
        game_state["table"].seats.players[0].stack = 0
        self.true(self.emu._is_last_round(game_state, self.emu.game_rule))

    def test_start_new_round(self):
        game_state = restore_game_state(TwoPlayerSample.round_state)
        game_state = attach_hole_card_from_deck(game_state,
                                                "tojrbxmkuzrarnniosuhct")
        game_state = attach_hole_card_from_deck(game_state,
                                                "pwtwlmfciymjdoljkhagxa")
        p1, p2 = FoldMan(), FoldMan()
        self.emu.set_game_rule(2, 10, 5, 0)
        self.emu.register_player("tojrbxmkuzrarnniosuhct", FoldMan())
        self.emu.register_player("pwtwlmfciymjdoljkhagxa", FoldMan())

        # run until round finish
        game_state, event = self.emu.apply_action(game_state, "call", 15)
        game_state, event = self.emu.apply_action(game_state, "call", 0)
        game_state, event = self.emu.apply_action(game_state, "call", 0)

        game_state, events = self.emu.start_new_round(game_state)
        self.eq(4, game_state["round_count"])
        self.eq(1, game_state["table"].dealer_btn)
        self.eq(0, game_state["street"])
        self.eq(0, game_state["next_player"])
        self.eq("event_new_street", events[0]["type"])
        self.eq("event_ask_player", events[1]["type"])
        self.eq("preflop", events[0]["street"])
        self.eq("tojrbxmkuzrarnniosuhct", events[1]["uuid"])

    def test_start_new_round_exclude_no_money_players(self):
        uuids = [
            "ruypwwoqwuwdnauiwpefsw", "sqmfwdkpcoagzqxpxnmxwm",
            "uxrdiwvctvilasinweqven"
        ]
        game_state = restore_game_state(ThreePlayerGameStateSample.round_state)
        original = reduce(
            lambda state, uuid: attach_hole_card_from_deck(state, uuid), uuids,
            game_state)
        sb_amount, ante = 5, 7
        self.emu.set_game_rule(3, 10, sb_amount, ante)
        [self.emu.register_player(uuid, FoldMan()) for uuid in uuids]

        # case1: second player cannot pay small blind
        finish_state, events = self.emu.apply_action(original, "fold")
        finish_state["table"].seats.players[0].stack = 11
        stacks = [p.stack for p in finish_state["table"].seats.players]
        game_state, events = self.emu.start_new_round(finish_state)
        self.eq(2, game_state["table"].dealer_btn)
        self.eq(1, game_state["next_player"])
        self.eq(stacks[1] - sb_amount - ante,
                game_state["table"].seats.players[1].stack)
        self.eq(stacks[2] - sb_amount * 2 - ante,
                game_state["table"].seats.players[2].stack)
        self.eq(PayInfo.FOLDED,
                game_state["table"].seats.players[0].pay_info.status)
        self.eq(
            sb_amount * 3 + ante * 2,
            GameEvaluator.create_pot(
                game_state["table"].seats.players)[0]["amount"])

        # case2: third player cannot pay big blind
        finish_state, events = self.emu.apply_action(original, "fold")
        finish_state["table"].seats.players[1].stack = 16
        stacks = [p.stack for p in finish_state["table"].seats.players]
        game_state, events = self.emu.start_new_round(finish_state)
        self.eq(2, game_state["table"].dealer_btn)
        self.eq(0, game_state["next_player"])
        self.eq(stacks[0] - sb_amount - ante,
                game_state["table"].seats.players[0].stack)
        self.eq(stacks[2] - sb_amount * 2 - ante,
                game_state["table"].seats.players[2].stack)
        self.eq(PayInfo.FOLDED,
                game_state["table"].seats.players[1].pay_info.status)
        self.eq(PayInfo.PAY_TILL_END,
                game_state["table"].seats.players[0].pay_info.status)
        self.eq(
            sb_amount * 3 + ante * 2,
            GameEvaluator.create_pot(
                game_state["table"].seats.players)[0]["amount"])

    def test_start_new_round_exclude_no_money_players2(self):
        uuids = [
            "ruypwwoqwuwdnauiwpefsw", "sqmfwdkpcoagzqxpxnmxwm",
            "uxrdiwvctvilasinweqven"
        ]
        game_state = restore_game_state(ThreePlayerGameStateSample.round_state)
        original = reduce(
            lambda state, uuid: attach_hole_card_from_deck(state, uuid), uuids,
            game_state)
        sb_amount, ante = 5, 7
        self.emu.set_game_rule(3, 10, sb_amount, ante)
        [self.emu.register_player(uuid, FoldMan()) for uuid in uuids]

        # case1: second player cannot pay small blind
        finish_state, events = self.emu.apply_action(original, "fold")
        finish_state["table"].seats.players[2].stack = 6
        stacks = [p.stack for p in finish_state["table"].seats.players]
        game_state, events = self.emu.start_new_round(finish_state)
        self.eq(0, game_state["table"].dealer_btn)
        self.eq(1, game_state["table"].sb_pos())
        self.eq(1, game_state["next_player"])

    def test_start_new_round_game_finish_judge(self):
        uuids = [
            "ruypwwoqwuwdnauiwpefsw", "sqmfwdkpcoagzqxpxnmxwm",
            "uxrdiwvctvilasinweqven"
        ]
        game_state = restore_game_state(ThreePlayerGameStateSample.round_state)
        original = reduce(
            lambda state, uuid: attach_hole_card_from_deck(state, uuid), uuids,
            game_state)
        sb_amount, ante = 5, 7
        self.emu.set_game_rule(3, 10, sb_amount, ante)
        [self.emu.register_player(uuid, FoldMan()) for uuid in uuids]

        finish_state, events = self.emu.apply_action(original, "fold")
        finish_state["table"].seats.players[2].stack = 11
        finish_state["table"].seats.players[1].stack = 16
        game_state, events = self.emu.start_new_round(finish_state)
        self.eq(1, len(events))
        self.eq("event_game_finish", events[0]["type"])

    def test_generate_initial_game_state(self):
        self.emu.set_game_rule(2, 8, 5, 3)
        p1, p2 = FoldMan(), FoldMan()

        players_info = OrderedDict()
        players_info["uuid-1"] = {"name": "hoge", "stack": 100}
        players_info["uuid-2"] = {"name": "fuga", "stack": 100}
        state = self.emu.generate_initial_game_state(players_info)
        table = state["table"]
        self.eq(0, state["round_count"])
        self.eq(5, state["small_blind_amount"])
        self.eq(100, table.seats.players[0].stack)
        self.eq("uuid-1", table.seats.players[0].uuid)
        self.eq(100, table.seats.players[1].stack)
        self.eq("uuid-2", table.seats.players[1].uuid)
        self.eq(1, table.dealer_btn)

        state, events = self.emu.start_new_round(state)
        self.eq(0, state["table"].dealer_btn)
        self.eq(1, state["table"].sb_pos())
        self.eq(0, state["table"].bb_pos())
        self.eq(1, state["next_player"])
        state, events = self.emu.apply_action(state, "call", 10)
        self.eq(1, state["next_player"])

    def test_generate_possible_actions(self):
        state1 = restore_game_state(TwoPlayerSample.round_state)
        self.eq(TwoPlayerSample.valid_actions,
                self.emu.generate_possible_actions(state1))
        state2 = restore_game_state(ThreePlayerGameStateSample.round_state)
        self.eq(ThreePlayerGameStateSample.valid_actions,
                self.emu.generate_possible_actions(state2))