Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
150
Task/Poker-hand-analyser/Python/poker-hand-analyser.py
Normal file
150
Task/Poker-hand-analyser/Python/poker-hand-analyser.py
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
from collections import namedtuple
|
||||
|
||||
class Card(namedtuple('Card', 'face, suit')):
|
||||
def __repr__(self):
|
||||
return ''.join(self)
|
||||
|
||||
|
||||
suit = '♥ ♦ ♣ ♠'.split()
|
||||
# ordered strings of faces
|
||||
faces = '2 3 4 5 6 7 8 9 10 j q k a'
|
||||
lowaces = 'a 2 3 4 5 6 7 8 9 10 j q k'
|
||||
# faces as lists
|
||||
face = faces.split()
|
||||
lowace = lowaces.split()
|
||||
|
||||
|
||||
def straightflush(hand):
|
||||
f,fs = ( (lowace, lowaces) if any(card.face == '2' for card in hand)
|
||||
else (face, faces) )
|
||||
ordered = sorted(hand, key=lambda card: (f.index(card.face), card.suit))
|
||||
first, rest = ordered[0], ordered[1:]
|
||||
if ( all(card.suit == first.suit for card in rest) and
|
||||
' '.join(card.face for card in ordered) in fs ):
|
||||
return 'straight-flush', ordered[-1].face
|
||||
return False
|
||||
|
||||
def fourofakind(hand):
|
||||
allfaces = [f for f,s in hand]
|
||||
allftypes = set(allfaces)
|
||||
if len(allftypes) != 2:
|
||||
return False
|
||||
for f in allftypes:
|
||||
if allfaces.count(f) == 4:
|
||||
allftypes.remove(f)
|
||||
return 'four-of-a-kind', [f, allftypes.pop()]
|
||||
else:
|
||||
return False
|
||||
|
||||
def fullhouse(hand):
|
||||
allfaces = [f for f,s in hand]
|
||||
allftypes = set(allfaces)
|
||||
if len(allftypes) != 2:
|
||||
return False
|
||||
for f in allftypes:
|
||||
if allfaces.count(f) == 3:
|
||||
allftypes.remove(f)
|
||||
return 'full-house', [f, allftypes.pop()]
|
||||
else:
|
||||
return False
|
||||
|
||||
def flush(hand):
|
||||
allstypes = {s for f, s in hand}
|
||||
if len(allstypes) == 1:
|
||||
allfaces = [f for f,s in hand]
|
||||
return 'flush', sorted(allfaces,
|
||||
key=lambda f: face.index(f),
|
||||
reverse=True)
|
||||
return False
|
||||
|
||||
def straight(hand):
|
||||
f,fs = ( (lowace, lowaces) if any(card.face == '2' for card in hand)
|
||||
else (face, faces) )
|
||||
ordered = sorted(hand, key=lambda card: (f.index(card.face), card.suit))
|
||||
first, rest = ordered[0], ordered[1:]
|
||||
if ' '.join(card.face for card in ordered) in fs:
|
||||
return 'straight', ordered[-1].face
|
||||
return False
|
||||
|
||||
def threeofakind(hand):
|
||||
allfaces = [f for f,s in hand]
|
||||
allftypes = set(allfaces)
|
||||
if len(allftypes) <= 2:
|
||||
return False
|
||||
for f in allftypes:
|
||||
if allfaces.count(f) == 3:
|
||||
allftypes.remove(f)
|
||||
return ('three-of-a-kind', [f] +
|
||||
sorted(allftypes,
|
||||
key=lambda f: face.index(f),
|
||||
reverse=True))
|
||||
else:
|
||||
return False
|
||||
|
||||
def twopair(hand):
|
||||
allfaces = [f for f,s in hand]
|
||||
allftypes = set(allfaces)
|
||||
pairs = [f for f in allftypes if allfaces.count(f) == 2]
|
||||
if len(pairs) != 2:
|
||||
return False
|
||||
p0, p1 = pairs
|
||||
other = [(allftypes - set(pairs)).pop()]
|
||||
return 'two-pair', pairs + other if face.index(p0) > face.index(p1) else pairs[::-1] + other
|
||||
|
||||
def onepair(hand):
|
||||
allfaces = [f for f,s in hand]
|
||||
allftypes = set(allfaces)
|
||||
pairs = [f for f in allftypes if allfaces.count(f) == 2]
|
||||
if len(pairs) != 1:
|
||||
return False
|
||||
allftypes.remove(pairs[0])
|
||||
return 'one-pair', pairs + sorted(allftypes,
|
||||
key=lambda f: face.index(f),
|
||||
reverse=True)
|
||||
|
||||
def highcard(hand):
|
||||
allfaces = [f for f,s in hand]
|
||||
return 'high-card', sorted(allfaces,
|
||||
key=lambda f: face.index(f),
|
||||
reverse=True)
|
||||
|
||||
handrankorder = (straightflush, fourofakind, fullhouse,
|
||||
flush, straight, threeofakind,
|
||||
twopair, onepair, highcard)
|
||||
|
||||
def rank(cards):
|
||||
hand = handy(cards)
|
||||
for ranker in handrankorder:
|
||||
rank = ranker(hand)
|
||||
if rank:
|
||||
break
|
||||
assert rank, "Invalid: Failed to rank cards: %r" % cards
|
||||
return rank
|
||||
|
||||
def handy(cards='2♥ 2♦ 2♣ k♣ q♦'):
|
||||
hand = []
|
||||
for card in cards.split():
|
||||
f, s = card[:-1], card[-1]
|
||||
assert f in face, "Invalid: Don't understand card face %r" % f
|
||||
assert s in suit, "Invalid: Don't understand card suit %r" % s
|
||||
hand.append(Card(f, s))
|
||||
assert len(hand) == 5, "Invalid: Must be 5 cards in a hand, not %i" % len(hand)
|
||||
assert len(set(hand)) == 5, "Invalid: All cards in the hand must be unique %r" % cards
|
||||
return hand
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
hands = ["2♥ 2♦ 2♣ k♣ q♦",
|
||||
"2♥ 5♥ 7♦ 8♣ 9♠",
|
||||
"a♥ 2♦ 3♣ 4♣ 5♦",
|
||||
"2♥ 3♥ 2♦ 3♣ 3♦",
|
||||
"2♥ 7♥ 2♦ 3♣ 3♦",
|
||||
"2♥ 7♥ 7♦ 7♣ 7♠",
|
||||
"10♥ j♥ q♥ k♥ a♥"] + [
|
||||
"4♥ 4♠ k♠ 5♦ 10♠",
|
||||
"q♣ 10♣ 7♣ 6♣ 4♣",
|
||||
]
|
||||
print("%-18s %-15s %s" % ("HAND", "CATEGORY", "TIE-BREAKER"))
|
||||
for cards in hands:
|
||||
r = rank(cards)
|
||||
print("%-18r %-15s %r" % (cards, r[0], r[1]))
|
||||
Loading…
Add table
Add a link
Reference in a new issue