예제 #1
0
 def bet(self, player, amount):
     print(Debug.log_str_bet(player, amount))
     if amount == player.stack_size:
         self.pot.move_all_in(player)
         self.active_players.remove(player)
     else:
         self.pot.invest_chips(player, amount)
예제 #2
0
    def betting_round(self, first_to_act_idx, total_bet):
        is_hand_finished = False
        more_action = True
        turn_player_idx = first_to_act_idx
        raise_amount = total_bet
        last_to_act = self.active_players[first_to_act_idx - 1]
        any_allins = False
        allins = []
        previous_raiser = None

        while more_action:
            active_player = self.active_players[turn_player_idx]
            closing_action = False
            if active_player is last_to_act:
                closing_action = True
            if len(self.active_players) == 1 and active_player is last_to_act and len(self.pot.allin_players) == 0:
                self.non_showdown()
                is_hand_finished = True
                break
            action = active_player.action(total_bet, raise_amount, self.table.big_blind, closing_action)
            action_arr = action.split()
            if action_arr[0].casefold() == 'x' or action_arr[0].casefold() == 'k' or action_arr[
                0].casefold() == 'check':
                if total_bet > active_player.street_investment:
                    print('Cannot check if facing a bet/raise. Try again')
                    continue
                self.hand_log.add_action(active_player, 'x', Debug.log_str_check(active_player))
                self.check(active_player)
                if active_player is last_to_act:
                    more_action = False
            elif action_arr[0] == 'b' or action_arr[0].casefold() == 'bet':
                amt = int(action_arr[1])
                if total_bet > 0:
                    print('Raise instead of bet if facing a bet. Try again')
                    continue
                elif amt > active_player.stack_size:
                    print('Cannot bet more than current stack. Try again')
                    continue
                elif amt < self.table.big_blind <= active_player.stack_size:
                    print('Minimum bet is 1 big blind: ' + str(self.table.big_blind) + '. Try again')
                    continue
                total_bet = amt
                raise_amount = amt
                self.hand_log.add_action(active_player, 'b ' + str(amt), Debug.log_str_bet(active_player, amt))
                self.bet(active_player, amt)
                last_to_act = self.active_players[turn_player_idx - 1]
                previous_raiser = active_player
            elif action_arr[0].casefold() == 'f' or action_arr[0].casefold() == 'fold':
                self.hand_log.add_action(active_player, 'f', Debug.log_str_fold(active_player))
                self.fold(active_player)
                if active_player is last_to_act:
                    more_action = False
            elif action_arr[0] == 'c' or action_arr[0].casefold() == 'call':
                if total_bet == active_player.street_investment:
                    print('Not facing a bet or raise. Valid actions are check(x), bet(b) or fold(f)')
                    continue
                self.hand_log.add_action(active_player, 'c', Debug.log_str_call(active_player, total_bet))
                self.call(active_player, total_bet)
                if active_player is last_to_act:
                    more_action = False
            elif action_arr[0] == 'r' or action_arr[0].casefold() == 'raise':
                try:
                    amt = int(action_arr[1])
                    full_raise = True
                    if not active_player.can_raise:
                        print('Cannot reraise previous raise as it was not a full raise')
                        continue
                    if total_bet == 0:
                        print('Cannot reraise if there is no bet. Try again')
                        continue
                    if amt - total_bet < raise_amount:
                        if active_player.stack_size + active_player.street_investment > amt:
                            print('Must raise current bet by at least ' + str(raise_amount) + '. Try again')
                            continue
                        else:
                            if amt == active_player.stack_size + active_player.street_investment:
                                full_raise = False
                    if full_raise:
                        raise_amount = amt - total_bet
                        if previous_raiser:
                            previous_raiser.can_raise = True
                    elif previous_raiser:
                        previous_raiser.can_raise = False
                    total_bet = amt
                    last_to_act = self.active_players[turn_player_idx - 1]
                    self.hand_log.add_action(active_player, 'r ' + str(amt), Debug.log_str_raise(active_player, amt))
                    self.reraise(active_player, amt)
                except IndexError as e:
                    print('Need a second argument for raise amount. Try again')
                    continue
            else:
                print(action_arr[0] + ' is not a valid option. Try again')
                continue

            # check if the hand has finished
            if len(self.active_players) == 0:
                if len(self.pot.allin_players) > 1:
                    self.showdown()
                elif len(self.pot.allin_players) <= 1:
                    self.non_showdown()
                is_hand_finished = True
                more_action = False
                break
            elif len(self.active_players) == 1 and active_player is last_to_act:
                if len(self.pot.allin_players) == 0:
                    self.non_showdown()
                elif len(self.pot.allin_players) > 0:
                    self.showdown()
                is_hand_finished = True
                more_action = False
                break

            if active_player not in self.active_players:
                turn_player_idx -= 1
            if turn_player_idx + 1 == len(self.active_players):
                turn_player_idx = 0
            else:
                turn_player_idx += 1
        # create sidepots if necessary
        if any_allins and not is_hand_finished:
            p_sorted = [allins[0]]
            for p in self.active_players:
                inserted = False
                for i in range(len(p_sorted)):
                    if p.street_investment < p_sorted[i].street_investment:
                        p_sorted.insert(i, p)
                if not inserted:
                    p_sorted.append(p)
            for p in allins:
                inserted = False
                for i in range(len(p_sorted)):
                    if p.street_investment < p_sorted[i].street_investment:
                        p_sorted.insert(i, p)
                if not inserted:
                    p_sorted.append(p)
            num_sidepots = 0
            for i in range(0, len(p_sorted) - 1):
                if p_sorted[i].street_investment < p_sorted[i + 1].street_investment:
                    difference = p_sorted[i + 1].street_investment - p_sorted[i].street_investment
                    sidepot = SidePot(self.pot, p_sorted[i + 1:])
                    for p in p_sorted[i + 1:]:
                        Pot.transfer_chips(self.pot, sidepot)
                    self.pot.add_side_pot(sidepot)
                    num_sidepots += 1
            # if no chip transfers are necessary then there is only one new sidepot with remaining active players
            if num_sidepots == 0:
                sidepot = SidePot(self.pot, self.active_players)
                self.pot.add_side_pot(sidepot)
        return is_hand_finished