def computeEHS2( data ) : [pocket_assignment, board, EV_or_HS] = data d = Deck() d.remove( board ) valid = all([d.remove(pa) for pa in pocket_assignment]) results = {} if valid : canonical_pockets = [canonicalize(p) for p in pocket_assignment] num_unknown_board = 5-len(board) HS2sums = {} counts = {} for pocket in canonical_pockets : HS2sums[pocket] = 0 counts[pocket] = 0 for board_suffix in combinations( d.cards, num_unknown_board ) : full_board = board + makeHuman(board_suffix) #print makeHuman(pocket), full_board data = [ pocket_assignment, full_board, EV_or_HS] HS2s = computeHS2(data) for pocket in canonical_pockets : HS2sums[pocket] += HS2s[pocket] counts[pocket] += 1 for pocket in canonical_pockets : results[pocket] = HS2sums[pocket] / float(counts[pocket]) return results
def __str__(self): r = [] r.append("Table:") r.append(" Player Names: %s" % "; ".join(self.players)) pocks = [str(makeHuman(p)) for p in self.pockets] r.append(" Pockets: %s" % "; ".join(pocks)) r.append(" Folded: %s" % "; ".join([str(f) for f in self.folded])) r.append(" Stacks: %s" % "; ".join([str(s) for s in self.stacks])) r.append(" Button: %s" % self.players[self.button]) r.append(" Street: %s" % self.street) r.append(" Board: %s" % " ".join(makeHuman(self.board))) r.append(" Pot: %f" % self.pot) r.append(" Current Bets: %s" % "; ".join([str(cb) for cb in self.current_bets])) r.append(" Committed: %s" % "; ".join([str(c) for c in self.committed])) r.append(" Action To: %s" % self.players[self.action_to]) return "\n".join(r)
def computeEHS2DistsLongways_special() : pool = Pool( processes = 8 ) count = 0 timea = time() for board_size in range(4,5) : start_time = time() already_repped = {} if board_size == 3 : street_name = 'flops' print_every = 10 elif board_size == 4 : street_name = 'turns' print_every = 100 else : street_name = 'rivers' print_every = 1000 count = 0 for board in combinations( range(52), board_size ) : cboard = collapseBoard( board ) if cboard.endswith( "_p_22f" ) and cboard not in already_repped : d_pocket_EHS2 = rollout.mapReduceComputeEHS2( pool,list(board) ) filename = "hsdists/%s/%s.hsdist" % (street_name, cboard) fout = open( filename, 'w' ) fout.write( json.dumps( d_pocket_EHS2 ) ) fout.close() already_repped[cboard] = makeHuman(board) else : pass count += 1 if count % print_every == 0 : print "board_size: ", board_size, " count: ", count print "time: ", time() - timea timea = time() fout = open("hsdists/%s/special_representatives.txt" % street_name, 'w' ) fout.write( json.dumps( already_repped ) ) fout.close() print "time for board_size: ", board_size, " was: ", time() - start_time pool.close()
def computeDists(num_known_board, EV_or_HS) : already_seen = {} count = 0 if num_known_board == 3 : street = 'flops' elif num_known_board == 4 : street = 'turns' elif num_known_board == 5 : street = 'rivers' else : assert False for board in combinations( d.cards, num_known_board ) : collapsed = collapseBoard( board ) if EV_or_HS == 'EV' : path = "evdists/%s/%s.evdist" % (street,collapsed) else : path = "hsdists/%s/%s.hsdist" % (street,collapsed) if collapsed in already_seen or exists(path) : continue else : print count, collapsed count += 1 board = makeHuman(board) + ['__']*(5-num_known_board) x = [] if EV_or_HS == 'EV' : d_pocket_EV = rollout.computeEVs( [], board, 2, num_threads=4 ) for ev in d_pocket_EV.values() : x.append( makeRound( ev ) ) else : d_pocket_HS = rollout.computeHSs( board, num_threads=4 ) for hs in d_pocket_HS.values() : x.append( hs ) x.sort() fout = open(path, 'w') fout.write( "%s\n" % ';'.join([str(t) for t in x]) ) fout.close() already_seen[collapsed] = True
def newHand(self, players, pockets, stacks, button): # TODO, probably be setting button, no guarantee of constant player # as table progresses in hand histories # self.advanceButton() self.num_players = len(players) self.button = button if self.num_players > 2: self.action_to = self.ringIncrement(self.button, self.num_players) else: self.action_to = self.button self.players = players self.stacks = stacks self.pockets = pockets # [deck.draw(2) for i in range(self.num_players)] # self.pockets = [[FOLDED]*POCKET_SIZE]*self.num_players self.folded = [False] * self.num_players self.acted = [False] * self.num_players self.current_bets = [0] * self.num_players self.passive_pip = [0] * self.num_players self.aggressive_pip = [0] * self.num_players self.committed = [0] * self.num_players self.pot = 0 # will worry about this bridge when we come to it self.side_pot = {} self.board = makeHuman([WILDCARD] * 5) self.streets = iter(STREET_NAMES) ##extra one to take it out of uninit state self.street = self.streets.next() # self.street = self.streets.next() # print "new hand, street: ", self.street self.aggressor = -1 # will be multi-dimensional list # 1st dim = street 0 - 3 # 2nd dim = player 0 - (self.num_players-1) # 3rd dim = particular feature. The last one is the EHS2 belief self.past_actions = [] self.buckets = [] # record the actions that comprise each betting round self.active_actions = [] self.re_raises = [] self.features = { # DONE (defacto) "active_players": len(players), "total_players": len(players), # done, though these aren't the actual features themselves # (they are ratios of passive v active on different streets "num_aggressive_actions": [0] * 4, "num_past_actions": [0] * 4, "all_in_with_call": False, # TODO: done, but seems not useful. The implied odds lower down # seem much more informative. We have X to call. Is that a lot? # Who knows? Need vs the blind amount, or something "amount_to_call": -1, # TODO. Not done. # perhaps instead we could introduce the mean, var of HS2 for board # or could give prob to each type of hand being made (hard?) # don't like these board features, feel they are very rough "average_rank": -1, "high_card_flop": -1, "high_card_turn": -1, "high_card_river": -1, "max_cards_suited": [0] * 4, "max_cards_same_rank": -1, "num_different_high_cards": -1, "straight_possibilties": [0] * 4, # done "callers_since_last_raise": -1, # TODO. not done. what good is effective stack. # Just a number, with no # way to gauge it's significance or not. I wanna know how # big/short stacked I am relative to the baddest active, not the # absolute number, right? # either way, when compute, make sure to compare the # committed + stack numbers. If someone hasn't acted yet, # it will artificially inflate their stack size "effective_stack_vs_active": -1, "effective_stack_vs_aggressor": -1, # done "implied_odds_vs_aggressor": -1, "in_position_vs_active": False, "in_position_vs_aggressor": False, # done "num_bets": [0] * 4, "off_the_button": -1, # TODO: a little more involved "own_previous_action": -1, "own_previous_action_category": -1, # TODO easily done, how additionally informative after callers # since last raise? oh, could be useful to know how many have # folded vs how many stayed in? "players_acted": 0, # TODO: isn't this just off_the_button? "players_left_to_act": 0, "pot_odds": -1, "pot_size": 0, "stack_size": self.stacks[self.action_to], "was_aggressor": [False] * 4, # totalPIP/BB, totalPIP/effstack, aggPIP/totalPIP, passPIP/totalPIP "summarized_bets": [[[0] * 4] * self.num_players for i in range(4)], }
def advanceStreet(self, cards): # if we are out of streets and try to advance, do nothing try: self.street = self.streets.next() except StopIteration: return # pointless to report actions about automatic blinds # (remember self.streets already incremented here) if self.street > 0: acted_players = [player for player in range(self.num_players) if self.acted[player]] ##DEPRECATED, not using crude aggregates ##see parsing, goes through the actions for the round and ##merges into super-action # action_state = [] # for p in acted_players : # player_state = [] ##when looking for appropriate bet ratios # pip_to_pot = self.current_bets[p] / float(self.pot) ##self.ratio_file.write( "%f\n" % (pip_to_pot) ) ##print pip_to_pot # closest_ratio = closestRatio( pip_to_pot, 'past' ) # player_state.append( closest_ratio ) ##bet_ratio_added = True # ##Inherent in network structure now ##the left side is always first to act ###1 if in position, last to act ###TODO: hardcoded for heads up ###if advancing from preflop ##if self.street == 1 : ##action_state.append( int(self.button != p ) ) ##else : ##action_state.append( int(self.button == p) ) # # ##1 if aggressive PIP ratio # was_agg = int(self.aggressive_pip[p] > 0) # player_state.append( was_agg ) # ##did_re_raise = 0 ##for act in self.active_actions[self.street-1][p][1:] : ##if 'rt' in act or 'r' in act : did_re_raise = 1 ##player_state.append( did_re_raise ) ##print self.re_raises ##print self.re_raises[-1][p] # player_state.append( int(self.re_raises[-1][p]) ) # # action_state.append( player_state ) # ##meaningless to register actions where no one acts ##this can happend when an all-In is called ##future streets are dealt but there are no actions to take # if len(acted_players) > 0 : # self.past_actions.append( action_state ) # make space for the next street # TODO hardcoded for 2p self.active_actions.append([[], []]) self.re_raises.append([False, False]) # bookkeeping if cards: # remember self.street has already been advanced by now if self.street == 1: self.board[:3] = cards elif self.street == 2: self.board[3] = cards[0] elif self.street == 3: self.board[4] = cards[0] if self.street > 0: self.current_bets = [0] * self.num_players self.passive_pip = [0] * self.num_players self.aggressive_pip = [0] * self.num_players self.acted = [False] * self.num_players self.action_to = self.nextUnfoldedPlayer(self.button) if self.logging: self.history.update(self.street, makeHuman(self.board))
def sampleTransitionProbs( street, n_samples, bucket_percentiles ) : pool = Pool( processes = 4 ) dirname = "hsdists/%ss" % street fout1 = open( "%s/transition_names.txt" % dirname, 'w' ) fout2 = open( "%s/transition_probs.txt" % dirname, 'w' ) write_buffer_1 = [] write_buffer_2 = [] # [[cboard, cboard', tran probs],[],...] fin = open( "%s/collapsed_representatives.txt" % dirname ) representatives = load( fin.read() ) fin.close() bkt_filenames = ["%s/%s" % (dirname, file) \ for file in listdir( dirname ) \ if file.endswith('bkts')] dek = Deck() for bkt_filename in sample( bkt_filenames, n_samples ) : timea = time() fin = open( bkt_filename) d_pocket_buckets = load( fin.read() ) fin.close() [rest,fileext] = bkt_filename.rsplit('/',1) [file,ext] = fileext.rsplit('.',1) actual_board = [str(t) for t in representatives[file]] dek.remove( actual_board ) #enumerate the possible collapsed flops d_cboard_aboard = {} for next_card in dek.cards : aboard = actual_board + makeHuman([next_card]) cboard = collapseBoard( aboard ) if cboard not in d_cboard_aboard : d_cboard_aboard[cboard] = aboard for cboard in d_cboard_aboard : print bkt_filename, aboard aboard = d_cboard_aboard[cboard] d_pocket_EHS2 = rollout.mapReduceComputeEHS2( pool, aboard ) d_pocket_buckets_prime = computeBucket( d_pocket_EHS2, bucket_percentiles[street] ) n_buckets = len(bucket_percentiles[street]) if street == "flop" : n_buckets_prime = len(bucket_percentiles['turn']) elif street == 'turn' : n_buckets_prime = len(bucket_percentiles['river']) else : assert False #print actual_board, aboard tprobs = getTransitionProbs( d_pocket_buckets, \ n_buckets, \ d_pocket_buckets_prime, \ n_buckets_prime ) prob_vector = [] for b in range(n_buckets) : for bprime in range(n_buckets_prime) : if b in tprobs and bprime in tprobs[b] : prob_vector.append( tprobs[b][bprime] ) else : prob_vector.append( 0.0 ) #write_buffer_1.append( "%s\t%s" % (file,cboard) ) fout1.write( "%s\t%s\n" % (file,cboard) ) fout2.write( dump( prob_vector, width=6000 )[1:-2] + "\n" ) #write_buffer_2.append ( prob_vector ) #print bkt_filename #print len(d_cboard_aboard) dek.shuffle() #fout1.write( dump( write_buffer_1 ) ) #fout2.write( dump( write_buffer_2, width=5000 )[2:] ) #write_buffer_1 = [] #write_buffer_2 = [] timeb = time() print "board: ", bkt_filename, " took: ", timeb-timea pool.close()
def computeEHS2Dists() : already_repped = set([]) results = {} count = 0 a = time() for board in combinations( range(52), 5 ) : count += 1 if count % 100 == 0 : print count print time() - a a = time() #pit every possible hand against 'mystery' known_pocket #and compute the HS2 from rollout known_pockets = ['__','__'] d_pocket_HS2 = rollout.mapReduceComputeEHS2( list(board) ) flop = ''.join( makeHuman(board[0:3]) ) cflop = collapseBoard( flop ) turn = ''.join( makeHuman(board[0:4]) ) cturn = collapseBoard( turn ) river = ''.join( makeHuman(board) ) if river == '2s2c3s4s5s' : print d_pocket_HS2 assert False criver =collapseBoard( river ) streets = [flop,turn,river] cstreets = [cflop, cturn, criver] for street, cstreet in zip(streets[:2],cstreets[:2]) : if cstreet not in already_repped and street not in results : results[street] = {} for cstreet in cstreets : already_repped.add( cstreet ) #rounding precision precision = 4 #collect the HS2 for the river river_hs2 = {} for pocket in d_pocket_HS2 : hs2 = d_pocket_HS2[pocket] #flop and turn for street in streets[:2] : if street in results : if pocket not in results[street] : results[street][pocket] = [hs2,1] else : results[street][pocket][0] += hs2 results[street][pocket][1] += 1 else : pass #already_repped river_hs2[pocket] =makeRound(hs2,precision) #the 5 card board is unique, so we can print out right away name = "hsdists/rivers/%s.hsdist" % criver if not exists(name) : friver = open( name, 'w' ) friver.write( json.dumps( river_hs2 ) ) #friver.write( ";".join( [str(t) for t in sorted(river_hs2)] ) + "\n" ) friver.close() pass if count == 500 : #fout = open("test.txt",'w') #fout.write( json.dumps(results) ) #fout.close() break pass print "printing" #once all the boards are done, have results[board][pocket] = HS2sum, count for board in results : collapsed_board = collapseBoard( board ) num_cards = len(collapsed_board.split('_')[0]) if num_cards == 3 : street_name = 'flops' elif num_cards == 4 : street_name = 'turns' else: assert False #print "collapsed name:", collapsed_board, " street name: " , street_name d_pocket_EHS2 = {} for pocket in results[board] : (HS2sum, count) = results[board][pocket] ehs2 = makeRound( HS2sum / count, precision ) d_pocket_EHS2[pocket] = ehs2 filename = "hsdists/%s/%s.hsdist" % (street_name, collapsed_board) fout = open( filename, 'w' ) #print "len HS2s: ", len(HS2s) fout.write( json.dumps( d_pocket_EHS2 ) ) #fout.write( ';'.join( [str(t) for t in sorted(HS2s)] )+"\n" ) fout.close() #chunked version that is not any faster, you dolt #def iterateTransitions() : #transitions = {} #conn = db.Conn("localhost") #street = 'turn' #street_prime = 'river' # #chunk_size = 100 #cboards_chunk = [] #for i, board_prime in enumerate( combinations( range(52), 5 ) ): ##19148.pts-5.genomequery ##if i < 59601 or i >= 500000: continue # ##2529.pts-4.genomequery ##if i < 535098 or i >= 1000000: continue #if i < 600000 : continue # ##3567.pts-4.genomequery ##if i < 1000056 or i >= 1500000: continue #finished #if i < 2300000 : continue #3601.pts-4.genomequery #if i < 1507912 or i >= 2000000: continue #3718.pts-4.genomequery #if i < 2000007 : continue print i if len(cboards_chunk) == chunk_size : cboard_where = [] cboard_prime_where = [] for cboards in cboards_chunk : cboard, cboard_prime = cboards.split('|') cboard_where.append("cboard = '%s'" % cboard ) cboard_prime_where.append( "cboard = '%s'" % cboard_prime ) cboard_where = ' or '.join( cboard_where ) cboard_prime_where = ' or '.join( cboard_prime_where ) #query q_prime = """select pocket, memberships from %s%s where %s""" % \ (globles.BUCKET_TABLE_PREFIX, \ street_prime.upper(), \ cboard_prime_where) q = """select pocket, memberships from %s%s where %s""" % \ (globles.BUCKET_TABLE_PREFIX, \ street.upper(), \ cboard_where) print q_prime for pocket, memb in conn.query( q_prime ) : pass for pocket, memb in conn.query( q ) : pass for cboards in cboards_chunk : #build select dictionary #computeBucketTransitions( conn, cboard, cboard_prime ) pass cboards_chunk = [] a = raw_input() board = board_prime[:-1] cboard = collapseBoard(board) cboard_prime = collapseBoard(board_prime) cboards = "%s|%s" % (cboard, cboard_prime) q = "select count(*) from TRANSITIONS where cboards = '%s'" % cboards count = conn.queryScalar(q, int) if count > 0 : cboards_chunk.append( cboards ) else : print "skipping", cboards print len(transitions)