def computeHS2( data ) : [pocket_assignment, board, EV_or_HS] = data if len(board) != 5 : print "HS2 only works on board lengths of 5" assert False results = {} d = Deck() d.remove( board ) valid = all([d.remove(pa) for pa in pocket_assignment]) if valid : r = pe.poker_eval( game=globles.GAME, \ pockets=pocket_assignment, \ board=board ) if EV_or_HS == 'EV' : for pocket,evl in zip( pocket_assignment, r["eval"] ) : results[canonicalize(pocket)] = evl["ev"] / float(globles.EV_RANGE) else : for i, pocket in enumerate(pocket_assignment) : wins = r["eval"][i]["winhi"] ties = r["eval"][i]["tiehi"] losses = r["eval"][i]["losehi"] hs = (wins + float(ties)/2) / (wins + ties + losses) hs2 = hs*hs; #if canonicalize(pocket) == '8d8c' : #print data, hs2 results[canonicalize(pocket)] = hs2 else : pass #raise Exception("Invalid Assignment") return results
def mapReduceComputeEHS2( pool, \ board, \ num_opponents = 1 ) : known_pockets = [['__','__']] dek = Deck() dek.shuffle() dek.remove( board ) remaining_cards = dek.cards possible_pockets = combinations( remaining_cards, globles.POCKET_SIZE ) possible_pocket_assignments = combinations( possible_pockets, \ num_opponents ) #map a = time() all_pockets_plus_globals = wrapWithGlobals( possible_pocket_assignments, \ known_pockets, \ remaining_cards, \ board, \ 'HS') mapped = pool.map( computeEHS2, all_pockets_plus_globals ) #mapped: [{pocket1: HS2, __: HS2},{pocket2: HS2, __:HS2},...] d_pocket_HS2 = {} for pocket_hs in mapped : for pocket in pocket_hs : if pocket != canonicalize(['__','__']) : d_pocket_HS2[pocket] = pocket_hs[pocket] #print d_pocket_HS2 return d_pocket_HS2
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 insertRepresentatives() : conn = db.Conn("localhost") for street_name in ['turn'] : #['flop','turn','river'] : dirname = "hsdists/%ss/" % street_name fin = open("%s/special_representatives.txt" % dirname) reps = load( fin.read() ) fin.close() for cboard in reps : aboard = canonicalize( reps[cboard] ) conn.insert('REPRESENTATIVES',[cboard,aboard] )
def computeSingleEHS2( pocket, board ) : print pocket r = computeEHS2( [ [['__','__'],pocket], board, 'HS' ] ) return r[canonicalize(pocket)]
def registerRevealedPockets(self, player_names, pockets): # TODO: handle preflop strength via some table for street in range(self.street): # for street in range(len(self.past_actions)) : self.buckets.append([0] * len(player_names)) for player_name, pocket in zip(player_names, pockets): pix = self.players.index(player_name) if street == 0: street_name = "preflop" q = """select memberships from %s%s where pocket = '%s'""" % ( BUCKET_TABLE_PREFIX, street_name.upper(), canonicalize(pocket), ) else: if street == 1: board = self.board[:3] street_name = "flop" elif street == 2: board = self.board[:4] street_name = "turn" elif street == 3: board = self.board street_name = "river" cboard = collapseBoard(board) q = """select aboard from REPRESENTATIVES where cboard = '%s'""" % ( cboard ) # print q try: [[aboard]] = self.conn.query(q) except Exception as ve: self.ratio_file.write("%s\n\n" % q) aboard = listify(aboard) # pocket:board::apocket:aboard # print "board",board # print "aboard", aboard apocket = symmetricComplement(board, pocket, aboard) # apocket = 'AhAs' # print "pocket",pocket # print "apocket", apocket q = """select memberships from %s%s where cboard = '%s' and pocket = '%s'""" % ( BUCKET_TABLE_PREFIX, street_name.upper(), cboard, apocket, ) # print q try: [[memberships]] = self.conn.query(q) except Exception as ve: message = "cboard: %s\naboard: %s\npocket: %s\n\n" % (cboard, aboard, pocket) self.ratio_file.write(message) ve.message = message raise ve # TODO # eventually the beliefs should be a continuous node, # for now let's just # cram it into the closest to the average memberships = [float(t) for t in memberships.split(":")] # print "memberships: ", memberships # print "membs", memberships # we want the buckets to be from 1->N, not 0->N-1 w = [(i + 1) * m for i, m in enumerate(memberships)] # print "w:", w bucket = int(round(sum(w))) # print "bucket,", bucket self.buckets[street][pix] = bucket
def testSymmetric() : conn = db.Conn("localhost") tests = [] #cboard is 455_p_r #representative is 4h5d5c board = ['4d','5h','5c'] pocket = ['5d','7s'] tests.append( (board,pocket,'FLOP') ) #cboard is 9TQ_h_2fxox #rep is 9hQhTd board = ['9s','Qs','Tc'] pocket = ['7h','Th'] tests.append( (board,pocket,'FLOP') ) #cboard is 34QK_h_3foxxx #rep is 3h3dQdKd board = ['3s','3h','Qh','Kh'] pocket = ['7h','Tc'] tests.append( (board, pocket, 'TURN') ) #cboard is #rep is 2h 4h 7d 9d Ad board = ['2c','4h','7d','9h','Ah'] pocket = ['3c','Kh'] tests.append( (board,pocket,'RIVER') ) #cboard is 2335K_p_4f #2h3h5hKh3d board = ['2c','3d','3c','5c','Kc'] pocket = ['5s','Qc'] tests.append( (board,pocket,'RIVER') ) board = ['5c','5d','7c','7d','Qs'] pocket = ['6c','Qh'] tests.append( (board,pocket,'RIVER') ) for (board,pocket,street_name) in tests : cboard = collapseBoard( board ) #print "cboard", cboard q = """select aboard from REPRESENTATIVES where cboard = '%s'""" % \ (cboard) [[aboard]] = conn.query(q) #print "board", board #print "aboard", listify(aboard) #print "pocket", pocket pocketp = listify( symmetricComplement( board, \ pocket,\ listify(aboard) ) ) #print "pocketp: " , pocketp ehs2 = rollout.computeSingleEHS2( pocket, board ) print ehs2 q = """select ehs2 from EHS2_%s where cboard = '%s' and pocket = '%s'""" % (street_name, \ cboard, \ canonicalize(pocketp) ) [[ehs2p]] = conn.query(q) ehs2p = float(ehs2p) print ehs2p assert round(ehs2,4) == round(ehs2p,4)
def computeBucketTransitions( conn, cboard, cboard_prime, \ pocket_membs=False, pocket_prime_membs=False) : #if cboard is blank, that means it is preflop. "dummy" was inserted as #cboard value in BUCKET_EXPO_PREFLOP if cboard == "" : cboard = "dummy" print cboard, cboard_prime #get the aboards, for which the EHS2 and buckets have been computed q = "select aboard from REPRESENTATIVES where cboard = '%s'" if cboard != "dummy" : aboard = conn.queryScalar( q % cboard, listify ) aboard_prime = conn.queryScalar( q % cboard_prime, listify ) #street names and bucket sizes if len(aboard_prime) == 5 : street_prime = 'river' street = 'turn' elif len(aboard_prime) == 4 : street_prime = 'turn' street = 'flop' elif len(aboard_prime) == 3 : street_prime = 'flop' street = 'preflop' else : assert False nbuckets = len(globles.BUCKET_PERCENTILES[street]) nbuckets_prime = len(globles.BUCKET_PERCENTILES[street_prime]) #setup the output P[bucket] = {bucket_prime : prob, ...} P = {} for bucket in range( nbuckets ) : P[bucket] = {} legal_pockets = [] #the memberships against cboard_prime if not pocket_prime_membs : pocket_prime_membs = {} q = """select pocket, memberships from %s%s where cboard = '%s'""" % \ (globles.BUCKET_TABLE_PREFIX, \ street_prime.upper(), \ cboard_prime) for p_prime,membs in conn.query(q) : legal_pockets.append(p_prime) pocket_prime_membs[p_prime] = [float(m) for m in membs.split(':')] else : pass #print "p_prime memberships built" #the memberships against cboard pocket_membs = {} if not pocket_membs : q = """select pocket, memberships from %s%s where cboard = '%s'""" % \ (globles.BUCKET_TABLE_PREFIX, \ street.upper(), \ cboard) for p,membs in conn.query(q) : pocket_membs[p] = [float(m) for m in membs.split(':')] else : pass #print "p memberships built" #determine the pocket map between prime and aboard pocket_map = {} no_map_necessary = (cboard == "dummy") or (aboard == aboard_prime[:-1]) if no_map_necessary : for pocket in legal_pockets : pocket_map[pocket] = pocket else : #print aboard, aboard_prime #print aboard_prime, cboard_prime #figure out which card, when added to aboard, gives cboard_prime #call this aboard_prime_wish aboard_prime_wish = completeStemToMakeCboard( aboard, cboard_prime ) print aboard_prime_wish #new set of legal_pockets legal_pockets = [] dek = Deck() dek.shuffle() dek.remove(aboard_prime_wish) for p in combinations( dek.cards, 2) : legal_pockets.append(canonicalize(list(p))) #print "wish", aboard_prime_wish, collapseBoard(aboard_prime_wish) #find mapping between aboard_prime and wish for pocket in legal_pockets : #print pocket symm_pocket = symmetricComplement( aboard_prime_wish, \ pocket, \ aboard_prime ) pocket_map[pocket] = symm_pocket #main computation C = 1 / float(len(legal_pockets)) for k in range(nbuckets) : for k_prime in range(nbuckets_prime) : s = 0 for p in legal_pockets : p_prime = pocket_map[p] A = pocket_prime_membs[p_prime][k_prime] B = pocket_membs[p][k] s += A*B*C P[k][k_prime] = s dist = [] marginals = [] total_sum = 0 for k in range(nbuckets) : conditionals = [] for k_prime in range(nbuckets_prime) : conditionals.append( round(P[k][k_prime],6) ) marg = sum(conditionals) total_sum += marg if marg > 0 : cond_sum = sum([c / marg for c in conditionals]) assert .99 < cond_sum < 1.01 dist.append( ",".join( [str(c) for c in conditionals] ) ) assert .99 < total_sum < 1.01 dist = ';'.join(dist) conn.insert( 'TRANSITIONS_%s' % street_prime.upper(), \ ["%s|%s" % (cboard, cboard_prime),dist], \ skip_dupes=True)