Here is code which I wrote to experiment how hard it is to get Royal Flush in Poker.

``````import random
from itertools import islice

valuecode={14:'A',13:'K',12:'Q',11:'J'}
for i in range(2,11):
valuecode[i] = str(i)

def dealer(deck):
while deck:
yield deck.pop()

def gethand(dealer):
return sorted(islice(dealer,5))

def isflush(cards):
return all(suit==firstsuit
for value,suit in cards
for _,firstsuit in (cards[0],)
)

def isstraight(cards):
if all(a==b for a,b in zip(range(2,6)+[14],[x for x,_ in cards])):
##        print 'Small ace',cards #straight 1..5
return True
else:
return all(nextvalue==thisvalue+1
for (thisvalue,_),(nextvalue,_) in zip(cards[:-1],cards[1:]))

def cardcode(value,suit):
return suitcode[suit]+valuecode[value]

def codedhand(cards):
return ','.join(cardcode(*card) for card in cards)

if __name__== '__main__':
wins = games = 0
handstyle=''

multiples={frozenset([1,3]):'Triple',frozenset([1,2]):'Two pairs', frozenset([1,4]):'Four same',
frozenset([2,3]):'Full house'}
while 'Royal' not in handstyle: # and wins < 1000:
## cards with ace as more high value 14
deck=[(value+2,suit)
for value in range(13)]
random.shuffle(deck)

getcards=dealer(deck)

while len(deck)>=10 and 'Royal' not in handstyle:
games+=1
playerhand, dealerhand = gethand(getcards), gethand(getcards)

for cards in (dealerhand,playerhand):
if len(set(x for x,_ in cards))<4: ## 3 or 4 same, two pairs or full house
wins+=1
values=list(x for x,_ in cards)
counts={}
for value in set(values):
counts[value]=values.count(value)
handstyle = multiples[frozenset(counts.values())]
print handstyle,':',codedhand(cards)

if isflush(cards) or isstraight(cards):
wins+=1
if isflush(cards) and isstraight(cards):
handstyle = 'Royal Flush' if cards[-1][0]==14 else 'Straight Flush'
print '***'+handstyle+'***'
else:
handstyle = 'Straight ' if isstraight(cards) else 'Flush'
print handstyle,':',codedhand(cards)

raw_input("\n\n%i wins in %i games" % (wins,games))``````

Specialties:
IT/Science/Contracts/Religious translation/interpreting FIN-ENG-FIN
Python programming

1
Contributor
3
Replies
7
Views
7 Years
Discussion Span
Last Post by pyTony

Bug in Royal Flush detection because of Ace as 1 straight is sorted wrong. Change the main routine for loop to:

``````for cards in (dealerhand,playerhand):
if len(set(x for x,_ in cards)) < 4: ## 3 or 4 same, two pairs or full house
wins+=1
values=list(x for x,_ in cards)
counts={}
for value in set(values):
counts[value]=values.count(value)
handstyle = multiples[frozenset(counts.values())]

elif isflush(cards) or isstraight(cards):
wins+=1
if isflush(cards) and isstraight(cards):
handstyle = 'Royal Flush' if cards[0][0]==10 else 'Straight Flush'
print '***'+handstyle+'***'
else:
handstyle = 'Straight' if isstraight(cards) else 'Flush'
else: # at most one pair -> pass printing
continue

print handstyle,':',codedhand(cards)``````

to correct the problem.

If you want to recognize one pair hands add to dictionary:

``frozenset([1,1,1,2]):'One pair'``

and include hands with 4 different values.

Edited by pyTony: n/a

This my old hashing is not sufficient in identifying all valuable hands in game, so I got shamed of this old code and did some cleaning of the mess, with more complete statistics:

``````import random
from itertools import islice

valuecode={14:'A',13:'K',12:'Q',11:'J'}
for i in range(2,11):
valuecode[i] = str(i)

def dealer(deck):
while deck:
yield deck.pop()

def gethands(dealer):
while dealer:
cards = sorted(islice(dealer,5))
if len(cards) == 5:
yield cards
else:
break

def isflush(cards):
return all(suit==firstsuit
for value,suit in cards
for _,firstsuit in (cards[0],)
)

def isstraight(cards):
# check also case 2,3,4,5,14 -> 1,2,3,4,5
return (all(a==b for a,b in zip(range(2,6)+[14],
[x for x,_ in cards])
) or
# normal case
all(nextvalue==thisvalue+1
for (thisvalue,_),(nextvalue,_) in zip(cards[:-1],cards[1:]))
)

def cardcode(value,suit):
return suitcode[suit]+valuecode[value]

def codedhand(cards):
return ','.join(cardcode(*card) for card in cards)

