Exemplo n.º 1
0
    def test_everyone_agree_logic_regression(self):
        players = [Player("uuid%d" % i, 100) for i in range(4)]
        players[0].stack = 150
        players[1].stack = 150
        players[2].stack = 50
        players[3].stack = 50
        deck = Deck(cheat=True, cheat_card_ids=range(1, 53))
        table = Table(cheat_deck=deck)
        for player in players:
            table.seats.sitdown(player)
        table.dealer_btn = 3
        table.set_blind_pos(0, 1)

        state, _ = RoundManager.start_new_round(1, 5, 0, table)
        state, _ = RoundManager.apply_action(state, "raise", 15)
        state, _ = RoundManager.apply_action(state, "raise", 20)
        state, _ = RoundManager.apply_action(state, "raise", 25)
        state, _ = RoundManager.apply_action(state, "raise", 30)
        state, _ = RoundManager.apply_action(state, "raise", 50)
        state, _ = RoundManager.apply_action(state, "call", 50)
        state, _ = RoundManager.apply_action(state, "raise", 125)
        state, _ = RoundManager.apply_action(state, "call", 125)
        state, _ = RoundManager.apply_action(state, "fold", 0)
        state, _ = RoundManager.apply_action(state, "fold", 0)
        self.eq(Const.Street.FINISHED, state["street"])
Exemplo n.º 2
0
 def __setup_table(self):
   players = [Player("uuid%d" % i, 100) for i in range(3)]
   deck = Deck(cheat=True, cheat_card_ids=range(1,53))
   table = Table(cheat_deck=deck)
   for player in players: table.seats.sitdown(player)
   table.dealer_btn = 2
   table.set_blind_pos(0, 1)
   return table
Exemplo n.º 3
0
 def __setup_table(self):
     players = [Player("uuid%d" % i, 100) for i in range(3)]
     deck = Deck(cheat=True, cheat_card_ids=range(1, 53))
     table = Table(cheat_deck=deck)
     for player in players: table.seats.sitdown(player)
     table.dealer_btn = 2
     table.set_blind_pos(0, 1)
     return table
Exemplo n.º 4
0
 def __init__(self, small_blind_amount=None, initial_stack=None, ante=None):
     self.small_blind_amount = small_blind_amount
     self.ante = ante if ante else 0
     self.initial_stack = initial_stack
     self.uuid_list = self.__generate_uuid_list()
     self.message_handler = MessageHandler()
     self.message_summarizer = MessageSummarizer(verbose=0)
     self.table = Table()
     self.blind_structure = {}
Exemplo n.º 5
0
    def generate_initial_game_state(self, players_info):
        table = Table()
        for uuid, info in players_info.items():
            table.seats.sitdown(Player(uuid, info["stack"], info["name"]))

        table.dealer_btn = len(table.seats.players) - 1
        return {
            "round_count": 0,
            "small_blind_amount": self.game_rule["sb_amount"],
            "street": Const.Street.PREFLOP,
            "next_player": None,
            "table": table
        }
Exemplo n.º 6
0
def deepcopy_game_state(game_state):
    tabledeepcopy = Table.deserialize(game_state["table"].serialize())
    return {
            "round_count": game_state["round_count"],
            "small_blind_amount": game_state["small_blind_amount"],
            "street": game_state["street"],
            "next_player": game_state["next_player"],
            "table": tabledeepcopy
            }
Exemplo n.º 7
0
def deepcopy_game_state(game_state):
    tabledeepcopy = Table.deserialize(game_state['table'].serialize())
    return {
        'round_count': game_state['round_count'],
        'small_blind_amount': game_state['small_blind_amount'],
        'street': game_state['street'],
        'next_player': game_state['next_player'],
        'table': tabledeepcopy
    }
Exemplo n.º 8
0
def deepcopy_game_state(game_state):
    tabledeepcopy = Table.deserialize(game_state["table"].serialize())
    return {
        "round_count": game_state["round_count"],
        "small_blind_amount": game_state["small_blind_amount"],
        "street": game_state["street"],
        "next_player": game_state["next_player"],
        "table": tabledeepcopy
    }
Exemplo n.º 9
0
 def __deep_copy_state(self, state):
     table_deepcopy = Table.deserialize(state['table'].serialize())
     return {
         'round_count': state['round_count'],
         'small_blind_amount': state['small_blind_amount'],
         'street': state['street'],
         'next_player': state['next_player'],
         'table': table_deepcopy
     }
