예제 #1
0
class GenPlayer(BasePokerPlayer):

    # Setup Emulator object by registering game information
    def receive_game_start_message(self, game_info):
        player_num = game_info["player_num"]
        max_round = game_info["rule"]["max_round"]
        small_blind_amount = game_info["rule"]["small_blind_amount"]
        ante_amount = game_info["rule"]["ante"]
        blind_structure = game_info["rule"]["blind_structure"]

        self.emulator = Emulator()
        self.emulator.set_game_rule(player_num, max_round, small_blind_amount,
                                    ante_amount)
        self.emulator.set_blind_structure(blind_structure)

        # Register algorithm of each player which used in the simulation.
        for player_info in game_info["seats"]["players"]:
            self.emulator.register_player(player_info["uuid"], RandomPlayer())

    def declare_action(self, valid_actions, hole_card, round_state):
        game_state = restore_game_state(round_state)
        # decide action by using some simulation result
        updated_state, events = self.emulator.apply_action(game_state, "fold")
        # updated_state, events = self.emulator.run_until_round_finish(game_state)
        # updated_state, events = self.emulator.run_until_game_finish(game_state)
        if self.is_good_simulation_result(updated_state):
            return  # you would declare CALL or RAISE action
        else:
            return "fold", 0
예제 #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 [["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))
예제 #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 [['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))
예제 #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))
예제 #5
0
class Alpha0Regret(BasePokerPlayer):
    def __init__(self,
                 mccfr_simulations,
                 model,
                 exp=0,
                 uuid=None,
                 emulator=None,
                 memory=None):
        super().__init__()
        self.MCCFR_simulations = mccfr_simulations
        self.model = model
        self.mccfr = None
        self.intial_round_stack = 0
        self.total_round_money = 0
        self.emulator = emulator
        self.memory = memory
        if uuid is not None:
            self.uuid = uuid
        self.exp = exp

    # Setup Emulator object by registering game information
    def declare_action(self, valid_actions, hole_card, round_state):

        state = GameState(self.uuid, round_state, gen_cards(hole_card),
                          self.emulator)
        if self.mccfr == None or state.id not in self.mccfr.tree:
            self.buildMCCFR(state)
        else:
            self.changeRootMCCFR(state)

        [self.simulate() for sim in range(self.MCCFR_simulations)]

        #for sim in range(self.MCCFR_simulations):
        #    self.simulate()

        pi = self.getAV()

        action = self.chooseAction(pi)
        if self.memory is not None:
            self.memory.commit_stmemory(self.uuid,
                                        state.convertStateToModelInput(), pi,
                                        np.zeros((1, )))

        return list(state.get_action_list()[action].values())

    def receive_game_start_message(self, game_info):
        player_num = game_info["player_num"]
        max_round = game_info["rule"]["max_round"]
        small_blind_amount = game_info["rule"]["small_blind_amount"]
        ante_amount = game_info["rule"]["ante"]
        blind_structure = game_info["rule"]["blind_structure"]

        self.emulator = Emulator()
        self.emulator.set_game_rule(player_num, max_round, small_blind_amount,
                                    ante_amount)
        self.emulator.set_blind_structure(blind_structure)

    def receive_round_start_message(self, round_count, hole_card, seats):
        pass

    def receive_street_start_message(self, street, round_state):
        pass

    def receive_game_update_message(self, action, round_state):
        pass

    def receive_round_result_message(self, winners, hand_info, round_state):
        pass

    def buildMCCFR(self, state):
        self.root = mc.Node(state)
        self.mccfr = mc.MCCFR(self.root, self.uuid)

    def changeRootMCCFR(self, state):
        self.mccfr.root = self.mccfr.tree[state.id]

    def simulate(self):
        leaf, value, done, breadcrumbs = self.mccfr.moveToLeaf(self.model)
        value, breadcrumbs = self.evaluateLeaf(leaf, value, done, breadcrumbs)
        self.mccfr.backFill(value, breadcrumbs)

    def evaluateLeaf(self, leaf, value, done, breadcrumbs):
        if done == 0:

            value, probs, allowedActions = self.get_preds(leaf.state)
            probs = probs[allowedActions]

            for idx, action in enumerate(allowedActions):
                newState, _, _ = leaf.state.takeAction(action)
                if newState.id not in self.mccfr.tree:
                    node = mc.Node(newState)
                    self.mccfr.addNode(node)
                else:
                    node = self.mccfr.tree[newState.id]
                newEdge = mc.Edge(leaf, node, probs[idx], action)
                leaf.edges.append((action, newEdge))

        return ((value, breadcrumbs))

    def get_preds(self, state):
        # predict the leaf
        main_input, my_info, my_history, adv_info, adv_history = state.convertStateToModelInput(
        )
        preds = self.model.predict(
            [main_input, my_info, my_history, *adv_info, *adv_history])
        value_array = preds[0]
        logits_array = preds[1]
        value = value_array[0][0]
        logits = logits_array[0]

        allowedActions = state.allowed_action

        mask = np.ones(logits.shape, dtype=bool)
        mask[allowedActions] = False
        logits[mask] = float('-inf')

        probs = stable_softmax(logits)

        return ((value, probs, allowedActions))

    def getAV(self):
        edges = self.mccfr.root.edges
        pi = np.zeros(config.game_param['RAISE_PARTITION_NUM'] + 2,
                      dtype=np.float32)
        for action, edge in edges:
            pi[action] = max(0, edge.stats['R'])
        if np.sum(pi) == 0:
            for action, edge in edges:
                pi[action] = edge.stats['N']

        pi = pi / np.sum(pi)
        return pi

    def chooseAction(self, pi):
        pi = np.asarray([truncate_float(x, 7) for x in pi])
        if self.exp == 0:
            actions = np.argwhere(pi == max(pi))
            action = random.choice(actions)[0]
        else:
            action_idx = np.random.multinomial(1, pi)
            action = np.where(action_idx == 1)[0][0]

        return action
