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))
class EmulatorPlayer(BasePokerPlayer): def set_opponents_model(self, model_player): self.opponents_model = model_player # setup Emulator with passed game information def receive_game_start_message(self, game_info): self.my_model = MyModel() nb_player = game_info['player_num'] max_round = game_info['rule']['max_round'] sb_amount = game_info['rule']['small_blind_amount'] ante_amount = game_info['rule']['ante'] self.emulator = Emulator() self.emulator.set_game_rule(nb_player, max_round, sb_amount, ante_amount) for player_info in game_info['seats']: uuid = player_info['uuid'] player_model = self.my_model if uuid == self.uuid else self.opponents_model self.emulator.register_player(uuid, player_model) def declare_action(self, valid_actions, hole_card, round_state): try_actions = [MyModel.FOLD, MyModel.CALL, MyModel.MIN_RAISE, MyModel.MAX_RAISE] action_results = [0 for i in range(len(try_actions))] log("hole_card of emulator player is %s" % hole_card) for action in try_actions: self.my_model.set_action(action) simulation_results = [] for i in range(NB_SIMULATION): game_state = self._setup_game_state(round_state, hole_card) round_finished_state, _events = self.emulator.run_until_round_finish(game_state) my_stack = [player for player in round_finished_state['table'].seats.players if player.uuid == self.uuid][0].stack simulation_results.append(my_stack) action_results[action] = 1.0 * sum(simulation_results) / NB_SIMULATION log("average stack after simulation when declares %s : %s" % ( {0:'FOLD', 1:'CALL', 2:'MIN_RAISE', 3:'MAX_RAISE'}[action], action_results[action]) ) best_action = max(zip(action_results, try_actions))[1] self.my_model.set_action(best_action) return self.my_model.declare_action(valid_actions, hole_card, round_state) def _setup_game_state(self, round_state, my_hole_card): game_state = restore_game_state(round_state) game_state['table'].deck.shuffle() player_uuids = [player_info['uuid'] for player_info in round_state['seats']] for uuid in player_uuids: if uuid == self.uuid: game_state = attach_hole_card(game_state, uuid, gen_cards(my_hole_card)) # attach my holecard else: game_state = attach_hole_card_from_deck(game_state, uuid) # attach opponents holecard at random return game_state 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
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))
class ModelPlayer(BasePokerPlayer): table_name = "gameinfotbl" standard_insert = "Player_name, win_rate, hole_cards, community_cards, action, stack, small_blind_amount" db_name = "game_information.db" street = ['preflop', 'flop', 'turn', 'river', 'showdown'] def __init__(self, name): self.name = name self.seat = None self.raise_amount = 0 self.win_rate = None self.stack = None self.small_blind_amount = None self.hole_card = None self.community_card = None self.action = None self.opponent_raise_threshold = 0.7 self.opponent_bluffing_ratio = 0.5 self.__init_database() self.Opponent_Model = OpponentModel("Opponent", 0.5, 0.5) self.my_model = MyModel() def declare_action(self, valid_actions, hole_card, round_state): # try_actions = [MyModel.FOLD, MyModel.CALL, MyModel.RAISE] # community_card = round_state['community_card'] pot = round_state['pot']['main']['amount'] call_amount = valid_actions[1]['amount'] self.raise_amount = valid_actions[2]['amount']['min'] # round_strategy = {'preflop' : 0, 'flop' : 0, 'turn' : 0, 'river' : 0, 'showdown' : 0} # street_now = round_state['street'] # # self.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)) # action_results = [0 for i in range(len(try_actions))] # # win_rate = calculate_win_rate_with_model(hole_card, community_card) # log("hole_card of emulator player is %s" % hole_card) # for action_now in try_actions: # round_strategy[round_state['street']] = action_now # for street in enumerate(self.street, self.street.index(street_now) + 1): # for action_later in try_actions: # round_strategy[street] = action_later # self.my_model.set_round_strategy(round_strategy) # simulation_results = [] # for _ in range(NB_SIMULATION): # game_state = self._setup_game_state(round_state, hole_card) # round_finished_state, _events = self.emulator.run_until_round_finish(game_state) # new_winner_uuid = _events[-1]['winners'][-1]['uuid'] # my_stack = [player for player in round_finished_state['table'].seats.players if player.uuid == self.uuid][0].stack # simulation_results.append(my_stack) # if action_results[action_now] < 1.0 * sum(simulation_results) / NB_SIMULATION: # action_results[action_now] = 1.0 * sum(simulation_results) / NB_SIMULATION # log("average stack after simulation when declares %s : %s" % ( # {0:'FOLD', 1:'CALL', 2:'RAISE'}[action_now], action_results[action_now]) # ) # best_action = max(zip(action_results, try_actions))[1] # round_strategy[round_state['street']] = best_action # self.my_model.set_round_strategy(round_strategy) # declare_action, amount = self.my_model.declare_action(valid_actions, hole_card, round_state) # if declare_action == "FOLD": # self.action = 0 # elif declare_action == "CALL": # self.action = 1 # else: # self.action = 2 # self.record_action() win_rate_with_model = self.estimate_win_rate_with_model_to_convergent( hole_card, round_state) print(win_rate_with_model) ev = self.ev_calculation(win_rate_with_model, pot, call_amount) if ev.index(max(ev)) == 0: return valid_actions[0]['action'], valid_actions[0]['amount'] elif ev.index(max(ev)) == 1: return valid_actions[1]['action'], valid_actions[1]['amount'] else: return valid_actions[2]['action'], valid_actions[2]['amount'][ 'min'] def receive_game_start_message(self, game_info): self.nb_player = game_info['player_num'] self.small_blind_amount = game_info['rule']['small_blind_amount'] self.Opponent_Model.set_nb_player(self.nb_player) self.my_model = MyModel() max_round = game_info['rule']['max_round'] sb_amount = game_info['rule']['small_blind_amount'] ante_amount = game_info['rule']['ante'] for player in game_info['seats']: if player['uuid'] == self.uuid: self.seat = game_info['seats'].index(player) break else: raise ('not participating!') self.emulator = Emulator() self.emulator.set_game_rule(self.nb_player, max_round, sb_amount, ante_amount) for player_info in game_info['seats']: uuid = player_info['uuid'] player_model = self.my_model if uuid == self.uuid else self.Opponent_Model self.emulator.register_player(uuid, player_model) def receive_round_start_message(self, round_count, hole_card, seats): self.self_bet = 0 self.hole_card = hole_card def receive_street_start_message(self, street, round_state): self.community_card = round_state['community_card'] def receive_game_update_message(self, action, round_state): if action['player_uuid'] == self.uuid: self.self_bet = self.self_bet + action['amount'] Opponent_bet = round_state['pot']['main']['amount'] - self.self_bet self.Opponent_Model.set_bet(Opponent_bet) self.stack = round_state['seats'][self.seat]['stack'] def receive_round_result_message(self, winners, hand_info, round_state): pass def record_action(self): msg_record = self.__make_message() con = lite.connect(self.db_name) with con: cur = con.cursor() cur.execute( "INSERT INTO gameinfotbl(Player_name, win_rate, hole_cards, community_cards, action, stack, small_blind_amount) VALUES(?,?,?,?,?,?,?)", msg_record) ####################################################################### def ev_calculation(self, win_rate, pot, call_amount): ev = [0 for i in range(3)] ev[0] = -self.self_bet ev[1] = win_rate * (pot - self.self_bet) - (1 - win_rate) * ( self.self_bet + call_amount) ev[2] = win_rate * (pot - self.self_bet + self.raise_amount) - \ (1 - win_rate) * (self.self_bet + self.raise_amount + call_amount) return ev # def choose_action(self, win_rate, pot, valid_actions): # r = rand.random() # ev = self.ev_calculation(win_rate, pot, valid_actions[1]['amount']) # if win_rate >= self.raise_threshold: # return valid_actions[2]['action'], 2 * self.small_blind_amount # elif r >= self.bluffing_ratio: # return valid_actions[2]['action'], 2 * self.small_blind_amount # elif ev[1] >= ev[0]: # return valid_actions[1]['action'], valid_actions[1]['amount'] # else: # return valid_actions[0]['action'], valid_actions[0]['amount'] def _setup_game_state(self, round_state, my_hole_card): game_state = restore_game_state(round_state) game_state['table'].deck.shuffle() community_card = round_state['community_card'] current_street = round_state['street'] player_uuids = [ player_info['uuid'] for player_info in round_state['seats'] ] for uuid in player_uuids: if uuid == self.uuid: game_state = attach_hole_card( game_state, uuid, gen_cards(my_hole_card)) # attach my holecard else: while True: opponent_card = assuming_card(gen_cards(my_hole_card)) if not self.is_already_fold(opponent_card, current_street, community_card): break game_state = attach_hole_card( game_state, uuid, opponent_card) # attach opponents holecard at random return game_state def __make_message(self): msg = [] msg.append(self.name) msg.append(self.win_rate) msg.append(str(self.hole_card)) msg.append(str(self.community_card)) msg.append(self.action) msg.append(self.stack) msg.append(self.small_blind_amount) return msg def __init_database(self): con = lite.connect(self.db_name) with con: cur = con.cursor() cur.execute( "CREATE TABLE IF NOT EXISTS {tbl_name}(_Id INTEGER PRIMARY KEY, Player_name TEXT, win_rate REAL, \ hole_cards TEXT, community_cards TEXT, action INT, stack INT, small_blind_amount INT)" .format(tbl_name=self.table_name)) def _modify_round_strategy_list(self, action, street, round_strategy): round_strategy['street'] = action def is_already_fold(self, opponent_card, current_street, community_card): win_rate = 0 r = rand.random() str_card = [str(a) for a in opponent_card] for street in street_table.keys(): win_rate = get_broad_win_rate( str_card, community_card[0:street_table[street]]) if win_rate < self.opponent_raise_threshold and r < self.opponent_bluffing_ratio: return True if street == current_street or street == 'river': break return False def simulate_one_time(self, round_state, hole_card): game_state = self._setup_game_state(round_state, hole_card) _round_finished_state, _events = self.emulator.run_until_round_finish( game_state) if _events[-1]['type'] == 'event_game_finish': return 0 #if not 0, the last round will report a error new_winner_uuid = _events[-1]['winners'][-1]['uuid'] # my_stack = [player for player in round_finished_state['table'].seats.players if player.uuid == self.uuid][0].stack # simulation_results.append(my_stack) return 1 if new_winner_uuid == self.uuid else 0 def calculate_win_rate_with_model_serval_time(self, round_state, hole_card, nb_simulation): win_count = sum([ self.simulate_one_time(round_state, hole_card) for _ in range(nb_simulation) ]) return 1.0 * win_count / nb_simulation def estimate_win_rate_with_model_to_convergent(self, hole_card, round_state): ls_win_rate = [.0 for _ in range(10)] rpt_times = 50 counter = 0 ##the newer calculated win percentage must be the avarage number while True: newer_win_rate = self.calculate_win_rate_with_model_serval_time( round_state, hole_card, rpt_times) ls_win_rate.pop(0) itered_win_rate = (ls_win_rate[-1] * counter + newer_win_rate) / (counter + 1) ls_win_rate.append(itered_win_rate) if (np.max(ls_win_rate) - np.min(ls_win_rate)) < 0.1: break counter = counter + 1 return ls_win_rate[-1]
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))
def run_episode(agents): emulator = Emulator() temp_final_state = {} winner_counts = [0] * N_AGENTS n_games_played = 0 for game in range(GAMES_PER_EPISODE): wrappers = [] player_info = {} for i, agent in enumerate(agents): if PERSISTENT_STACKS: if temp_final_state: for seat in temp_final_state: player_info[seat.uuid] = {'name': 'Player ' + str(seat.uuid), 'stack': seat.stack if seat.stack else STACK_SIZE} else: player_info[i] = {'name': 'Player ' + str(i), 'stack': STACK_SIZE} else: player_info[i] = {'name': 'Player ' + str(i), 'stack': STACK_SIZE} wrappers.append(DQNAgentWrapper(agent, STACK_SIZE)) emulator.register_player(uuid=i, player=wrappers[-1]) emulator.set_game_rule(N_AGENTS, 2, BB_SIZE / 2, 0) initial_game_state = emulator.generate_initial_game_state(player_info) game_state, events = emulator.start_new_round(initial_game_state) game_finish_state, events = emulator.run_until_round_finish(game_state) # import json # if game == 0 or game == 1: # print('dumping') # with open('event_dump_' + str(game), 'w') as f: # json.dump(events, f, indent=2) if 'winners' not in events[-1]: events.pop() winner = events[-1]['winners'][0]['uuid'] winner_counts[winner] += 1 n_games_played += 1 for i in range(N_AGENTS): new_stack_size = game_finish_state['table'].seats.players[i].stack reward = (new_stack_size - wrappers[i].prev_stack_size) / BB_SIZE #print('Remembering {} reward for {} action'.format(reward, wrappers[i].prev_action)) wrappers[i].agent.remember(wrappers[i].prev_state, wrappers[i].prev_action, reward, None, 1) temp_final_state = game_finish_state['table'].seats.players # print('====') print('\rGame:{}, epsilon:{}'.format(game, wrappers[0].agent.epsilon), end='') # print(game_finish_state) # print('\n') # print(events[-5:]) # print('====') if (game % REPLAY_EVERY_N_GAMES == 0) or (game == GAMES_PER_EPISODE - 1): # replay memory for every agent # for agent in agents: # agent.replay(BATCH_SIZE) agents[0].replay(BATCH_SIZE) for i in range(N_AGENTS): agents[i].model.reset_states() clear_memory() return agents[0], temp_final_state, winner_counts, n_games_played
class EmulatorPlayer(BasePokerPlayer): def set_opponents_model(self, model_player): self.opponents_model = model_player # setup Emulator with passed game information def receive_game_start_message(self, game_info): self.my_model = MyModel() nb_player = game_info['player_num'] max_round = game_info['rule']['max_round'] sb_amount = game_info['rule']['small_blind_amount'] ante_amount = game_info['rule']['ante'] self.emulator = Emulator() self.emulator.set_game_rule(nb_player, max_round, sb_amount, ante_amount) for player_info in game_info['seats']: uuid = player_info['uuid'] player_model = self.my_model if uuid == self.uuid else self.opponents_model self.emulator.register_player(uuid, player_model) def declare_action(self, valid_actions, hole_card, round_state): try_actions = [MyModel.FOLD, MyModel.CALL, MyModel.MIN_RAISE, MyModel.MAX_RAISE] action_results = [0 for i in range(len(try_actions))] log("hole_card of emulator player is %s" % hole_card) for action in try_actions: self.my_model.set_action(action) simulation_results = [] for i in range(NB_SIMULATION): game_state = self._setup_game_state(round_state, hole_card) round_finished_state, _events = self.emulator.run_until_round_finish(game_state) my_stack = [player for player in round_finished_state['table'].seats.players if player.uuid == self.uuid][0].stack simulation_results.append(my_stack) action_results[action] = 1.0 * sum(simulation_results) / NB_SIMULATION log("average stack after simulation when declares %s : %s" % ( {0:'FOLD', 1:'CALL', 2:'MIN_RAISE', 3:'MAX_RAISE'}[action], action_results[action]) ) best_action = max(zip(action_results, try_actions))[1] self.my_model.set_action(best_action) return self.my_model.declare_action(valid_actions, hole_card, round_state) def _setup_game_state(self, round_state, my_hole_card): game_state = restore_game_state(round_state) game_state['table'].deck.shuffle() player_uuids = [player_info['uuid'] for player_info in round_state['seats']] for uuid in player_uuids: if uuid == self.uuid: game_state = attach_hole_card(game_state, uuid, gen_cards(my_hole_card)) # attach my holecard else: game_state = attach_hole_card_from_deck(game_state, uuid) # attach opponents holecard at random return game_state 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
print("Simulating the game") while True: current_state, events = emulator.start_new_round(current_state) if Event.GAME_FINISH == events[-1]["type"]: break #update game rules round_num = current_state["round_count"] new_ante = int(ANTE["initial"] * (ANTE["growth"]**(round_num // ANTE["rate"]))) emulator.set_game_rule(player_num=len(hall_of_fame), max_round=2**32, small_blind_amount=SB, ante_amount=new_ante) print("Playing round %d of game %d" % (round_num, i)) current_state, events = emulator.run_until_round_finish(current_state) #fit players if Event.GAME_FINISH == events[-1]["type"]: break else: round_state = events[-1]["round_state"] for player in hall_of_fame: player.receive_round_result_message(None, None, round_state) print("Finished playing game %d" % (i)) #calculate score player_to_stack = {} winner = ("uuid", 0) for player in events[-1]['players']: if player["stack"] > winner[1]: winner = (player["uuid"], player["stack"])
[{ x['uuid']: parse_action(x, 1)[6] } for k in events[-1]['round_state']['action_histories'].keys() for x in events[-1]['round_state']['action_histories'][k]]) stack_history = { x['uuid']: x['stack'] for x in events[-1]['round_state']['seats'] } player_initial_stack = { k: stack_history[k] + sum(pay_history[k]) for k in stack_history.keys() } total_round_money = sum( [player_initial_stack[k] for k in player_initial_stack.keys()]) game_state, events = emulator.run_until_round_finish(game_state) if events[-1]['type'] == "event_game_finish": score = { x['uuid']: ((x['stack'] - player_initial_stack[x['uuid']]) / total_round_money) for x in events[-1]['players'] } else: score = { x['uuid']: ((x['stack'] - player_initial_stack[x['uuid']]) / total_round_money) for x in events[-1]['round_state']['seats'] } for e in memory.stmemory: