Reputation: 3
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 (e.g. 'two of Spades' and 'three of Spades') or the same rank (e.g. '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.
Upvotes: 0
Views: 4003
Reputation: 1336
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 !"
Upvotes: 1
Reputation: 439
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).
Upvotes: 0
Reputation: 459
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.
Upvotes: 0
Reputation: 4216
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.
Upvotes: 0