First determine if the round of betting has finished. i.e. all players have acted, AND EITHER all remaining players have met the price (the biggest bet) OR they have gone all-in. Only if the round of betting has finished do you start adding chips to pots.
Algorithm:
Each player has a stack, and a hasBet amount, which is the amount of money they're betting before it gets added to a pot.
Take the lowest hasBet
For every player left in the hand, add that amount to the pot, and subtract it from the player's hasBet
Are there at least 2 players left with hasBet > 0?
YES: start a new pot, go to (1)
NO: go to (4)
- Is this an all-in/cards-up situation? (i.e. all players are all-in, or all players are all in except one, so there are no more betting rounds).
YES: return any remaining hasBet chips to that player, deal all the remaining cards, and determine winners (multiple pots can mean multiple winners).
NO: deal the next card and move to the next round.
Example (python)
if all_in_situation:
add_chips_to_pot()
cards_up_scenario() # no more betting, deal all remaining cards
elif all_players_have_acted and all_players_have_met_price_or_shoved:
add_chips_to_pot()
move_to_next_stage() # stage being flop, turn, etc
else:
increment_action() # action moves on to the next player
def add_chips_to_pot(self):
lowest_bet = work_out_lowest_bet() # omitted for brevity
current_pot_index = len(self.pots) - 1 # i.e. if there are 2 pots, the one we want is at index 1
for player in self.players:
if player.has_bet == 0:
continue
self.pots[current_pot_index].amount = self.pots[current_pot_index].amount + lowest_bet
self.pots[current_pot_index].players.append(player)
player.has_bet = player.has_bet - lowest_bet
players_with_hasbet_remaining = work_this_out() # omitted for brevity
if players_with_hasbet_remaining > 1:
self.pots.append(Pot())
self.add_chips_to_pot()
else:
return
..where self.pots
is a list of Pot
s, and a Pot
has 2 properties: the pot amount and a list of players that are in that Pot, which we need when determining the winner of each pot. You can have whatever data structures you like to achieve the same thing.
Split pots
You'll need a way of determining hand strength, which is beyond the scope of this question. To handle split pots we can say that each Pot
has a list of winners.
def determine_winners(self):
for pot in self.pots:
winners = [] # multiple winners if split pot
winning_score = 0
for player in pot.players:
if player.score == winning_score:
winners.append(player)
elif player.score > winning_score:
winners = []
winning_score = player.score
winners.append(player)
number_of_winners = len(pot.winners)
for winner in pot.winners:
winner.stack = winner.stack + (pot.amount / number_of_winners) # division assumes ints, not decimals
# return any spare chips from a split pot to the player in earliest position
spare = pot.amount % number_of_winners
self.players[0].stack = self.players[0].stack + spare
Note here that I'm returning spare chips left over from the split to the player in earliest position, which I believe is the common rule, but you can do whatever you want with them.