Reputation: 85
I'm trying to write a program to play Blackjack, between the user and the dealer, in Python.
For the cards, I have:
suits = ['spades','hearts','diamonds','clubs']
ranks = ['ace','two','three','four','five','six','seven','eight','nine','ten','jack','queen','king']
def create_deck():
deck = []
for suit in suits:
for rank in ranks:
deck.append((suit,rank))
return deck
def shuffle(deck):
for i in range(100):
card = deck.pop(randint(0,51))
deck.append(card)
With the deck of cards in a list, what is the simplest way to make a dictionary where I can map each card to its face value?
Upvotes: 0
Views: 2329
Reputation: 1727
From the comments of your question:
"Fundamentally, I think of building the dictionary manually:
{('spades','ace'):1, ('spades','two'):2}
and so on, but is there a way
to build the dictionary more efficiently?"
You could do this simply by:
def create_deck(suits,ranks):
deck = []
for suit in suits:
for rank in ranks:
deck.append((suit,rank))
return deck
suits = ['spades','hearts','diamonds','clubs']
ranks = ['ace','two','three','four','five','six','seven','eight','nine','ten','jack','queen','king']
deck=create_deck(suits,ranks)
d={} #empty dictionary
i=1 #start with i=1
for card in deck:
d[card]=i #add to dictionary
if i==13:
i=1 #reverse i to 1 every 13 iterations
else:
i+=1 #otherwise increment i
>>> d
{('diamonds', 'eight'): 8, ('hearts', 'five'): 5, ('diamonds', 'two'): 2, ('diamonds', 'nine'): 9, ('diamonds', 'jack'): 11, ('hearts', 'eight'): 8, ('diamonds', 'king'): 13, ('spades', 'jack'): 11, ('clubs', 'jack'): 11, ('spades', 'nine'): 9, ('spades', 'two'): 2, ('clubs', 'two'): 2, ('hearts', 'queen'): 12, ('spades', 'ace'): 1, ('hearts', 'three'): 3, ('diamonds', 'six'): 6, ('hearts', 'ace'): 1, ('spades', 'four'): 4, ('spades', 'three'): 3, ('clubs', 'four'): 4, ('hearts', 'nine'): 9, ('spades', 'seven'): 7, ('spades', 'queen'): 12, ('hearts', 'six'): 6, ('spades', 'ten'): 10, ('clubs', 'seven'): 7, ('diamonds', 'queen'): 12, ('hearts', 'ten'): 10, ('clubs', 'three'): 3, ('diamonds', 'seven'): 7, ('clubs', 'ten'): 10, ('hearts', 'king'): 13, ('hearts', 'seven'): 7, ('diamonds', 'ten'): 10, ('clubs', 'six'): 6, ('clubs', 'nine'): 9, ('spades', 'six'): 6, ('diamonds', 'five'): 5, ('hearts', 'four'): 4, ('spades', 'five'): 5, ('diamonds', 'four'): 4, ('clubs', 'queen'): 12, ('diamonds', 'three'): 3, ('clubs', 'eight'): 8, ('hearts', 'two'): 2, ('clubs', 'ace'): 1, ('clubs', 'king'): 13, ('hearts', 'jack'): 11, ('diamonds', 'ace'): 1, ('spades', 'eight'): 8, ('spades', 'king'): 13, ('clubs', 'five'): 5}
Note: This works because the deck
list you created earlier is in numerical order.
Update:
If the deck
list is NOT already sorted, you could do this:
def create_deck(suits,ranks):
deck = []
for suit in suits:
for rank in ranks:
deck.append((suit,rank))
return deck
suits = ['spades','hearts','diamonds','clubs']
ranks = ['ace','two','three','four','five','six','seven','eight','nine','ten','jack','queen','king']
vals = dict(zip(ranks, [i for i in range(1,14)])) #create a value dictionary
deck = create_deck(suits,ranks)
d={} #create an empty dictionary
for card in deck:
d[card]=vals[card[1]] #add card '(spades,king)' as index and vals['king'] (which is 13) as the value
Where the vals
dictionary is in the form:
{'king': 13, 'seven': 7, 'queen': 12, 'ten': 10, 'ace': 1, 'nine': 9, 'six': 6, 'two': 2, 'three': 3, 'four': 4, 'five': 5, 'jack': 11, 'eight': 8}
Upvotes: 1
Reputation: 39
You could also write a class 'Cards' so that a card is an object of that class with suit and rank as attributes. Thus you don't need the dictionary. Here's an example:
suits = ['spades','hearts','diamonds','clubs']
ranks = ['ace','two','three','four','five','six','seven','eight','nine','ten','jack','queen','king']
class Card:
def __init__(self, rank, suit):
self.rank = rank
self.suit = suit
def create_deck():
deck = []
for suit in suits:
for rank in ranks:
deck.append(Card(rank, suit))
return deck
When your function create_deck() is executed it'll return the list 'deck' with 52 Card objects which you can now access and work with like e.g. this:
>>> from cards import *
>>> deck = create_deck() # create the deck
>>> len(deck)
52
>>> deck[12] # show contents are objects of the class
<cards.Card object at 0x1006ba6d8>
>>> deck[12].suit, deck[12].rank
('spades', 'king')
>>> from random import shuffle # following lines demonstrate shuffle Shashank mentioned
>>> shuffle(deck)
>>> deck[12].rank, deck[12].suit
('seven', 'clubs')
>>>
HTH
Upvotes: 0
Reputation: 4469
It looks like the code you have should work, are you getting an error?
By far the most fun way to do this is to simply use the numbers 1-52 (NOT 0-51) and using modulus 4 for suit and modulus 13 for face value. no number in this range will have both modulus value in common.
Otherwise, objects.
Upvotes: 2