1 from random import randint, choice, seed
2 from combinations import *
5 Cards in the deck is stored as (n,m), where n is the rank number
6 n=[0,12], m=[0,3], with n defined to be the card value and m as the suit.
9 (0,1) is a two of hearts,
10 (11,0) is a king of spades,
11 (12,3) is an Ace of clubs
14 DECK = dict().fromkeys(range(52))
15 for c in DECK: DECK[c] = (c/4,c%4)
17 ''' Fisher-Yates shuffle from Knuth '''
19 for n in range(1,52)[::-1]:
21 DECK[k], DECK[n] = DECK[n], DECK[k]
24 To determine which five card hand is stronger according to standard poker
25 rules, each hand is given a score and a pair rank. The score cooresponds to
26 the poker hand (Straight Flush=8, Four of a Kind=7, etc...). The pair score
27 is used to break ties of score. The pair score creates a set of pairs then
28 rank sorts within each set. Examples:
33 Pair Score A: [ (2, [7,5]), (1, [K]) ]
34 Pair Score B: [ (2, [8,5]), (1, [A]) ]
39 Pair Score A: [ (1, [A,K,Q,J,2]) ]
40 Pair Score B: [ (1, [A,5,4,3,2]) ]
44 P = dict().fromkeys(cards,0)
45 for c in cards: P[c] += 1
46 V = sorted(set(P.values()))[::-1]
47 return [[v,sorted([c for c in set(P) if P[c]==v])[::-1]] for v in V]
49 def top_pairScore(P1,P2): # Only compare to cards with same score!
50 for p1, p2 in zip(P1,P2):
51 if p1[1]>p2[1]: return 1
52 elif p1[1]<p2[1]: return -1
55 def isFullHouse(P0): return P0==(3,2)
56 def isPair4(P0): return P0==(4,1)
57 def isPair3(P0): return P0==(3,1)
58 def isdoublePair2(P0,P1): return P0==(2,1) and len(P1[0])==2
59 def isPair2(P0,P1): return P0==(2,1) and len(P1[0])==1
60 def isFlush(suit): return len(set(suit)) == 1
61 def isSt(cards) : # Handles the low Ace as well
63 diff = [(x2-x1) for x1,x2 in zip(cards,cards[1:])]
64 return len([x for x in diff if x==1])==4 or cards==[0,1,2,3,12]
72 S,F = isSt(cards), isFlush(suit)
74 if isPair2(P0,P1) : score = 1
75 elif isdoublePair2(P0,P1): score = 2
76 elif isPair3(P0) : score = 3
77 elif S and not F : score = 4
78 elif F and not S : score = 5
79 elif isFullHouse(P0) : score = 6
80 elif isPair4(P0) : score = 7
81 elif S and F : score = 8
86 To determine who wins a poker hand, given two players hole cards, each player
87 determines the best hand they can make within their 7 choose 5 = 21 possible five
88 card combinations. Then each players best hands are put against each other. 1, -1
89 or 0 is returned if player A wins, B wins, or ties respectively.
92 # This function prevents call xunqiueCombinations a bajillon times
93 HAND_COMBOS = list(xuniqueCombinations(range(7),5))
95 for L in HAND_COMBOS: yield [H[n] for n in L]
97 def top_hand_reduce(P1,P2):
100 if A[0]>B[0]: return H1,A
101 elif A[0]<B[0]: return H2,B
102 pairscore = top_pairScore(A[1],B[1])
103 if pairscore > 0: return H1,A
104 elif pairscore < 0: return H2,B
107 def top_hand_score(A,B):
108 A.score,B.score = handScore(A.score), handScore(B.score)
109 if A.score[0]>B.score[0]: return 1
110 elif A.score[0]<B.score[0]: return -1
111 return top_pairScore(A.score[1],B.score[1])
113 def HOLDEM_score(A, B, board):
114 A.score = reduce(top_hand_reduce,[(H,handScore(H)) for H in pull_hand(A.hole+board)])[0]
115 B.score = reduce(top_hand_reduce,[(H,handScore(H)) for H in pull_hand(B.hole+board)])[0]
116 return top_hand_score(A,B)
118 # ***************************************
119 # Returns the hand in a human readable format (pretty-print)
125 elif c[0]==10: S+='Q'
126 elif c[0]==11: S+='K'
127 elif c[0]==12: S+='A'
128 else : S+=str(c[0]+2)
131 elif c[1]==1 : S+='d'
132 elif c[1]==2 : S+='c'
140 if A.score[0] == 0: S = 'HighCard '
141 elif A.score[0] == 1: S = 'Pair '
142 elif A.score[0] == 2: S = 'TwoKind '
143 elif A.score[0] == 3: S = 'ThreeKind '
144 elif A.score[0] == 4: S = 'Straight '
145 elif A.score[0] == 5: S = 'Flush '
146 elif A.score[0] == 6: S = 'FullHouse '
147 elif A.score[0] == 7: S = 'FourKind '
148 elif A.score[0] == 8: S = 'StFlush '