def get_actions(self, game_state, round_state, active): ''' Where the magic happens - your code should implement this function. Called any time the engine needs a triplet of actions from your bot. Arguments: game_state: the GameState object. round_state: the RoundState object. active: your player's index. Returns: Your actions. ''' legal_actions = round_state.legal_actions() # the actions you are allowed to take street = round_state.street # 0, 3, 4, or 5 representing pre-flop, flop, turn, or river respectively my_cards = round_state.hands[active] # your cards across all boards board_cards = [board_state.deck if isinstance(board_state, BoardState) else board_state.previous_state.deck for board_state in round_state.board_states] #the board cards my_pips = [board_state.pips[active] if isinstance(board_state, BoardState) else 0 for board_state in round_state.board_states] # the number of chips you have contributed to the pot on each board this round of betting opp_pips = [board_state.pips[1-active] if isinstance(board_state, BoardState) else 0 for board_state in round_state.board_states] # the number of chips your opponent has contributed to the pot on each board this round of betting continue_cost = [opp_pips[i] - my_pips[i] for i in range(NUM_BOARDS)] #the number of chips needed to stay in each board's pot my_stack = round_state.stacks[active] # the number of chips you have remaining opp_stack = round_state.stacks[1-active] # the number of chips your opponent has remaining stacks = [my_stack, opp_stack] net_upper_raise_bound = round_state.raise_bounds()[1] # max raise across 3 boards net_cost = 0 # keep track of the net additional amount you are spending across boards this round my_actions = [None] * NUM_BOARDS for i in range(NUM_BOARDS): print("bot reached street", street) if AssignAction in legal_actions[i]: cards = self.board_allocations[i] my_actions[i] = AssignAction(cards) if street < 3: if CheckAction in legal_actions[i]: # check-call my_actions[i] = CheckAction() elif CallAction in legal_actions[i]: my_actions[i] = CallAction() else: #self.calculate_strength(self.board_allocations[i], board_cards, 100) if RaiseAction(stacks[0]/3) in legal_actions[i]: my_actions[i] = RaiseAction(stacks[0]/3) elif CallAction in legal_actions[i]: my_actions[i] = CallAction() elif RaiseAction(stacks[0]) in legal_actions[i]: my_actions[i] = RaiseActions(stack[0]) elif CheckAction in legal_actions[i]: my_actions[i] = CheckAction() else: my_actions[i] = FoldAction() return my_actions
def get_actions(self, game_state: GameState, round_state: RoundState, active: int): ''' Where the magic happens - your code should implement this function. Called any time the engine needs a triplet of actions from your bot. Arguments: game_state: the GameState object. round_state: the RoundState object. active: your player's index. Returns: Your actions. ''' legal_actions = round_state.legal_actions() my_actions = [None] * NUM_BOARDS raise_bounds = list(round_state.raise_bounds()) print(raise_bounds) total_cost = sum([ (round_state.board_states[i].pips[1 - active] - round_state.board_states[i].pips[active]) if isinstance( round_state.board_states[i], BoardState) else 0 for i in range(NUM_BOARDS) ]) for i in range(NUM_BOARDS): board_state = round_state.board_states[i] board_actions = legal_actions[i] if isinstance(board_state, TerminalState) or board_state.settled: my_actions[i] = CheckAction() continue elif AssignAction in legal_actions[i]: my_actions[i] = AssignAction(self.card_allocation[i]) mc = monte_carlo_prob(self.card_allocation[i], [], all_cards_excluding(self.cards)) for hand_range in branches_from_dealer[0]: if mc <= float(hand_range): self.players[i].move_down(hand_range) print(f'Branching from dealer: {hand_range}') break elif round_state.street <= 3: print(f'-Board {i+1}-') pips = board_state.pips[active] opp_pips = board_state.pips[1 - active] pot = board_state.pot + opp_pips + pips continue_cost = opp_pips - pips count = 0 while not (self.players[i].is_owner() or self.players[i].at_terminal()): if count > 10: break if self.players[i].current_node().get_owner() == 'D': mc = self.win_probability(board_state, active) for hand_range in branches_from_dealer[1]: if mc <= float(hand_range): self.players[i].move_down(hand_range) print(f'Branching from dealer: {hand_range}') break else: prev = self.players[i].current_node().get_incoming() if continue_cost > 0: if round_state.street > 0 and prev == 'C': self.players[i].move_down('K2') print(f'Opp chose branch: K2') else: branches = [] for branch in self.players[i].get_branches(): if 'R' in branch: branches.append(branch) raise_boundaries = [ int((pot - continue_cost) * (2**(int(branch.replace('R', '')) - 2.5))) for branch in branches ] casted_amount = 0 for k in range(len(raise_boundaries)): if continue_cost <= raise_boundaries[k]: casted_amount = branches[k].replace( 'R', '') break if casted_amount == 0: casted_amount = branches[-1].replace( 'R', '') if 'R' in prev: self.players[i].move_down( f'RR{casted_amount}') print( f'Opp chose branch: RR{casted_amount}') else: self.players[i].move_down( f'R{casted_amount}') print( f'Opp chose branch: R{casted_amount}') else: if 'R' in prev: self.players[i].move_down('C') print('Opp chose branch: C') elif 'K1' == prev or 'C' == prev: self.players[i].move_down('K2') print('Opp chose branch: K2') elif '.' in prev: if 'K1' in self.players[i].get_branches(): self.players[i].move_down('K1') print('Opp chose branch: K1') elif 'C' in self.players[i].get_branches(): self.players[i].move_down('C') print('Opp chose branch: C') count += 1 if continue_cost > 2.25 * (pot - continue_cost): mc = self.win_probability(board_state, active) if (mc > .7 and round_state.street == 0) or (mc > .85 and round_state.street == 3): my_actions[i] = CallAction() self.players[i].move_down('C') print('Swerving branch: C') else: my_actions[i] = FoldAction() self.players[i].move_down('F') print('Swerving branch: F') continue elif not (self.players[i].is_owner() or self.players[i].at_terminal()): if CheckAction in board_actions: my_actions[i] = CheckAction() print('Timed out branch: K') else: my_actions[i] = CallAction() print('Timed out branch: C') continue branch = self.players[i].choose_branch() prev = self.players[i].current_node().get_incoming() if 'RR' in branch and CallAction in board_actions: my_actions[i] = CallAction() self.players[i].move_down('C') print('Choosing branch: C') elif 'R' in branch and 'RR' not in branch and RaiseAction in board_actions: raise_amount = max( BIG_BLIND, min(raise_bounds[1], int(pot * (2**(int(branch[1:]) - 3))))) raise_bounds[1] -= raise_amount my_actions[i] = RaiseAction(raise_amount + opp_pips) self.players[i].move_down(branch) print('Choosing branch:', branch) elif 'C' in branch and CallAction in board_actions: my_actions[i] = CallAction() self.players[i].move_down(branch) print('Choosing branch:', branch) elif 'K' in branch and CheckAction in board_actions: my_actions[i] = CheckAction() self.players[i].move_down(branch) print('Choosing branch:', branch) elif 'F' in branch and FoldAction in board_actions: my_actions[i] = FoldAction() self.players[i].move_down(branch) print('Choosing branch:', branch) elif CheckAction in board_actions: my_actions[i] = CheckAction() self.players[i].move_down('K') print('Defaulting branch: K') else: my_actions[i] = CallAction() self.players[i].move_down('C') print('Defaulting branch: C') else: pips = board_state.pips[active] opp_pips = board_state.pips[1 - active] continue_cost = opp_pips - pips pot = board_state.pot + opp_pips + pips pot_odds = float(continue_cost) / (pot + continue_cost) win_prob = self.win_probability(board_state, active) if continue_cost == 0: if win_prob >= .7 and RaiseAction in legal_actions[ i] and raise_bounds[1] >= BIG_BLIND: if win_prob > 0.96: increase = min(raise_bounds[1] - total_cost, int(pot)) elif win_prob >= 0.9: increase = min(raise_bounds[1] - total_cost, int(.75 * pot)) else: increase = min(raise_bounds[1] - total_cost, int(0.5 * pot)) amount = increase print(f'Bet/raise board {i + 1} to {amount}.') my_actions[i] = RaiseAction(amount) raise_bounds[1] -= amount else: print(f'Check {i + 1}.') my_actions[i] = CheckAction() else: if win_prob > .97 and RaiseAction in legal_actions[ i] and raise_bounds[1] >= BIG_BLIND: increase = min(raise_bounds[1] - total_cost, int(.5 * pot) + opp_pips) amount = increase + opp_pips print(f'Reraise board {i + 1} to {amount}.') my_actions[i] = RaiseAction(amount) raise_bounds[1] -= amount elif win_prob - .4 > pot_odds or win_prob > .95 - ( .05 * (5 - round_state.street)): print( f'Call board {i + 1} w/ {round(pot_odds, 2)} odds.' ) self.when_raised[i].append(round_state.street) my_actions[i] = CallAction() else: print(f'Fold board {i + 1}') my_actions[i] = FoldAction() print() return my_actions
def get_actions(self, game_state, round_state, active): ''' Where the magic happens - your code should implement this function. Called any time the engine needs a triplet of actions from your bot. Arguments: game_state: the GameState object. round_state: the RoundState object. active: your player's index. Returns: Your actions. ''' legal_actions = round_state.legal_actions( ) # the actions you are allowed to take street = round_state.street # 0, 3, 4, or 5 representing pre-flop, flop, turn, or river respectively my_cards = round_state.hands[active] # your cards across all boards board_cards = [ board_state.deck if isinstance(board_state, BoardState) else board_state.previous_state.deck for board_state in round_state.board_states ] #the board cards my_pips = [ board_state.pips[active] if isinstance(board_state, BoardState) else 0 for board_state in round_state.board_states ] # the number of chips you have contributed to the pot on each board this round of betting opp_pips = [ board_state.pips[1 - active] if isinstance(board_state, BoardState) else 0 for board_state in round_state.board_states ] # the number of chips your opponent has contributed to the pot on each board this round of betting continue_cost = [ opp_pips[i] - my_pips[i] for i in range(NUM_BOARDS) ] #the number of chips needed to stay in each board's pot my_stack = round_state.stacks[ active] # the number of chips you have remaining opp_stack = round_state.stacks[ 1 - active] # the number of chips your opponent has remaining stacks = [my_stack, opp_stack] net_upper_raise_bound = round_state.raise_bounds()[ 1] # max raise across 3 boards net_cost = 0 # keep track of the net additional amount you are spending across boards this round my_actions = [None] * NUM_BOARDS for i in range(NUM_BOARDS): if AssignAction in legal_actions[i]: cards = self.board_allocations[ i] #allocate our cards that we made earlier my_actions[i] = AssignAction(cards) #add to our actions elif (RaiseAction in legal_actions[i] and self.strong_hole): #only consider this if we're strong min_raise, max_raise = round_state.board_states[ i].raise_bounds( active, round_state.stacks ) #calulate the highest and lowest we can raise to max_cost = max_raise - my_pips[ i] #the cost to give the max raise if max_cost <= my_stack - net_cost: #make sure the max_cost is something we can afford! Must have at least this much left after our other costs my_actions[i] = RaiseAction(max_raise) #GO ALL IN!!! net_cost += max_cost elif CallAction in legal_actions[i]: # check-call my_actions[i] = CallAction() net_cost += continue_cost[i] else: my_actions[i] = CheckAction() elif CheckAction in legal_actions[i]: # check-call my_actions[i] = CheckAction() else: my_actions[i] = CallAction() net_cost += continue_cost[i] return my_actions
def get_actions(self, game_state, round_state, active): ''' Where the magic happens - your code should implement this function. Called any time the engine needs a triplet of actions from your bot. Arguments: game_state: the GameState object. round_state: the RoundState object. active: your player's index. Returns: Your actions. ''' legal_actions = round_state.legal_actions() # the actions you are allowed to take street = round_state.street # 0, 3, 4, or 5 representing pre-flop, flop, turn, or river respectively my_cards = round_state.hands[active] # your cards across all boards board_cards = [board_state.deck if isinstance(board_state, BoardState) else board_state.previous_state.deck for board_state in round_state.board_states] #the board cards my_pips = [board_state.pips[active] if isinstance(board_state, BoardState) else 0 for board_state in round_state.board_states] # the number of chips you have contributed to the pot on each board this round of betting opp_pips = [board_state.pips[1-active] if isinstance(board_state, BoardState) else 0 for board_state in round_state.board_states] # the number of chips your opponent has contributed to the pot on each board this round of betting continue_cost = [opp_pips[i] - my_pips[i] for i in range(NUM_BOARDS)] #the number of chips needed to stay in each board's pot my_stack = round_state.stacks[active] # the number of chips you have remaining opp_stack = round_state.stacks[1-active] # the number of chips your opponent has remaining stacks = [my_stack, opp_stack] net_upper_raise_bound = round_state.raise_bounds()[1] # max raise across 3 boards net_cost = 0 # keep track of the net additional amount you are spending across boards this round my_actions = [None] * NUM_BOARDS for i in range(NUM_BOARDS): if AssignAction in legal_actions[i]: cards = self.board_allocations[i] #assign our cards that we made earlier my_actions[i] = AssignAction(cards) #add to our actions elif isinstance(round_state.board_states[i], TerminalState): #make sure the game isn't over at this board my_actions[i] = CheckAction() #check if it is else: #do we add more resources? board_cont_cost = continue_cost[i] #we need to pay this to keep playing board_total = round_state.board_states[i].pot #amount before we started betting pot_total = my_pips[i] + opp_pips[i] + board_total #total money in the pot right now min_raise, max_raise = round_state.board_states[i].raise_bounds(active, round_state.stacks) strength = self.hole_strengths[i] if street < 3: #pre-flop raise_ammount = int(my_pips[i] + board_cont_cost + 0.4 * (pot_total + board_cont_cost)) #play a little conservatively pre-flop else: raise_ammount = int(my_pips[i] + board_cont_cost + 0.75 * (pot_total + board_cont_cost)) #raise the stakes deeper into the game raise_ammount = max([min_raise, raise_ammount]) #make sure we have a valid raise raise_ammount = min([max_raise, raise_ammount]) raise_cost = raise_ammount - my_pips[i] #how much it costs to make that raise if RaiseAction in legal_actions[i] and (raise_cost <= my_stack - net_cost): #raise if we can and if we can afford it commit_action = RaiseAction(raise_ammount) commit_cost = raise_cost elif CallAction in legal_actions[i] and (board_cont_cost <= my_stack - net_cost): #call if we can afford it! commit_action = CallAction() commit_cost = board_cont_cost #the cost to call is board_cont_cost elif CheckAction in legal_actions[i]: #try to check if we can commit_action = CheckAction() commit_cost = 0 else: #we have to fold commit_action = FoldAction() commit_cost = 0 if board_cont_cost > 0: #our opp raised!!! we must respond if board_cont_cost > 5: #<--- parameters to tweak. _INTIMIDATION = 0.15 strength = max([0, strength - _INTIMIDATION]) #if our opp raises a lot, be cautious! pot_odds = board_cont_cost / (pot_total + board_cont_cost) if strength >= pot_odds: #Positive Expected Value!! at least call!! if strength > 0.5 and random.random() < strength: #raise sometimes, more likely if our hand is strong my_actions[i] = commit_action net_cost += commit_cost else: # try to call if we don't raise if (board_cont_cost <= my_stack - net_cost): #we call because we can afford it and it's +EV my_actions[i] = CallAction() net_cost += board_cont_cost else: #we can't afford to call :( should have managed our stack better my_actions[i] = FoldAction() net_cost += 0 else: #Negative Expected Value!!! FOLD!!! my_actions[i] = FoldAction() net_cost += 0 else: #board_cont_cost == 0, we control the action if random.random() < strength: #raise sometimes, more likely if our hand is strong my_actions[i] = commit_action net_cost += commit_cost else: #just check otherwise my_actions[i] = CheckAction() net_cost += 0 return my_actions
def get_actions(self, game_state, round_state, active): ''' Where the magic happens - your code should implement this function. Called any time the engine needs a triplet of actions from your bot. Arguments: game_state: the GameState object. round_state: the RoundState object. active: your player's index. Returns: Your actions. ''' legal_actions = round_state.legal_actions( ) # the actions you are allowed to take # street = round_state.street # 0, 3, 4, or 5 representing pre-flop, flop, turn, or river respectively my_cards = round_state.hands[active] # your cards across all boards # board_cards = [board_state.deck if isinstance(board_state, BoardState) else board_state.previous_state.deck for board_state in round_state.board_states] #the board cards # my_pips = [board_state.pips[active] if isinstance(board_state, BoardState) else 0 for board_state in round_state.board_states] # the number of chips you have contributed to the pot on each board this round of betting # opp_pips = [board_state.pips[1-active] if isinstance(board_state, BoardState) else 0 for board_state in round_state.board_states] # the number of chips your opponent has contributed to the pot on each board this round of betting # continue_cost = [opp_pips[i] - my_pips[i] for i in range(NUM_BOARDS)] #the number of chips needed to stay in each board's pot # my_stack = round_state.stacks[active] # the number of chips you have remaining # opp_stack = round_state.stacks[1-active] # the number of chips your opponent has remaining # stacks = [my_stack, opp_stack] # net_upper_raise_bound = round_state.raise_bounds()[1] # max raise across 3 boards # net_cost = 0 # keep track of the net additional amount you are spending across boards this round my_actions = [None] * NUM_BOARDS high_cards = [] for card in my_cards: if (card[0] == 'A' or card[0] == 'J' or card[0] == 'Q' or card[0] == 'K'): high_cards.append(card) not_high_cards_set = set(my_cards) - set(high_cards) not_high_cards = list(not_high_cards_set) if len( high_cards ) == 2: # if we have a pair of high cards, then make sure they're both on the third board self.board_allocations[2] = high_cards[0:2] self.board_allocations[0] = not_high_cards[0:2] self.board_allocations[1] = not_high_cards[2:4] elif len( high_cards ) == 1: # if we have one high card, then make sure it's on the third board self.board_allocations[2] = [high_cards[0], []] self.board_allocations[0] = not_high_cards[0:2] self.board_allocations[1] = not_high_cards[2:4] self.board_allocations[2][1] = not_high_cards[4] elif len(high_cards) == 4: # big money self.board_allocations[2] = high_cards[0:2] self.board_allocations[1] = high_cards[2:4] self.board_allocations[0] = not_high_cards[0:2] else: self.board_allocations[2] = my_cards[0:2] self.board_allocations[0] = my_cards[2:4] self.board_allocations[1] = my_cards[4:6] for i in range(NUM_BOARDS): if AssignAction in legal_actions[i]: my_actions[i] = AssignAction(self.board_allocations[i]) elif CheckAction in legal_actions[i]: # check-call my_actions[i] = CheckAction() else: my_actions[i] = CallAction() print(my_cards) return my_actions