Exemplo n.º 10
0
 def __deep_copy_state(self, state):
   table_deepcopy = Table.deserialize(state["table"].serialize())
   return {
       "round_count": state["round_count"],
       "small_blind_amount": state["small_blind_amount"],
       "street": state["street"],
       "next_player": state["next_player"],
       "table": table_deepcopy
       }
Exemplo n.º 11
0
def _restore_table(round_state):
    table = Table()
    table.dealer_btn = round_state["dealer_btn"]
    table.set_blind_pos(round_state["small_blind_pos"], round_state["big_blind_pos"])
    _restore_community_card_on_table(table, round_state["community_card"])
    table.deck = _restore_deck(round_state["community_card"])
    table.seats = _restore_seats(round_state["seats"], round_state["action_histories"])
    return table
Exemplo n.º 12
0
 def __setup_players_with_table(self):
     p1 = Player('uuid1', 100)
     p2 = Player('uuid2', 100)
     p3 = Player('uuid3', 100)
     p2.pay_info.update_to_fold()
     p3.pay_info.update_to_allin()
     table = Table()
     for player in [p1, p2, p3]:
         table.seats.sitdown(player)
     return table
Exemplo n.º 13
0
 def __init__(self, small_blind_amount=None, initial_stack=None, ante=None, log_file_location: str = ''):
     self.small_blind_amount = small_blind_amount
     self.ante = ante if ante else 0
     self.initial_stack = initial_stack
     self.uuid_list = self.__generate_uuid_list()
     self.message_handler = MessageHandler()
     self.message_summarizer = MessageSummarizer(verbose=0)
     self.table = Table()
     self.blind_structure = {}
     self.log_file_location = log_file_location
     self.game_history = {}
Exemplo n.º 14
0
def _restore_table(round_state):
    table = Table()
    table.dealer_btn = round_state['dealer_btn']
    table.set_blind_pos(round_state['small_blind_pos'],
                        round_state['big_blind_pos'])
    _restore_community_card_on_table(table, round_state['community_card'])
    table.deck = _restore_deck(round_state['community_card'])
    table.seats = _restore_seats(round_state['seats'],
                                 round_state['action_histories'])
    return table
Exemplo n.º 15
0
 def start_game(self, players_info, game_config):
     self.config = game_config
     # setup table
     table = Table()
     for uuid, name in players_info.items():
         player = Player(uuid, game_config['initial_stack'], name)
         table.seats.sitdown(player)
     # start the first round
     state, msgs = self._start_new_round(1, game_config['blind_structure'],
                                         table)
     self.current_state = state
     return _parse_broadcast_destination(msgs, self.current_state['table'])
Exemplo n.º 16
0
 def test_serialization(self):
     table = self.__setup_players_with_table()
     for card in table.deck.draw_cards(3):
         table.add_community_card(card)
     table.shift_dealer_btn()
     table.set_blind_pos(1, 2)
     serial = table.serialize()
     restored = Table.deserialize(serial)
     self.eq(table.dealer_btn, restored.dealer_btn)
     self.eq(Seats.serialize(table.seats), Seats.serialize(restored.seats))
     self.eq(Deck.serialize(table.deck), Deck.serialize(restored.deck))
     self.eq(table.get_community_card(), restored.get_community_card())
     self.eq(1, restored.sb_pos())
     self.eq(2, restored.bb_pos())
Exemplo n.º 17
0
  def test_everyone_agree_logic_regression(self):
    players = [Player("uuid%d" % i, 100) for i in range(4)]
    players[0].stack = 150
    players[1].stack = 150
    players[2].stack = 50
    players[3].stack = 50
    deck = Deck(cheat=True, cheat_card_ids=range(1,53))
    table = Table(cheat_deck=deck)
    for player in players: table.seats.sitdown(player)
    table.dealer_btn = 3
    table.set_blind_pos(0, 1)

    state, _ = RoundManager.start_new_round(1, 5, 0, table)
    state, _ = RoundManager.apply_action(state, "raise", 15)
    state, _ = RoundManager.apply_action(state, "raise", 20)
    state, _ = RoundManager.apply_action(state, "raise", 25)
    state, _ = RoundManager.apply_action(state, "raise", 30)
    state, _ = RoundManager.apply_action(state, "raise", 50)
    state, _ = RoundManager.apply_action(state, "call", 50)
    state, _ = RoundManager.apply_action(state, "raise", 125)
    state, _ = RoundManager.apply_action(state, "call", 125)
    state, _ = RoundManager.apply_action(state, "fold", 0)
    state, _ = RoundManager.apply_action(state, "fold", 0)
    self.eq(Const.Street.FINISHED, state["street"])
