All poker stacks are scraped every few seconds during one poker hand on the preflop. Here's the list of list of stacks in the big blinds(BB). Player 4 makes mandatory bet 0.5 BB, Player 5 makes 1 BB bet at the start, then players act consecutively from 0 to 5. The first sublist is player 0, the last is player 5. Return list of actions.
Example 1: [[102,102,102,102]
[101,101,99,99]
[103.5,103.5,103.5]
[100.5,100.5,100.5,93,79.5]
[105.5,105.0,105.0,105.0]
[94,93,93,93,93,73]]
Desired output 1: Fold - Raise 2 - Fold - Raise 7.5 - Fold - Raise 21 - Fold - Call.
Explanation:
- Player 0 folded because there's no change in his stack.
- Player 1 raised 2 because the stack decreased 101 - 99 = 2 big blinds (BB).
- Player 2 folded because there's no change in his stack.
- Player 3 raised because the stack decreased 100.5 - 93 = 7.5 big blinds and the decrease is larger than previous bet (2 big blinds).
- Player 4 folded because there's no change in his stack after posting small blind (0.5 big blinds or BB).
- Player 5 raised 21 because the his overall stack decreased 93 - 73 = 20 big blinds, he also posted 1 big blind so his overall raise size is 20 1 = 21).
- Player 1 folded because the stack doesn't decrease after his bet.
- Player 3 called 21 because his stack decreased 93 - 79.5 = 13.5 BB and his overall bet in the round is 13.5 7.5 = 21 BB which equals maximum raise size in current round.
I correctly wrote transform_stacks function that transfroms list of stacks sizes into list of differences, however get_actions function is completely incorrect.
from more_itertools import pairwise
from itertools import zip_longest
stacks = [[102,102,102,102], [101,101,99,99], [103.5,103.5,103.5], [100.5,100.5,100.5,93,79.5], [105.5,105.0,105.0,105.0], [94,93,93,93,93,73]]
def transform_stacks(stacks): # finds the difference in stack sizes, the functions is normal
u = [[float(x) - float(y) for (x, y) in pairwise(stacks[z]) if x != '' and y != '' and abs(float(y) - float(x)) > 0.499] for z in range(len(stacks))]
#print(u)
#will return [[], [2.0], [], [7.5, 13.5], [0.5], [1.0, 20.0]]
return u
transposed = transform_stacks(stacks)
def get_actions(stacks):
actions = []
for index in range(len(stacks)):
curr_max = 0
for k in range(len(stacks[index])):
if stacks[index][k] and (stacks[index][k] - 0.01 > curr_max):
actions.append("Raise " str(stacks[index][k]))
curr_max = stacks[index][k]
elif stacks[index][k]:
actions.append("Call " str(stacks[index][k]))
return actions
print(get_actions(transposed)) # should print ['Fold','Raise 2','Fold','Raise 7.5,'Fold','Raise 21','Fold','Call']
CodePudding user response:
I can't test it right now but try if this works. It might look a bit longer than what you had but I think it's a very intuitive way of going at this problem:
from itertools import accumulate
def get_actions(stacks):
# this part should probably go in the transform_stacks function
# what it does is give you the cumulative total rather than the individual raises
# this makes sense because you want the output to be "raise 21"
# for the BB in the example, rather than "raise 20"
stacks = [list(accumulate(x)) for x in stacks]
SB = None
for i, stack in enumerate(stacks):
try:
if stack[0] == 0.5:
SB = i
break
except IndexError:
continue
# just to make sure
if SB is None:
raise ValueError("Small Blind not found")
num_players = len(stacks)
stacks[SB].pop(0)
bet = stacks[(SB 1)%num_players].pop(0)
action_on_player = (SB 2)%num_players
action_strings, out_of_hand = [], []
while any(stacks):
if action_on_player in out_of_hand:
action_on_player = (action_on_player 1)%num_players
continue
if not stacks[action_on_player]:
action_strings.append("Fold")
out_of_hand.append(action_on_player)
action_on_player = (action_on_player 1)%num_players
continue
action = stacks[action_on_player].pop(0)
if action == bet:
action_strings.append("Call")
else:
action_strings.append("Raise " str(action))
bet = action
action_on_player = (action_on_player 1)%num_players
return action_strings