<s> import itertools <EOL> import random <EOL> import pickle <EOL> import time <EOL> SUITS = ( '<STR_LIT:c>' , '<STR_LIT:d>' , '<STR_LIT:h>' , '<STR_LIT:s>' ) <EOL> RANKS = ( '<STR_LIT:2>' , '<STR_LIT:3>' , '<STR_LIT:4>' , '<STR_LIT:5>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT:T>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT:A>' ) <EOL> DECK = tuple ( '<STR_LIT>' . join ( card ) for card in itertools . product ( RANKS , SUITS ) ) <EOL> ORDER_LOOKUP = dict ( zip ( DECK , range ( <NUM_LIT> ) ) ) <EOL> RANK_LOOKUP = dict ( zip ( RANKS , range ( <NUM_LIT> ) ) ) <EOL> SUIT_LOOKUP = dict ( zip ( SUITS , range ( <NUM_LIT:4> ) ) ) <EOL> def cmp_cards ( a , b ) : <EOL> return cmp ( ORDER_LOOKUP [ a ] , ORDER_LOOKUP [ b ] ) <EOL> def cmp_tuples ( a , b ) : <EOL> n1 = len ( a ) <EOL> n2 = len ( b ) <EOL> if n1 != n2 : <EOL> return cmp ( n1 , n2 ) <EOL> return cmp ( a , b ) <EOL> def suit ( card ) : <EOL> return card [ <NUM_LIT:1> ] <EOL> def suit_int ( card ) : <EOL> return SUIT_LOOKUP [ card [ <NUM_LIT:1> ] ] <EOL> def rank ( card ) : <EOL> return card [ <NUM_LIT:0> ] <EOL> def rank_int ( card ) : <EOL> return RANK_LOOKUP [ card [ <NUM_LIT:0> ] ] <EOL> def card_int ( card ) : <EOL> s = <NUM_LIT:1> << suit_int ( card ) <EOL> r = rank_int ( card ) <EOL> c = ( s << <NUM_LIT:4> ) | r <EOL> return c <EOL> def is_straight ( cards ) : <EOL> previous = rank_int ( cards [ <NUM_LIT:0> ] ) - <NUM_LIT:1> <EOL> for card in cards : <EOL> r = rank_int ( card ) <EOL> if r != previous + <NUM_LIT:1> : <EOL> if not ( r == <NUM_LIT:12> and previous == <NUM_LIT:3> ) : <EOL> return False <EOL> previous = r <EOL> return True <EOL> def is_flush ( cards ) : <EOL> s = suit ( cards [ <NUM_LIT:0> ] ) <EOL> return all ( suit ( card ) == s for card in cards ) <EOL> def same_rank ( cards ) : <EOL> r = rank ( cards [ <NUM_LIT:0> ] ) <EOL> return all ( rank ( card ) == r for card in cards ) <EOL> def split_ranks ( cards , indexes ) : <EOL> for index in indexes : <EOL> a , b = cards [ : index ] , cards [ index : ] <EOL> if same_rank ( a ) and same_rank ( b ) : <EOL> return True <EOL> return False <EOL> def is_full_house ( cards ) : <EOL> return split_ranks ( cards , ( <NUM_LIT:2> , <NUM_LIT:3> ) ) <EOL> def is_four ( cards ) : <EOL> return split_ranks ( cards , ( <NUM_LIT:1> , <NUM_LIT:4> ) ) <EOL> def is_pat ( cards ) : <EOL> return is_straight ( cards ) or is_flush ( cards ) or is_full_house ( cards ) or is_four ( cards ) <EOL> def is_straight_flush ( cards ) : <EOL> return is_straight ( cards ) and is_flush ( cards ) <EOL> def rank_count ( cards ) : <EOL> result = { } <EOL> for card in cards : <EOL> r = rank_int ( card ) <EOL> result [ r ] = result . get ( r , <NUM_LIT:0> ) + <NUM_LIT:1> <EOL> return result <EOL> def is_three ( cards , counts = None ) : <EOL> counts = counts or rank_count ( cards ) <EOL> for rank , count in counts . iteritems ( ) : <EOL> if count == <NUM_LIT:3> : <EOL> return True <EOL> return False <EOL> def is_two_pair ( cards , counts = None ) : <EOL> pairs = <NUM_LIT:0> <EOL> counts = counts or rank_count ( cards ) <EOL> for rank , count in counts . iteritems ( ) : <EOL> if count == <NUM_LIT:2> : <EOL> pairs += <NUM_LIT:1> <EOL> return pairs == <NUM_LIT:2> <EOL> def is_pair ( cards , counts = None ) : <EOL> counts = counts or rank_count ( cards ) <EOL> for rank , count in counts . iteritems ( ) : <EOL> if count == <NUM_LIT:2> : <EOL> return True <EOL> return False <EOL> def get_ranks ( counts ) : <EOL> values = [ ( count , rank ) for rank , count in counts . iteritems ( ) ] <EOL> values . sort ( reverse = True ) <EOL> values = [ n [ <NUM_LIT:1> ] for n in values ] <EOL> return values <EOL> def get_straight_rank ( cards ) : <EOL> top = rank_int ( cards [ - <NUM_LIT:1> ] ) <EOL> bottom = rank_int ( cards [ <NUM_LIT:0> ] ) <EOL> if top == <NUM_LIT:12> and bottom == <NUM_LIT:0> : <EOL> return <NUM_LIT:3> <EOL> return top <EOL> def evaluate_hand ( cards ) : <EOL> flush = is_flush ( cards ) <EOL> straight = is_straight ( cards ) <EOL> counts = rank_count ( cards ) <EOL> ranks = get_ranks ( counts ) <EOL> if straight : <EOL> ranks = [ get_straight_rank ( cards ) ] <EOL> if straight and flush : <EOL> value = <NUM_LIT:9> <EOL> elif is_four ( cards ) : <EOL> value = <NUM_LIT:8> <EOL> elif is_full_house ( cards ) : <EOL> value = <NUM_LIT:7> <EOL> elif flush : <EOL> value = <NUM_LIT:6> <EOL> elif straight : <EOL> value = <NUM_LIT:5> <EOL> elif is_three ( cards , counts ) : <EOL> value = <NUM_LIT:4> <EOL> elif is_two_pair ( cards , counts ) : <EOL> value = <NUM_LIT:3> <EOL> elif is_pair ( cards , counts ) : <EOL> value = <NUM_LIT:2> <EOL> else : <EOL> value = <NUM_LIT:1> <EOL> ranks . insert ( <NUM_LIT:0> , value ) <EOL> return tuple ( ranks ) </s>