Exemplo n.º 18
0
def setup_table():
    table = Table()
    players = [Player("uuid%d" % i, 100, "hoge") for i in range(3)]
    table.seats.players = players
    table.add_community_card(Card.from_id(1))
    table.dealer_btn = 2
    table.set_blind_pos(2, 0)
    p1, p2, p3 = table.seats.players
    p3.add_action_history(Const.Action.RAISE, 10, 5)
    p1.add_action_history(Const.Action.FOLD)
    p2.add_action_history(Const.Action.RAISE, 20, 10)
    p3.add_action_history(Const.Action.CALL, 20)
    [
        p.save_street_action_histories(Const.Street.PREFLOP)
        for p in [p1, p2, p3]
    ]
    p3.add_action_history(Const.Action.CALL, 5)
    p2.add_action_history(Const.Action.RAISE, 5, 5)
    return table
Exemplo n.º 19
0
def setup_table():
    table = Table()
    players = [Player("uuid%d"%i, 100, "hoge") for i in range(3)]
    table.seats.players = players
    table.add_community_card(Card.from_id(1))
    table.dealer_btn = 2
    table.set_blind_pos(2, 0)
    p1, p2, p3 = table.seats.players
    p3.add_action_history(Const.Action.RAISE, 10, 5)
    p1.add_action_history(Const.Action.FOLD)
    p2.add_action_history(Const.Action.RAISE, 20, 10)
    p3.add_action_history(Const.Action.CALL, 20)
    [p.save_street_action_histories(Const.Street.PREFLOP) for p in [p1, p2, p3]]
    p3.add_action_history(Const.Action.CALL, 5)
    p2.add_action_history(Const.Action.RAISE, 5, 5)
    return table
Exemplo n.º 20
0
 def __setup_table(self, players):
     table = Table()
     for player in players:
         table.seats.sitdown(player)
     return table
Exemplo n.º 21
0
 def __init__(self, small_blind_amount=None, initial_stack=None, ante=None):
     super().__init__(self,
                      small_blind_amount=small_blind_amount,
                      initial_stack=initial_stack,
                      ante=ante)
     self.table = Table(cheat_deck=EmptyCheatDeck())
Exemplo n.º 22
0
class TableTest(BaseUnitTest):

    def setUp(self):
        self.__setup_table()
        self.__setup_player()
        self.table.seats.sitdown(self.player)

    def test_set_blind(self):
        self.assertIsNone(self.table._blind_pos)
        self.table.set_blind_pos(1, 2)
        self.assertIsNotNone(self.table._blind_pos)
        self.eq(1, self.table.sb_pos())
        self.eq(2, self.table.bb_pos())

    def test_set_blind_error(self):
        with self.assertRaises(Exception) as e1:
            self.table.sb_pos()
        with self.assertRaises(Exception) as e2:
            self.table.bb_pos()
        for e in [e1, e2]:
            self.eq('blind position is not yet set', str(e.exception))

    def test_reset_deck(self):
        self.table.reset()
        self.eq(52, self.table.deck.size())

    def test_reset_commynity_card(self):
        self.table.reset()
        for card in self.table.deck.draw_cards(5):
            self.table.add_community_card(card)

    def test_reset_player_status(self):
        self.table.reset()
        self.eq(0, len(self.player.hole_card))
        self.eq(0, len(self.player.action_histories))
        self.eq(PayInfo.PLAY_TILL_END, self.player.pay_info.status)

    @raises(ValueError)
    def test_community_card_exceed_size(self):
        self.table.add_community_card(Card.from_id(1))

    def test_shift_dealer_btn_skip(self):
        table = self.__setup_players_with_table()
        table.shift_dealer_btn()
        self.eq(2, table.dealer_btn)
        table.shift_dealer_btn()
        self.eq(0, table.dealer_btn)

    def test_next_ask_waiting_player_pos(self):
        table = self.__setup_players_with_table()
        self.eq(0, table.next_ask_waiting_player_pos(0))
        self.eq(0, table.next_ask_waiting_player_pos(1))
        self.eq(0, table.next_ask_waiting_player_pos(2))

    def test_next_ask_waitint_player_pos_when_no_one_waiting(self):
        table = self.__setup_players_with_table()
        table.seats.players[0].pay_info.update_to_allin()
        self.eq(table._player_not_found, table.next_ask_waiting_player_pos(0))
        self.eq(table._player_not_found, table.next_ask_waiting_player_pos(1))
        self.eq(table._player_not_found, table.next_ask_waiting_player_pos(2))

    def test_serialization(self):
        table = self.__setup_players_with_table()
        for card in table.deck.draw_cards(3):
            table.add_community_card(card)
        table.shift_dealer_btn()
        table.set_blind_pos(1, 2)
        serial = table.serialize()
        restored = Table.deserialize(serial)
        self.eq(table.dealer_btn, restored.dealer_btn)
        self.eq(Seats.serialize(table.seats), Seats.serialize(restored.seats))
        self.eq(Deck.serialize(table.deck), Deck.serialize(restored.deck))
        self.eq(table.get_community_card(), restored.get_community_card())
        self.eq(1, restored.sb_pos())
        self.eq(2, restored.bb_pos())

    def __setup_table(self):
        self.table = Table()
        for card in self.table.deck.draw_cards(5):
            self.table.add_community_card(card)

    def __setup_player(self):
        self.player = Player('uuid', 100)
        self.player.add_holecard([Card.from_id(cid + 1) for cid in range(2)])
        self.player.add_action_history(Const.Action.CALL, 10)
        self.player.pay_info.update_to_fold()

    def __setup_players_with_table(self):
        p1 = Player('uuid1', 100)
        p2 = Player('uuid2', 100)
        p3 = Player('uuid3', 100)
        p2.pay_info.update_to_fold()
        p3.pay_info.update_to_allin()
        table = Table()
        for player in [p1, p2, p3]:
            table.seats.sitdown(player)
        return table