예제 #6
0
class RLPlayer(BasePokerPlayer):
    def __init__(self, nplayers, uuid, alpha=0.7):
        self._probability_cutoff = [0.2, 0.62, 0.92]
        self._stack_cutoff = [5, 20, 32.5]
        self._raise_cutoff = [4, 10, 20]
        self._stages = [0, 1, 2, 3]
        self._pot_cutoff = [4, 15, 32.5]
        self.STATES = list(
            itertools.product(self._raise_cutoff, self._stages,
                              self._probability_cutoff, self._pot_cutoff,
                              self._stack_cutoff))
        #self.STATES = list(itertools.product(self._raise_cutoff, self._stages, self._probability_cutoff, self._stack_cutoff))
        self.ACTIONS = ['FOLD', 'RAISE', 'CALL']
        self._pot = []
        self._previous_state = []
        self._stack = []
        self._uuid = uuid
        self._probabilities = []
        self._state = []
        self._raise = []
        self.nb_player = nplayers
        self.ALPHA = alpha

    # Setup Emulator object by registering game information
    def receive_game_start_message(self, game_info):
        self.nb_player = game_info['player_num']
        global PLAYER_NUM
        PLAYER_NUM = game_info["player_num"]
        max_round = game_info["rule"]["max_round"]
        small_blind_amount = game_info["rule"]["small_blind_amount"]
        ante_amount = game_info["rule"]["ante"]
        blind_structure = game_info["rule"]["blind_structure"]

        for i in range(0, len(game_info['seats'])):
            if (game_info['seats'][i]['name'] == 'q-learning'):
                self._uuid = game_info['seats'][i]['uuid']

        self.emulator = Emulator()
        self.emulator.set_game_rule(PLAYER_NUM, max_round, small_blind_amount,
                                    ante_amount)
        self.emulator.set_blind_structure(blind_structure)

    def declare_action(self, valid_actions, hole_card, round_state):
        community_card = round_state['community_card']
        game_state = restore_game_state(round_state)
        big_blind = round_state['small_blind_amount'] * 2

        win_rate = estimate_hole_card_win_rate(
            nb_simulation=NB_SIMULATION,
            nb_player=self.nb_player,
            hole_card=gen_cards(hole_card),
            community_card=gen_cards(community_card))

        if np.random.rand() <= EPSILON:
            choice = np.random.choice(["fold", "call", "raise"], 1)[0]
            #print(valid_actions[2])
            if choice == "raise":
                #amount = rand.randrange(valid_actions[2]['amount']["min"], max(valid_actions[2]['amount']["min"], valid_actions[2]['amount']["max"]) + 1)
                #amount = valid_actions[2]['amount']['min']
                amount = np.random.randint(
                    valid_actions[2]['amount']["min"],
                    valid_actions[2]['amount']["max"] + 1, 1)[0]
                #print(amount)
                return 'raise', amount
            elif (choice == "fold"):
                return "fold", 0
            elif (choice == "call"):
                return "call", valid_actions[1]['amount']

        self._probabilities.append([win_rate, round_state['street']])
        self._pot.append(round_state['pot']['main']['amount'] / big_blind)
        my_stack = 0
        for i in range(0, len(round_state['seats'])):
            if (round_state['seats'][i]['name'] == 'q-learning'):
                my_stack = round_state['seats'][i]['stack']
                self._stack.append(my_stack)

        # GET RAISED AMOUNT AND STAGES
        total_raised_amount = 0
        for i in ["preflop", "flop", "turn", "river"]:
            if (i in round_state['action_histories']):
                for y in round_state['action_histories'][i]:
                    if (y['uuid'] == self._uuid):
                        self._previous_state.append([
                            y['action'], ["preflop", "flop", "turn",
                                          "river"].index(i)
                        ])
                    if (y['action'] == 'RAISE' and y['uuid'] != self._uuid):
                        total_raised_amount += y['amount']

        total_raised_amount = (total_raised_amount /
                               self.nb_player) / big_blind

        for i in range(0, len(self._raise_cutoff)):
            if (i == len(self._raise_cutoff) - 1):
                self._raise.append(self._raise_cutoff[i])
            elif (total_raised_amount >= self._raise_cutoff[i]):
                continue
            else:
                self._raise.append(self._raise_cutoff[i])
                break

        # GET PRESENT POT
        for i in range(0, len(self._pot_cutoff)):
            if (i == len(self._pot_cutoff) - 1):
                self._pot[-1] = self._pot_cutoff[i]
            elif (self._pot[-1] >= self._pot_cutoff[i]):
                continue
            else:
                self._pot[-1] = self._pot_cutoff[i]
                break

        # DISCRETIZE PRESENT STACK
        for i in range(0, len(self._stack_cutoff)):
            if (i == len(self._stack_cutoff) - 1):
                self._stack[-1] = self._stack_cutoff[i]
            elif (self._stack[-1] >= self._stack_cutoff[i]):
                continue
            else:
                self._stack[-1] = self._stack_cutoff[i]
                break

        # DISCRETIZE PROBABILITIES
        for i in range(0, len(self._probability_cutoff)):
            if (i == len(self._probability_cutoff) - 1):
                self._probabilities[-1][0] = self._probability_cutoff[i]
            elif (self._probabilities[-1][0] >= self._probability_cutoff[i]):
                continue
            else:
                self._probabilities[-1][0] = self._probability_cutoff[i]
                break

        if (len(self._stack) > 1):
            self.update_qmatrix()

        present_state = self.STATES.index(
            (self._raise[-1], ["preflop", "flop", "turn",
                               "river"].index(self._probabilities[-1][1]),
             self._probabilities[-1][0], self._pot[-1], self._stack[-1]))
        #present_state = self.STATES.index( (self._raise[-1], ["preflop", "flop", "turn", "river"].index(self._probabilities[-1][1]), self._probabilities[-1][0], self._stack[-1]) )
        #present_state = self.STATES.index( (self._probabilities[-1][0]) )
        action_todo = self.ACTIONS[np.argmax(QVALUE_MATRIX[present_state])]
        if (action_todo == 'FOLD'):
            return "fold", 0
        elif (action_todo == 'CALL'):
            return "call", valid_actions[1]['amount']
        else:
            #avg_raise = (valid_actions[2]['amount']['max'] + valid_actions[2]['amount']['min']) / 2.0
            #if (avg_raise/3 <= 0):
            #    return "raise", valid_actions[2]['amount']['min']
            #raise_amount = int(np.random.poisson(avg_raise/200, 1))
            raise_amount = valid_actions[2]['amount']['min']
            #print("raise_amount",raise_amount)
            #print(raise_amount)
            return "raise", raise_amount

    def receive_round_start_message(self, round_count, hole_card, seats):
        pass

    def receive_street_start_message(self, street, round_state):
        pass

    def receive_game_update_message(self, new_action, round_state):
        pass

    def receive_round_result_message(self, winners, hand_info, round_state):
        pass

    def update_qmatrix(self):
        i = -1
        reward = self._stack[-1] - self._stack[-2]
        index = self.STATES.index(
            (self._raise[i], self._previous_state[i][1],
             self._probabilities[i][0], self._pot[i], self._stack[i]))
        #index = self.STATES.index( (self._raise[i], self._previous_state[i][1], self._probabilities[i][0], self._stack[i]) )
        if (i + 1 == len(self._probabilities)):
            index_next_state = index
        else:
            index_next_state = self.STATES.index(
                (self._raise[i + 1], self._previous_state[i + 1][1],
                 self._probabilities[i + 1][0], self._pot[i + 1],
                 self._stack[i + 1]))
            #index_next_state = self.STATES.index( (self._raise[i+1], self._previous_state[i+1][1], self._probabilities[i+1][0], self._stack[i+1]) )
        if ((self._previous_state[i][0] == "SMALLBLIND")
                or (self._previous_state[i][0] == "BIGBLIND")):
            self._previous_state[i][0] = "CALL"
        action = self.ACTIONS.index(self._previous_state[i][0])
        maxi = np.amax(QVALUE_MATRIX[index_next_state])
        QVALUE_MATRIX[index][
            action] = QVALUE_MATRIX[index][action] + self.ALPHA * (
                reward + GAMMA * maxi - QVALUE_MATRIX[index][action])

    def clear_stack(self):
        self._probabilities = []
        self._stack = []
        self._raise = []
        self._pot = []
        self._previous_state = []
        self._raise = []
