简体   繁体   中英

Simple card game in python

I am making a simple card game that deals the player two cards and if the cards are the same suit, the same rank (value), or a run the player wins. If the player's hand has none of these properties the player loses. The code I am using is as follows:

from itertools import product
import random


class Card(object):

    FACES = {11: 'Jack', 12: 'Queen', 13: 'King', 14: 'Ace'}

    def __init__(self, rank, suit):
        self.suit = suit
        self.rank = rank

    def __str__(self):
        value = self.FACES.get(self.rank, self.rank)
        return "{0} of {1}".format(value, self.suit)

    def __lt__(self, other):
        return self.rank < other.rank


class Deck(object):

    def __init__(self, ranks=None, suits=None):
        if ranks is None:
            ranks = xrange(2, 15)
        if suits is None:
            suits = ['Clubs', 'Diamonds', 'Hearts', 'Spades']
        self.deck = []
        for r in ranks:
            for s in suits:
                self.deck.append(Card(r, s))

    def deal(self, n):
        return random.sample(self.deck, n)


ranks = xrange(2, 15)
suits = ['Clubs', 'Diamonds', 'Hearts', 'Spades']
deck = Deck()
hand = deck.deal(2)
print "Your hand is"
print " - ".join(map(str, hand))

suits_in_hand = []
for card in hand:
    suits_in_hand.append(card.suit)

if all(suits_in_hand == suit for suit in suits):
    print "\nAll cards are of the same suit"
    print "You Win!"
elif all(suits_in_hand == rank for rank in ranks):
    print "\nAll cards are of the same rank"
    print "You Win!"
# I don't know how to test if the cards in the player's hand are a run
else:
    print "\nYou Lose."

However, even if the cards are both the same suit (eg 'two of Spades' and 'three of Spades') or the same rank (eg 'two of Hearts' and 'two of Clubs') it outputs You Lose . What can I do to fix this and how can I add the elif statement to test whether or not the cards in the player's hand are a run.

To check if all elements in a collection are the same, a short and elegant solution is to use a set :

suits_in_hand = set(card.suit for card in hand)

if len(suits_in_hand) == 1:
    print "\nAll cards are of the same suit"
    print "You Win!"

Same for ranks.

For runs, you could compare the set of ranks to a set from range :

ranks_in_hand = set(card.rank for card in hand)
min_rank == min(ranks_in_hand)
if set(ranks_in_hand) == set(range(min_rank, min_rank + 2)):
    print "\nGot a run !"

Your main issue is you're trying to compare a single entity to an array, which you can't do. Instead of

if all(suits_in_hand == suit for suit in suits):
    print "\nAll cards are of the same suit"
    print "You Win!"

do something like

if suit in suits_in_hand for suit in suits:
    print "\nAll cards are of the same suit"
    print "You Win!"

For the ranks , you'll need to do something similar, but build a ranks_in_hand object.

You want to compare the elements in suits_in_hand against each other. Comparing them to suits is comparing your hand to all possible suits, which isn't right. Similarly, you need a ranks_in_hand and compare the elements in it to each other.

To check for a run, just check if the difference between the card ranks in your hand is 1.

For checking if all of the suits in the hand are the same, you can check to see if the length of the set created from suits_in_hand is one.

if len(set(suits_in_hand)) == 1:
    # do something

A similar thing could be done for checking if the hand contains all of the same card.

To check for a run, you could try sorting the list and checking that each element is one greater than the next (simplified, just check the difference if you only need to support a hand size of two).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM