katja92
katja92

Reputation: 57

how to print user friendly poker hand in python?

I am writing a poker game in python and I need to print out a poker hand that will be easy to read for a user. It's not printing what i need it to print. I know there is a solution, I just don't see it. Here is the code:

userCards = ['AC','KD','4C','4S','7H']
print('Your cards:')
for card in range(len(userCards)):
   print('%s) %-2s of %-9s' % (card,cvalue,csuit))

I have already defined the userCards, value and suit. I just need it to print out the hand like this:

'Your cards:'

1) Ace of Spades

2) King of diamonds

3)4 of Clubs

4)4 of Spades

5)7 of Hearts

Thanks in advance!

Upvotes: 1

Views: 1031

Answers (1)

PM 2Ring
PM 2Ring

Reputation: 55469

Rather than using functions that expand the card's rank and suit I suggest using dictionaries. Dictionaries are a compact and efficient way to do this sort of thing.

This code should work on Python 2 or Python 3.

from __future__ import print_function

suits = {'C': 'Clubs', 'D': 'Diamonds', 'H': 'Hearts', 'S': 'Spades'}
ranks = {'J': 'Jack', 'Q': 'Queen', 'K': 'King', 'A': 'Ace'}

def show_hand(hand):
    print('Your cards:')
    for rank, suit in hand:
        rank = ranks.get(rank, rank)
        suit = suits[suit]
        print('%s of %s' % (rank, suit))

#Test
userCards = ['AC', 'KD', '4C', '4S', '7H']
show_hand(userCards)

output

Your cards:
Ace of Clubs
King of Diamonds
4 of Clubs
4 of Spades
7 of Hearts

I suppose I should explain rank = ranks.get(rank, rank).

somedict.get(key, default)

attempts to look up key in somedict. If that key is present then the associated value is returned, just as if you did somedict[key]. But if the key isn't present, then default is returned. So rank = ranks.get(rank, rank) returns the expanded rank, if one exists, otherwise it just returns the original rank string. So A gets translated to Ace but number strings remain as they are.


The clean way to get the card's index as well is to use the built-in enumerate function. We supply a start argument of 1 to enumerate to get 1-based indices:

def show_hand(hand):
    print('Your cards:')
    for i, (rank, suit) in enumerate(hand, 1):
        rank = ranks.get(rank, rank)
        suit = suits[suit]
        print('%d: %s of %s' % (i, rank, suit))

output

Your cards:
1: Ace of Clubs
2: King of Diamonds
3: 4 of Clubs
4: 4 of Spades
5: 7 of Hearts

Finally, here's a new version that uses the zip and all functions to detect if a hand contains a flush. If it does, the suit letter is returned, otherwise None is returned.

from __future__ import print_function

suits = {'C': 'Clubs', 'D': 'Diamonds', 'H': 'Hearts', 'S': 'Spades'}
ranks = {'J': 'Jack', 'Q': 'Queen', 'K': 'King', 'A': 'Ace'}

def show_hand(hand):
    print('Your cards:')
    for i, (rank, suit) in enumerate(hand, 1):
        rank = ranks.get(rank, rank)
        suit = suits[suit]
        print('%d: %s of %s' % (i, rank, suit))

def is_flush(hand):
    #Get suits
    suit_list = zip(*hand)[1]
    #Test if all the cards match the suit of the first card
    suit = suit_list[0]
    return suit if all(s == suit for s in suit_list) else None

#Test
userCards = ['AC', 'KD', '4C', '4S', '7H']
flushCards = '3D 5D AD QD 7D'.split()
hands = (userCards, flushCards)

for hand in hands:
    show_hand(hand)
    suit = is_flush(hand)
    if suit is None:
        print('Not a flush')
    else:
        print('Flush in %s' % suits[suit])
    print()

output

Your cards:
1: Ace of Clubs
2: King of Diamonds
3: 4 of Clubs
4: 4 of Spades
5: 7 of Hearts
Not a flush

Your cards:
1: 3 of Diamonds
2: 5 of Diamonds
3: Ace of Diamonds
4: Queen of Diamonds
5: 7 of Diamonds
Flush in Diamonds

Upvotes: 2

Related Questions