a ꒘e=@sDddlZddlmZddlmZGdddeZGdddeZdS)N)Card)Deckc@seZdZdZdZdZdZdZdZdZ dZ d Z ed ed ed ed edede de de di Z dddddddddd Z ddZdd Zd!d"Zd#d$Zd%d&Zd'd(Zd)S)* LookupTable iBi?iIi i i)i& zStraight FlushzFour of a Kindz Full HouseFlushStraightzThree of a KindzTwo PairPairz High Card) rrr r r r r rrcCs i|_i|_||dS)z* Calculates lookup tables N) flush_lookupunsuited_lookupflushes multiplesselfr@/Users/seanglover/Development/deuces-rs/deuces3/evaluator_mvp.py__init__;szLookupTable.__init__c Csgd}g}|tdd}tdt|dD]4}t|}d}|D]}||AsDd}qD|r0||q0|d}|D] }t|} ||j | <|d7}qvt j d}|D] }t|} ||j | <|d7}q| ||dS) z Straight flushes and flushes. Lookup is done on 13 bit integer (2^13 > 7462): xxxbbbbb bbbbbbbb => integer hand index ) iiiii|>i0b11111rirTFN) %get_lexographically_next_bit_sequenceintrangelennextappendreverserprime_product_from_rankbitsrrMAX_FULL_HOUSEstraight_and_highcards) rstraight_flushesrgenifnotSFsfrank prime_productrrrrHs.        zLookupTable.flushescCsdtjd}|D] }t|}||j|<|d7}qtjd}|D] }t|}||j|<|d7}q>dS)zx Unique five card sets. Straights and highcards. Reuses bit sequences from flush calculations. rN)r MAX_FLUSHrr(rMAX_PAIR)r straights highcardsr1sr2hrrrr*s       z"LookupTable.straight_and_highcardscCstttjddd}tjd}|D]R}t|dd}|||D].}tj|dtj|}||j |<|d7}qFq$tj d}|D]V}t|dd}|||D]2}tj|dtj|d}||j |<|d7}qqtj d}|D]r} t|dd}|| t |d} | D]B}|\} } tj| dtj| tj| }||j |<|d7}qqtjd}t |d} | D]v}|\}}t|dd}|||||D]>}tj|dtj|dtj|}||j |<|d7}qqztjd}|D]}t|dd}||t |d}|D]N}|\}}}tj|dtj|tj|tj|}||j |<|d7}q.qdS)zO Pair, Two Pair, Three of a Kind, Full House, and 4 of a Kind. rNr r r)r#r$r INT_RANKSrMAX_STRAIGHT_FLUSHlistremovePRIMESrMAX_FOUR_OF_A_KIND MAX_STRAIGHT itertools combinationsMAX_THREE_OF_A_KIND MAX_TWO_PAIR)rbackwards_ranksr1r-kickerskproduct pairranksprrr,c1c2tpgentppair1pair2kickerpairrankkgenk1k2k3rrrrsh           "     &      zLookupTable.multiplescCs^t|d@}|D]&\}}|t|dt|dqWdn1sP0YdS)z- Writes lookup table to disk w, N)open iteritemswritestr)rtablefilepathr. prime_prodr1rrrwrite_table_to_disks zLookupTable.write_table_to_diskccsz||dBd}|t|| @|| @d?dB}|V||dBd}|t|| @|| @d?dB}|Vq:dS)z Bit hack from here: http://www-graphics.stanford.edu/~seander/bithacks.html#NextBitPermutation Generator even does this in poker order rank so no need to sort when done! Perfect. rN)r")rbitstr%rrrr!s $$z1LookupTable.get_lexographically_next_bit_sequenceN)__name__ __module__ __qualname__r;r?r)r3r@rCrDr4 MAX_HIGH_CARDMAX_TO_RANK_CLASSRANK_CLASS_TO_STRINGrrr*rrbr!rrrrrsF   GTrc@sXeZdZdZddZddZddZdd Zd d Zd d Z ddZ ddZ ddZ dS) Evaluatora Evaluates hand strengths using a variant of Cactus Kev's algorithm: http://suffe.cool/poker/evaluator.html I make considerable optimizations in terms of speed and memory usage, in fact the lookup table generation can be done in under a second and consequent evaluations are very fast. Won't beat C, but very fast as all calculations are done with bit arithmetic and table lookups. cCs t|_|j|j|jd|_dS)N)r r r )rr__five_six_seven hand_size_maprrrrrs zEvaluator.__init__cCs||}|jt||S)z This is the function that the user calls to get a hand rank. Supports empty board, etc very flexible. No input validation because that's cycles! )ror$)rcardsboard all_cardsrrrevaluate szEvaluator.evaluatecCs|d|d@|d@|d@|d@d@rn|d|dB|dB|dB|dBd?}t|}|jj|St|}|jj|SdS) a= Performs an evalution given cards in integer form, mapping them to a rank in the range [1, 7462], with lower ranks being more powerful. Variant of Cactus Kev's 5 card evaluator, though I saved a lot of memory space using a hash table and condensing some of the calculations. rrrr r iN)rr(r_rprime_product_from_handr)rrphandORprimerrrrl)s ,,   zEvaluator._fivecCs6tj}t|d}|D]}||}||kr|}q|S)z Performs five_card_eval() on all (6 choose 5) = 6 subsets of 5 cards in the set of 6 to determine the best ranking, and returns this ranking. r rrhrArBrlrrpminimumall5cardcombobscomboscorerrrrm;s  zEvaluator._sixcCs6tj}t|d}|D]}||}||kr|}q|S)z Performs five_card_eval() on all (7 choose 5) = 21 subsets of 5 cards in the set of 7 to determine the best ranking, and returns this ranking. r rxryrrrrnLs  zEvaluator._sevencCs|dkr|tjkrtjtjS|tjkr4tjtjS|tjkrJtjtjS|tjkr`tjtjS|tjkrvtjtjS|tjkrtjtjS|tjkrtjtjS|tj krtjtj S|tj krtjtj St ddS)ze Returns the class of hand given the hand hand_rank returned from evaluate. rz+Inavlid hand rank, cannot return rank classN) rr;rir?r)r3r@rCrDr4rh Exception)rhrrrrget_rank_class]s&                 zEvaluator.get_rank_classcCs tj|S)zU Converts the integer class hand score into a human-readable string. )rrj)r class_intrrrclass_to_stringwszEvaluator.class_to_stringcCst|ttjS)zE Scales the hand rank score to the [0.0, 1.0] range. )floatrrh)r hand_rankrrrget_five_card_rank_percentage}sz'Evaluator.get_five_card_rank_percentagec Cst|dksJd|D]}t|dksJdqd}gd}tt|D]}d|dd|}t|||d }g} t|D]\} }|||d |d } || } || } d || }td | d| |f| |kr| | | }q| |kr| g} | }q|| dkrVt| dkr>td| ddfntddd| DqJtd|dd|t| dkrtd| dd||||| d|fqJtd| ||||| d|fqJd S)z Gives a sumamry of the hand with ranks as time proceeds. Requires that the board is in chronological order for the analysis to make sense. r zInvalid board lengthrzInavlid hand lengthr)FLOPTURNRIVER=z %s i'Nr g?z9Player %d hand = %s, percentage rank among all hands = %frrz%Player %d hand is currently winning. rz"Players %s are tied for the lead. cSsg|] }|dqS)rr).0xrrr z*Evaluator.hand_summary..z HAND OVER z"Player %d is the winner with a %s z&Players %s tied for the win with a %s ) r$r#print enumeratersrrrr&index)rrqhandshand line_lengthstagesr-line best_rankwinnersplayerr1 rank_class class_string percentagerrr hand_summarysH     zEvaluator.hand_summaryN) rerfrg__doc__rrsrlrmrnrrrrrrrrrk s   rk)rA deuces3.cardr deuces3.deckrobjectrrkrrrrs   u