예제 #7
0
파일: task.py 프로젝트: ishikota/PyPokerAI
class TexasHoldemTask(BaseTask):
    def __init__(self,
                 final_round=max_round,
                 scale_reward=False,
                 lose_penalty=False,
                 shuffle_position=False,
                 action_record=False):
        self.final_round = final_round
        self.scale_reward = scale_reward
        self.lose_penalty = lose_penalty
        self.shuffle_position = shuffle_position
        self.action_record = action_record
        self.emulator = Emulator()
        self.emulator.set_game_rule(nb_player, final_round, sb_amount, ante)
        self.emulator.set_blind_structure(blind_structure)
        self.opponent_value_functions = {}
        if shuffle_position:
            print "Warning: shuffle_position is set True. Are you sure?"

        for uuid in players_info:
            self.emulator.register_player(uuid, DummyPlayer())
            if uuid != my_uuid: self.opponent_value_functions[uuid] = None

    def set_opponent_value_functions(self, value_functions):
        assert len(value_functions) == 9
        opponent_uuids = [
            uuid for uuid in self.opponent_value_functions if uuid != my_uuid
        ]
        for uuid, value_function in zip(opponent_uuids, value_functions):
            self.opponent_value_functions[uuid] = value_function

    def generate_initial_state(self):
        return self.generate_initial_state_without_action_record() if not self.action_record\
                else self.generate_initial_state_with_action_record()

    def generate_initial_state_without_action_record(self):
        p_info = _get_shuffled_players_info(
        ) if self.shuffle_position else players_info
        clear_state = self.emulator.generate_initial_game_state(p_info)
        state, _events = self.emulator.start_new_round(clear_state)
        while not self._check_my_turn(state):
            action, amount = self._choose_opponent_action(state)
            state, _events = self.emulator.apply_action(state, action, amount)
            if state[
                    "street"] == Const.Street.FINISHED and not self.is_terminal_state(
                        state):
                state, _events = self.emulator.start_new_round(state)
        return state if not self.is_terminal_state(
            state) else self.generate_initial_state()

    def generate_initial_state_with_action_record(self):
        p_info = _get_shuffled_players_info(
        ) if self.shuffle_position else players_info
        clear_state = self.emulator.generate_initial_game_state(p_info)
        p_act_record = {
            p.uuid: [[], [], [], []]
            for p in clear_state["table"].seats.players
        }
        state, _events = self.emulator.start_new_round(clear_state)
        while not self._check_my_turn(state):
            state[ACTION_RECORD_KEY] = p_act_record
            opponent_uuid, action_info = self._choose_opponent_action(
                state, detail_info=True)
            p_act_record = self._update_action_record(state, p_act_record,
                                                      opponent_uuid,
                                                      action_info)
            action, amount = action_info["action"], action_info["amount"]
            state, _events = self.emulator.apply_action(state, action, amount)
            if state[
                    "street"] == Const.Street.FINISHED and not self.is_terminal_state(
                        state):
                state, _events = self.emulator.start_new_round(state)
        state[ACTION_RECORD_KEY] = p_act_record
        return state if not self.is_terminal_state(
            state) else self.generate_initial_state()

    def is_terminal_state(self, state):
        me = pick_me(state)
        round_finished = state["street"] == Const.Street.FINISHED
        active_players = [
            p for p in state["table"].seats.players if p.stack > 0
        ]
        short_of_players = len(active_players) <= table_break_threshold
        i_am_loser = me.stack == 0
        is_final_round = state["round_count"] >= self.final_round
        return round_finished and (short_of_players or i_am_loser
                                   or is_final_round)

    def transit_state(self, state, action):
        return self.transit_state_without_action_record(state, action) if not self.action_record\
                else self.transit_state_with_action_record(state, action)

    def transit_state_without_action_record(self, state, action):
        assert self._check_my_turn(state)
        assert not self.is_terminal_state(state)
        action, amount = action["action"], action["amount"]
        state, _events = self.emulator.apply_action(state, action, amount)
        if state[
                "street"] == Const.Street.FINISHED and not self.is_terminal_state(
                    state):
            state, _events = self.emulator.start_new_round(state)
        while not self._check_my_turn(state) and not self.is_terminal_state(
                state):
            action, amount = self._choose_opponent_action(state)
            state, _events = self.emulator.apply_action(state, action, amount)
            if state[
                    "street"] == Const.Street.FINISHED and not self.is_terminal_state(
                        state):
                state, _events = self.emulator.start_new_round(state)
        return state

    def transit_state_with_action_record(self, state, action_info):
        assert self._check_my_turn(state)
        assert not self.is_terminal_state(state)
        assert state.has_key(ACTION_RECORD_KEY)
        p_act_record = _deepcopy_action_record(state)
        p_act_record = self._update_action_record(state, p_act_record, my_uuid,
                                                  action_info)
        action, amount = action_info["action"], action_info["amount"]
        state, _events = self.emulator.apply_action(state, action, amount)
        state[ACTION_RECORD_KEY] = p_act_record
        if state[
                "street"] == Const.Street.FINISHED and not self.is_terminal_state(
                    state):
            state, _events = self.emulator.start_new_round(state)
        while not self._check_my_turn(state) and not self.is_terminal_state(
                state):
            state[ACTION_RECORD_KEY] = p_act_record
            opponent_uuid, action_info = self._choose_opponent_action(
                state, detail_info=True)
            p_act_record = self._update_action_record(state, p_act_record,
                                                      opponent_uuid,
                                                      action_info)
            action, amount = action_info["action"], action_info["amount"]
            state, _events = self.emulator.apply_action(state, action, amount)
            if state[
                    "street"] == Const.Street.FINISHED and not self.is_terminal_state(
                        state):
                state, _events = self.emulator.start_new_round(state)
        state[ACTION_RECORD_KEY] = p_act_record
        return state

    def _check_my_turn(self, state):
        players = state["table"].seats.players
        return state["next_player"] != "not_found" and my_uuid == players[
            state["next_player"]].uuid

    def _choose_opponent_action(self, state, detail_info=False):
        players = state["table"].seats.players
        opponent_uuid = players[state["next_player"]].uuid
        value_function = self.opponent_value_functions[opponent_uuid]
        action_info = choose_best_action(self, value_function, state)
        return (opponent_uuid,
                action_info) if detail_info else (action_info["action"],
                                                  action_info["amount"])

    def generate_possible_actions(self, state):
        action_info = self.emulator.generate_possible_actions(state)
        min_raise_amount = action_info[2]["amount"]["min"]
        max_raise_amount = action_info[2]["amount"]["max"]
        player = state["table"].seats.players[state["next_player"]]

        actions = [
            gen_fold_action(),
            gen_call_action(action_info[1]["amount"])
        ]
        if min_raise_amount != -1:
            actions.append(gen_min_raise_action(min_raise_amount))
        if min_raise_amount != -1 and min_raise_amount * 2 < max_raise_amount:
            actions.append(gen_double_raise_action(min_raise_amount * 2))
        if min_raise_amount != -1 and min_raise_amount * 3 < max_raise_amount:
            actions.append(gen_triple_raise_action(min_raise_amount * 3))
        if max_raise_amount != -1:
            actions.append(gen_max_raise_action(max_raise_amount))
        return actions

    def calculate_reward(self, state):
        if self.is_terminal_state(state):
            if pick_me(state).stack == 0 and self.lose_penalty:
                return -1
            if self.scale_reward:
                return 1.0 * pick_me(state).stack / (nb_player * initial_stack)
            else:
                return pick_me(state).stack
        else:
            return 0

    def _update_action_record(self, state, action_record, uuid, action_info):
        action, amount = action_info["action"], action_info["amount"]
        if 'fold' == action: idx = 0
        elif 'call' == action: idx = 1
        elif 'raise' == action: idx = 2
        else: raise Exception("unexpected action [ %s ] received" % action)

        # allin check. the idx of allin is 3.
        action_player = [
            player for player in state["table"].seats.players
            if player.uuid == uuid
        ]
        assert len(action_player) == 1
        if amount >= action_player[0].stack and 'fold' != action: idx = 3
        action_record[uuid][idx].append(amount)
        return action_record