def newdeck():
## cards with ace as more high value 14 == 12 + 2
deck = [(value+2,suit)
for value in range(13)]
random.shuffle(deck)
return deck

if __name__== '__main__':
hands = 0
wins = {}
handstyle=''

multiples={frozenset((3,(1,1,3))):'Triple',
frozenset((3,(1,2,2))):'Two pairs',
frozenset((2,(1,4))):'Four same',
frozenset((2,(2,3))):'Full house',
frozenset((4,(1,1,1,2))):'One pair'
}
totalhands = 0
while 'Royal Flush' not in wins: # and sum(wins[key] for key in wins) < 10000:
deck = newdeck()
cards_generator = dealer(deck)

for hands,cards in enumerate(gethands(cards_generator)):
if 'Royal' in handstyle:
break

if isflush(cards) or isstraight(cards):
if isflush(cards) and isstraight(cards):
handstyle = 'Royal Flush' if cards[0][0]==10 else 'Straight Flush'
print '***' + handstyle + '***'
else:
handstyle = 'Straight' if isstraight(cards) else 'Flush'
wins[handstyle] = wins[handstyle]+1 if handstyle in wins else 1
else:
values = [x for x,_ in cards]
count_of_values = tuple(sorted(values.count(x) for x in set(values)))
signature = frozenset((len(count_of_values), count_of_values))
if signature in multiples: # and not 4 in signature:
wins[multiples[signature]] = (wins[multiples[signature]]+1
if multiples[signature] in wins
else 1)
handstyle = multiples[signature]
else:
continue

##                print "%10s:%20s" % (handstyle,codedhand(cards))

totalhands += hands

raw_input("%i wins in %i hands:\n%s\nPush enter to finish! " %
(sum(wins[key] for key in wins), totalhands, wins))``````

Edited by pyTony: n/a

Frozenset is unnecessary as I use tuple instead of tuple, then also separate length is unnecessary and separate signature

``````import random
from itertools import islice

valuecode={14:'A',13:'K',12:'Q',11:'J'}
for i in range(2,11):
valuecode[i] = str(i)

def dealer(deck):
while deck:
yield deck.pop()

def gethands(dealer):
while dealer:
cards = sorted(islice(dealer,5))
if len(cards) == 5:
yield cards
else:
break

def isflush(cards):
return all(suit==firstsuit
for value,suit in cards
for _,firstsuit in (cards[0],)
)

def isstraight(cards):
# check also case 2,3,4,5,14 -> 1,2,3,4,5
return (all(a==b for a,b in zip(range(2,6)+[14],
[x for x,_ in cards])
) or
# normal case
all(nextvalue==thisvalue+1
for (thisvalue,_),(nextvalue,_) in zip(cards[:-1],cards[1:]))
)

def cardcode(value,suit):
return suitcode[suit]+valuecode[value]

def codedhand(cards):
return ','.join(cardcode(*card) for card in cards)

def newdeck():
## cards with ace as more high value 14 == 12 + 2
deck = [(value+2,suit)
for value in range(13)]
random.shuffle(deck)
return deck

if __name__== '__main__':
hands = 0
wins = {}
handstyle=''

multiples={(1,1,3) : 'Triple',
(1,2,2) : 'Two pairs',
(1,4) : 'Four same',
(2,3) : 'Full house',
(1,1,1,2) : 'One pair'
}
totalhands = 0
while sum(wins[key] for key in wins) < 100000: # 'Royal Flush' not in wins:
deck = newdeck()
cards_generator = dealer(deck)

for hands,cards in enumerate(gethands(cards_generator)):
if 'Royal' in handstyle:
break

if isflush(cards) or isstraight(cards):
if isflush(cards) and isstraight(cards):
handstyle = 'Royal Flush' if cards[0][0]==10 else 'Straight Flush'
print '***' + handstyle + '***'
else:
handstyle = 'Straight' if isstraight(cards) else 'Flush'
wins[handstyle] = wins[handstyle]+1 if handstyle in wins else 1
print "%10s:%20s" % (handstyle,codedhand(cards))
else:
values = [x for x,_ in cards]
count_of_values = tuple(sorted(values.count(x) for x in set(values)))
if count_of_values in multiples:
# and len(count_of_values) < 4: # do not consider simple pairs
wins[multiples[count_of_values]] = (wins[multiples[count_of_values]]+1
if multiples[count_of_values] in wins
else 1)
handstyle = multiples[count_of_values]
else:
continue

totalhands += hands

raw_input("%i wins in %i hands:\n%s\nPush enter to finish! " %
(sum(wins[key] for key in wins), totalhands, wins))``````
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.