Search code examples
pythondictionaryblackjack

What is wrong with my dictionary (mapping values to cards)


So the game is Blackjack and I have snippets of code to make a deck and make a hand. From the deck, that is a list, I'm trying to build a dictionary so that each card (a tuple from the deck) will have a value mapped to it, as per the rules of Blackjack.

from random import randint

def make_deck():
    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 = make_deck()

def make_hand():
    hand = []
    for k in range(2):
        card = deck.pop(randint(0,51))
        hand.append(card)
    return hand

hand = make_hand()

values = {} #empty dictionary
for card in deck:
    rank = [card[1] for card in deck]
    if rank == 'ace':
        values[card] = 1
    elif rank == 'two':
        values[card] = 2
    elif rank == 'three':
        values[card] = 3
    elif rank == 'four':
        values[card] = 4
    elif rank == 'five':
        values[card] = 5
    elif rank == 'six':
        values[card] = 6
    elif rank == 'seven':
        values[card] = 7
    elif rank == 'eight':
        values[card] = 8
    elif rank == 'nine':
        values[card] = 9
    elif rank == 'ten' or 'jack' or 'queen' or 'king':
        values[card] = 10
 print values

Obviously, this is very much creating the dictionary by brute force and lacks any elegance so any pointers into a more efficient manner would be appreciated. The real issue is that I can't identify what is wrong with my code that print values returns just one tuple mapped to its value rather the entire dictionary. If I move the list comprehension for rank outside of the loop, I just get a dictionary where everything is mapped to the value 10.

Also, I just realized that my make_hand() function sometimes results in an error where "the pop index is out of range," so advice on things to try so that it will work all the time would also be appreciated.


Solution

  • Replace the line:

    rank = [card[1] for card in deck]
    

    with:

    rank = card[1]
    

    And yes, you can do it more efficiently (and elegantly) by creating a dictionary that maps values to scores:

    mapper = {'ace': 1, 'two': 2, ...}
    

    and then you don't need the if/elif...else:

    for card in deck:
        values[card] = mapper[card[1]]