Charterer Sling
Charterer Sling

Reputation: 85

Blackjack implementation--how do I assign values to cards?

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

Answers (3)

logic
logic

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

Oliver S.
Oliver S.

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

Will
Will

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

Related Questions