What would be your recommendation for dealing a black jack hand?

Viewed 40

I am a beginner and have been tasked (as part of a course) to build a black jack game.

My initial code can be found below. The part I am stuck with is when I get to the Deck class and have to create the Deal method. What I am struggling with is how to deal out the initial four cards, remove them from the available ones in the deck (for future hits), and then also be able to store them as variables for the actual player's hand in an upcoming class. Appreciate the help!

import random

suits = ('Hearts', 'Diamonds', 'Spades', 'Clubs')
ranks = ('Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', 'Nine', 'Ten', 'Jack', 'Queen', 'King', 'Ace')
values = {'Two':2, 'Three':3, 'Four':4, 'Five':5, 'Six':6, 'Seven':7, 'Eight':8, 'Nine':9, 'Ten':10, 'Jack':10,
         'Queen':10, 'King':10, 'Ace':11}

playing = True

class Card:

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

    def __str__(self):
        print(f'{rank} of {suit}')


class Deck:

    def __init__(self):
        self.deck = []  # start with an empty list
        for suit in range(len(suits)):
            for rank in range(len(ranks)):
                self.deck += [(suits[suit],values[ranks[rank]])]

    def __str__(self):
        return f'{self.deck}'

    def shuffle(self):
        random.shuffle(self.deck)

    def deal(self):
        ?????

1 Answers

My suggestion would be to have the deal function just pop and return one card, since you'll be doing that a lot when players need to hit:

def deal(self) -> Card:
    return self.deck.pop()

Then to generate two hands of two cards you could do:

player_hand, dealer_hand = ([deck.deal() for _ in range(2)] for _ in range(2))

or perhaps:

def deal_starting_hand(deck: Deck) -> List[Card]:
    """Deals a starting hand of two cards."""
    return [deck.deal() for _ in range(2)]

deck = Deck()
players = ["Player 1", "Dealer"]
player_hands = {player: deal_starting_hand(deck) for player in players}

etc.


If you really wanted to have a single function that returns four cards and you didn't want to do it by popping iteratively, you could do:

four_cards = self.deck[:4]
self.deck = self.deck[4:]
return four_cards

but IMO it's better (from a learning and readability perspective) to have the smaller simpler function first and then use it to build larger things.

Related