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)]
Beispiel #6
0
    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)