Exemplo n.º 23
0
 def __setup_table(self):
     self.table = Table()
     for card in self.table.deck.draw_cards(5):
         self.table.add_community_card(card)
 def __setup_table(self):
   table = Table()
   table.set_blind_pos(0, 1)
   table.seats = self.__setup_seats()
   table.add_community_card(Card.from_id(1))
   return table
Exemplo n.º 25
0
class Dealer:
    def __init__(self, small_blind_amount=None, initial_stack=None, ante=None):
        self.small_blind_amount = small_blind_amount
        self.ante = ante if ante else 0
        self.initial_stack = initial_stack
        self.uuid_list = self.__generate_uuid_list()
        self.message_handler = MessageHandler()
        self.message_summarizer = MessageSummarizer(verbose=0)
        self.table = Table()
        self.blind_structure = {}

    def register_player(self, player_name, algorithm):
        self.__config_check()
        uuid = self.__escort_player_to_table(player_name)
        algorithm.set_uuid(uuid)
        self.__register_algorithm_to_message_handler(uuid, algorithm)

    def set_verbose(self, verbose):
        self.message_summarizer.verbose = verbose

    def start_game(self, max_round):
        table = self.table
        self.__notify_game_start(max_round)
        ante, sb_amount = self.ante, self.small_blind_amount
        for round_count in range(1, max_round + 1):
            ante, sb_amount = self.__update_forced_bet_amount(
                ante, sb_amount, round_count, self.blind_structure)
            table = self.__exclude_short_of_money_players(
                table, ante, sb_amount)
            if self.__is_game_finished(table): break
            table = self.play_round(round_count, sb_amount, ante, table)
            table.shift_dealer_btn()
        return self.__generate_game_result(max_round, table.seats)

    def set_table(self):
        return self.table.set_player()

    def play_round(self, round_count, blind_amount, ante, table):
        state, msgs = RoundManager.start_new_round(round_count, blind_amount,
                                                   ante, table)
        while True:
            self.__message_check(msgs, state["street"])
            if state["street"] != Const.Street.FINISHED:  # continue the round
                action, bet_amount = self.__publish_messages(msgs)
                state, msgs = RoundManager.apply_action(
                    state, action, bet_amount)
            else:  # finish the round after publish round result
                self.__publish_messages(msgs)
                break
        return state["table"]

    def set_small_blind_amount(self, amount):
        self.small_blind_amount = amount

    def set_initial_stack(self, amount):
        self.initial_stack = amount

    def set_blind_structure(self, blind_structure):
        self.blind_structure = blind_structure

    def __update_forced_bet_amount(self, ante, sb_amount, round_count,
                                   blind_structure):
        if round_count in blind_structure:
            update_info = blind_structure[round_count]
            msg = self.message_summarizer.summairze_blind_level_update(\
                    round_count, ante, update_info["ante"], sb_amount, update_info["small_blind"])
            self.message_summarizer.print_message(msg)
            ante, sb_amount = update_info["ante"], update_info["small_blind"]
        return ante, sb_amount

    def __register_algorithm_to_message_handler(self, uuid, algorithm):
        self.message_handler.register_algorithm(uuid, algorithm)

    def __escort_player_to_table(self, player_name):
        uuid = self.__fetch_uuid()
        player = Player(uuid, self.initial_stack, player_name)
        self.table.seats.sitdown(player)
        return uuid

    def __notify_game_start(self, max_round):
        config = self.__gen_config(max_round)
        start_msg = MessageBuilder.build_game_start_message(
            config, self.table.seats)
        self.message_handler.process_message(-1, start_msg)
        self.message_summarizer.summarize(start_msg)

    def __is_game_finished(self, table):
        return len([
            player for player in table.seats.players if player.is_active()
        ]) == 1

    def __message_check(self, msgs, street):
        address, msg = msgs[-1]
        invalid = msg["type"] != 'ask'
        invalid &= street != Const.Street.FINISHED or msg["message"][
            "message_type"] == 'round_result'
        if invalid:
            raise Exception("Last message is not ask type. : %s" % msgs)

    def __publish_messages(self, msgs):
        for address, msg in msgs[:-1]:
            self.message_handler.process_message(address, msg)
        self.message_summarizer.summarize_messages(msgs)
        return self.message_handler.process_message(*msgs[-1])

    def __exclude_short_of_money_players(self, table, ante, sb_amount):
        sb_pos, bb_pos = self.__steal_money_from_poor_player(
            table, ante, sb_amount)
        self.__disable_no_money_player(table.seats.players)
        table.set_blind_pos(sb_pos, bb_pos)
        if table.seats.players[table.dealer_btn].stack == 0:
            table.shift_dealer_btn()
        return table

    def __steal_money_from_poor_player(self, table, ante, sb_amount):
        players = table.seats.players
        # exclude player who cannot pay ante
        for player in [p for p in players if p.stack < ante]:
            player.stack = 0
        if players[table.dealer_btn].stack == 0: table.shift_dealer_btn()

        search_targets = players + players + players
        search_targets = search_targets[table.dealer_btn + 1:table.dealer_btn +
                                        1 + len(players)]
        # exclude player who cannot pay small blind
        sb_player = self.__find_first_elligible_player(search_targets,
                                                       sb_amount + ante)
        sb_relative_pos = search_targets.index(sb_player)
        for player in search_targets[:sb_relative_pos]:
            player.stack = 0
        # exclude player who cannot pay big blind
        search_targets = search_targets[sb_relative_pos + 1:sb_relative_pos +
                                        len(players)]
        bb_player = self.__find_first_elligible_player(search_targets,
                                                       sb_amount * 2 + ante,
                                                       sb_player)
        if sb_player == bb_player:  # no one can pay big blind. So steal money from all players except small blind
            for player in [p for p in players if p != bb_player]:
                player.stack = 0
        else:
            bb_relative_pos = search_targets.index(bb_player)
            for player in search_targets[:bb_relative_pos]:
                player.stack = 0
        return players.index(sb_player), players.index(bb_player)

    def __find_first_elligible_player(self,
                                      players,
                                      need_amount,
                                      default=None):
        if default:
            return next(
                (player for player in players if player.stack >= need_amount),
                default)
        return next(
            (player for player in players if player.stack >= need_amount))

    def __disable_no_money_player(self, players):
        no_money_players = [player for player in players if player.stack == 0]
        for player in no_money_players:
            player.pay_info.update_to_fold()

    def __generate_game_result(self, max_round, seats):
        config = self.__gen_config(max_round)
        result_message = MessageBuilder.build_game_result_message(
            config, seats)
        self.message_summarizer.summarize(result_message)
        return result_message

    def __gen_config(self, max_round):
        return {
            "initial_stack": self.initial_stack,
            "max_round": max_round,
            "small_blind_amount": self.small_blind_amount,
            "ante": self.ante,
            "blind_structure": self.blind_structure
        }

    def __config_check(self):
        if self.small_blind_amount is None:
            raise Exception("small_blind_amount is not set!!\
          You need to call 'dealer.set_small_blind_amount' before.")
        if self.initial_stack is None:
            raise Exception("initial_stack is not set!!\
          You need to call 'dealer.set_initial_stack' before.")

    def __fetch_uuid(self):
        return self.uuid_list.pop()

    def __generate_uuid_list(self):
        return [self.__generate_uuid() for _ in range(100)]

    def __generate_uuid(self):
        uuid_size = 22
        chars = [chr(code) for code in range(97, 123)]
        return "".join([random.choice(chars) for _ in range(uuid_size)])