def makeArray( self): #can you cut down on hand combos here through isomorphism? x = 0 printProgressBar(x, 812000) for i in range(NUM_CARDS): for j in range(NUM_CARDS): if i >= j: continue for a in range(NUM_CARDS): if a == i or a == j: continue for b in range(NUM_CARDS): if a >= b: continue if b == i or b == j or b == a: continue if self.eArray[a][b][i][j] != 0: self.eArray[i][j][a][ b] = 1 - self.eArray[a][b][i][j] continue # self.eArray[i][j][a][b] = 1 hand = str_to_cards(" ".join([CARDS[i], CARDS[j]])) villainHand = HandRange(" ".join([CARDS[a], CARDS[b]])) board = str_to_cards(" ".join(self.board)) self.eArray[i][j][a][b] = py_hand_vs_range_monte_carlo( hand, villainHand, board, 200000) x += 1 printProgressBar(x, 812000) numpy.save(self.getFilename(), self.eArray)
def test_hand_vs_range_monte_carlo(self): hand = map(eval7.Card, ("As", "Ad")) villain = eval7.HandRange("AA, A3o, 32s") board = [] equity = eval7.py_hand_vs_range_monte_carlo(hand, villain, board, 10000000) self.assertAlmostEqual(equity, 0.85337, delta=0.002)
def test_hand_vs_range_monte_carlo(self): hand = map(eval7.Card, ("As", "Ad")) villain = eval7.HandRange("AA, A3o, 32s") board = [] equity = eval7.py_hand_vs_range_monte_carlo( hand, villain, board, 10000000 ) self.assertAlmostEqual(equity, 0.85337, delta=0.002)
def river_action_wrapped(cards, board_cards, opponents, bet, pot, raised=False, first_bet=False, pot_type=2): hand = [eval7.Card(s) for s in (cards[:2], cards[2:])] board = [ eval7.Card(s) for s in [board_cards[i:i + 2] for i in range(0, len(board_cards), 2)] ] current_hand = eval7.hand_type(eval7.evaluate(hand + board)) # if you have nuts, raise or jam RFI = "22+, 32s, 53s+, 63s+, 74s+, 84s+, 95s+, T6s+, J6s+, " \ "Q4s+, K2s+, A2s+, A2o+, K8o+, Q8o+, J8o+, T8o+, 98o+" TBet = "ATo+, KJo+, QJo+, 44+, 65s, 76s, 87s, 97s+, T8s+, J9s+, Q9s+, K9s+, A2s+" FBet = "TT+, AJs+, KQs, AQo+" villain_ranges = {2: RFI, 3: TBet, 4: FBet} villain = eval7.HandRange(villain_ranges[pot_type]) equity = eval7.py_hand_vs_range_monte_carlo(hand, villain, board, 1000) if raised: if equity > 0.99: return "Raise " + str(2.5 * bet) elif equity > 0.95: return "Call" else: return "Fold" if equity > 0.97: if bet > 0: return "Raise " + str(2.5 * bet) else: return "Bet " + str(0.8 * pot) # else, look into non-raising methods # multi-way pot if opponents > 1: # someone bet, only call if top pair or better (< 2 rounds of bets) if bet > 0: if first_bet: if current_hand != 'High Card' and not play_the_board( cards, board_cards): if current_hand == 'Pair': if not tpttk(cards, board_cards): return "Fold" return "Call" if play_the_board(cards, board_cards): return "Fold" if current_hand == 'High Card' or current_hand == 'Pair': return "Fold" elif current_hand == 'Two Pair': if paired_card(board_cards) and max(list( board_cards[::2])) >= highest_two_pair( cards, board_cards): return "Fold" return "Call" else: return "Call" # no one bet, bet if you have trips or better if current_hand not in ['High Card', 'Pair', 'Two Pair' ] and not play_the_board(cards, board_cards): return "Bet " + str(pot * 0.8) else: return "Check" # heads up else: # someone bet, only call if enough equity, above 80% if bet > 0: if first_bet: if equity > bet / (bet + pot): return "Call" else: return "Fold" elif equity > 0.80: return "Call" else: return "Fold" else: if equity > 0.80: return "Bet " + str(pot * 0.8) else: return "Check"
def betting_round_2_wrapped(cards, board_cards, opponents, bet, pot, preflop_agg=False, position=False, raised=False, pot_type=2): hand = [eval7.Card(s) for s in (cards[:2], cards[2:])] board = [ eval7.Card(s) for s in [board_cards[i:i + 2] for i in range(0, len(board_cards), 2)] ] current_hand = eval7.hand_type(eval7.evaluate(hand + board)) if raised: if current_hand in ['High Card', 'Pair', 'Two Pair'] or play_the_board( cards, board_cards): return "Fold" else: return "Call" # multi-way pot, bluff less if opponents > 1: # someone bet again, only call if have top pair (if bet < pot) or better if bet > 0: if play_the_board(cards, board_cards): return "Fold" if current_hand == 'High Card': return "Fold" elif current_hand == 'Pair': if not tpttk(cards, board_cards): return "Fold" else: return "Call" elif current_hand == 'Two Pair': if paired_card(board_cards): return "Fold" return "Call" else: return "Call" # no one bet, bet if you are pre-flop aggressor IP if (preflop_agg or position) and current_hand not in ['High Card', 'Pair'] and \ not play_the_board(cards, board_cards): return "Bet " + str(pot * 0.70) else: return "Check" # heads up else: # since not playing limp pot, pots are either RFI, 3-bet, 4-bet+ RFI = "22+, 32s, 53s+, 63s+, 74s+, 84s+, 95s+, T6s+, J6s+, " \ "Q4s+, K2s+, A2s+, A2o+, K8o+, Q8o+, J8o+, T8o+, 98o+" TBet = "ATo+, KJo+, QJo+, 44+, 65s, 76s, 87s, 97s+, T8s+, J9s+, Q9s+, K9s+, A2s+" FBet = "TT+, AJs+, KQs, AQo+" villain_ranges = {2: RFI, 3: TBet, 4: FBet} villain = eval7.HandRange(villain_ranges[pot_type]) equity = eval7.py_hand_vs_range_monte_carlo(hand, villain, board, 1000) # someone bet, only call if above 75% equity, since second bullet if bet > 0: if equity > 0.75: return "Call" else: return "Fold" # no one bet, bet if you are pre-flop aggressor and have > 50% equity against range if (preflop_agg or position) and equity > 0.5: return "Bet " + str(pot * 0.7) else: return "Check"
def betting_round_1_wrapped(cards, board_cards, opponents, bet, pot, preflop_agg=False, position=False, raised=False, pot_type=2): hand = [eval7.Card(s) for s in (cards[:2], cards[2:])] board = [ eval7.Card(s) for s in [board_cards[i:i + 2] for i in range(0, len(board_cards), 2)] ] current_hand = eval7.hand_type(eval7.evaluate(hand + board)) if raised: if current_hand in ['High Card', 'Pair'] or play_the_board( cards, board_cards): return "Fold" elif current_hand == 'Two Pair': if paired_card(board_cards) and paired_card( board_cards) >= highest_two_pair(cards, board_cards): return "Fold" return "Call" else: return "Call" # multi-way pot, bluff less if opponents > 1: # someone bet, only call if have pair, oesd, fd if bet > 0: if play_the_board(cards, board_cards): return "Fold" if current_hand == 'High Card': # want a good flush draw, or an oesd w/ hole cards if bet < pot and (good_flush_draw(cards, board_cards) or (oesd(cards, board_cards) and not oesd("", board_cards))): return "Call" return "Fold" elif current_hand == 'Pair' and bet > 0.5 * pot: return "Fold" else: return "Call" # no one bet, bet if you are pre-flop aggressor IP if (preflop_agg or position ) and current_hand != 'High Card' and not play_the_board( cards, board_cards): return "Bet " + str(pot / 3) else: return "Check" # heads up else: # since not playing limp pot, pots are either RFI, 3-bet, 4-bet+ RFI = "22+, 32s, 53s+, 63s+, 74s+, 84s+, 95s+, T6s+, J6s+, " \ "Q4s+, K2s+, A2s+, A2o+, K8o+, Q8o+, J8o+, T8o+, 98o+" TBet = "ATo+, KJo+, QJo+, 44+, 65s, 76s, 87s, 97s+, T8s+, J9s+, Q9s+, K9s+, A2s+" FBet = "TT+, AJs+, KQs, AQo+" villain_ranges = {2: RFI, 3: TBet, 4: FBet} villain = eval7.HandRange(villain_ranges[pot_type]) equity = eval7.py_hand_vs_range_monte_carlo(hand, villain, board, 1000) # someone bet, only call if enough equity if bet > 0: if equity > bet / (bet + pot): return "Call" else: return "Fold" # no one bet, bet if you are pre-flop aggressor and have > 50% equity against range if (preflop_agg or position) and equity > 0.5: return "Bet " + str(pot / 3) else: return "Check"
t1 = perf_counter() result = py_equities_2hands(hand1, hand2, board) t2 = perf_counter() print(f"py_equities_2hands: {t2 - t1:0.8f} sec, result={result[0]:2.8f}") t1 = perf_counter() result = py_outcome_breakdown(board, hand1, hand2) t2 = perf_counter() print(f"py_outcome_breakdown: {t2 - t1:0.8f} sec, result={result}") hand2 = HandRange(h2) t1 = perf_counter() result = py_hand_vs_range_monte_carlo(hand1, hand2, board, 200000) t2 = perf_counter() print( f"py_hand_vs_range_monte_carlj: {t2 - t1:0.8f} sec, result={result:2.8f}") hand1 = h1.split() hand2 = h2.split() t1 = perf_counter() result = getEquityVsHandFast(pe_string2card(hand1), pe_string2card(hand2), ea) t2 = perf_counter() print(f'{hand1} vs {hand2}') print(f"getEquityFast: {t2 - t1:0.8f} sec, result={result:2.8f}") t1 = perf_counter()
def get_action(self, game_state, round_state, active): ''' Where the magic happens - your code should implement this function. Called any time the engine needs an action from your bot. Arguments: game_state: the GameState object. round_state: the RoundState object. active: your player's index. Returns: Your action. ''' 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, river, or turn respectively #my_cards = round_state.hands[active] # your cards #board_cards = round_state.deck[:street] # the board cards my_pip = round_state.pips[ active] # the number of chips you have contributed to the pot this round of betting opp_pip = round_state.pips[ 1 - active] # the number of chips your opponent has contributed to the pot this round of betting 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 #continue_cost = opp_pip - my_pip # the number of chips needed to stay in the pot my_contribution = STARTING_STACK - my_stack # the number of chips you have contributed to the pot opp_contribution = STARTING_STACK - opp_stack # the number of chips your opponent has contributed to the pot #if RaiseAction in legal_actions: # min_raise, max_raise = round_state.raise_bounds() # the smallest and largest numbers of chips for a legal bet/raise # min_cost = min_raise - my_pip # the cost of a minimum bet/raise # max_cost = max_raise - my_pip # the cost of a maximum bet/raise # "check" down if already all-in if len(legal_actions) == 1: return CheckAction() # x/f to victory if we can print(game_state.bankroll, NUM_ROUNDS, game_state.round_num) if game_state.bankroll > ceil((NUM_ROUNDS - game_state.round_num) * (SMALL_BLIND + BIG_BLIND) / 2): return CheckAction( ) if CheckAction in legal_actions else FoldAction() # Simple hardcoded / eval7 strategy. street = round_state.street my_hand = round_state.hands[active] board = round_state.deck[:street] # reorder cards for consistent key in dict my_hand = my_hand[::-1] if CARDS.index(my_hand[0]) < CARDS.index( my_hand[1]) else my_hand my_hand_trans = [ ALL_RANKS[self.value_ranks[c[0]]] + c[1] for c in my_hand ] my_hand_trans_e7 = convert_e7(my_hand_trans) trans_board = [ALL_RANKS[self.value_ranks[c[0]]] + c[1] for c in board] board_trans_e7 = convert_e7(trans_board) print(my_hand, board) print(my_hand_trans, trans_board, '(translated)') # raise sizes # these are parameters to be tweaked (maybe by stats on opponent) if street == 0: RAISE_SIZE = 1 # raise (1x)pot else: RAISE_SIZE = 0.75 # bet 3/4 pot if street == 0: equity = get_preflop_equity(my_hand_trans_e7, self.opponent_range) print(f'Preflop equity {equity}') else: equity = eval7.py_hand_vs_range_monte_carlo( my_hand_trans_e7, get_v_range(self.opponent_range), board_trans_e7, self.N_MCMC) print(f'Postflop equity {equity}') if my_pip == 1 and street == 0: pot_odds = 0.4 raise_odds = 0.45 if opp_pip > my_pip: self.opponent_range *= 0.5 else: pot = 2 * my_contribution bet = opp_pip - my_pip pot_odds = bet / (pot + 2 * bet) raise_amt = int(RAISE_SIZE * pot) + opp_pip raise_odds = raise_amt / (pot + 2 * raise_amt) print('pot odds = ', pot_odds, 'raise odds = ', raise_odds) if equity > raise_odds and opp_contribution < STARTING_STACK: raise_size = min(int(opp_pip + RAISE_SIZE * 2 * opp_contribution), my_pip + my_stack) print('RAISE:', raise_size) return RaiseAction(raise_size) elif equity > pot_odds and opp_pip > my_pip: print('CALL') return CallAction() elif my_pip == opp_pip: print('CHECK') return CheckAction() else: return FoldAction()
#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Created on Sun Jan 14 20:42:30 2018 @author: ant """ import eval7 import pprint hand = map(eval7.Card, ("As", "Kd")) villain = eval7.HandRange("2c 2s") board = [] equity_monte = eval7.py_hand_vs_range_monte_carlo(hand, villain, board, 1000000) equity_exact = eval7.py_hand_vs_range_exact(hand, villain, board) print(equity_monte) print(equity_exact)