Blackjack Table Class

The bets in Blackjack are associated with a hand. A player may have more than one hand in play. This will lead us to create a subclass of table to handle this complexity. In order to manage the relationships between hand and bet, we’ll rework hand, also.

We’ll look at the table in Blackjack Table Analysis.

Based on the classes defined so far, we can look at the design for the table in BlackjackTable Class.

We’ll look at some minor rework to Hand in Hand Rework.

In Blackjack Table Deliverables we’ll enumerate the deliverables for this chapter.

Blackjack Table Analysis

When we look at the game of Blackjack, we note that a player’s Hand object can be split into multiple Hand instances. In some casinos, resplits are allowed, leading to the possibility of three or more Hand instances. Each individual Hand object has a separate ante Bet and seperate resolution. This is different from the way bets are currently managed for Roulette and Craps, where the bets are associated with the player.

We have several alternatives for modeling this:

  • Assign responsibility to the Table class to keep track of bets tied to the various Hand instances. This would make the Hand a potential key into a mapping to associate a Hand object with one or more Bet instances. Because Hand instances change state, this is a poor choice for keys to a dictionary.

  • We could put a reference to a Hand object into each Bet object. In this way, as each Bet object is resolved, the relevant Hand object can be evaluated to determine the Outcome instance that applies and what they payout odds are.

  • We could put a reference to the Ante Bet object into the Hand instance. In this way, as each Hand instance is resolved, the relevant Bet instances can be paid or lost.

It’s helpful to look at the alternatives carefullly and try to identify the various forces and consequences.

We suggest designing the Hand class to contain the associated ante Bet object. This is least disruptive to the Bet class definition, which is a simple thing used widely in other games.

Additional Bets. While most Bet instances are associated with a specific Hand object, the insurance Bet instance is always resolved before an additional hand can be created. There doesn’t seem to be an essential association between the initial Hand object and the insurance Bet object. We can treat insurance as a Bet instance that follows the model established for Craps and Roulette – it belongs to the player, rather than a particular hand.

Currently, the Bet instances are collected by the Table instance. If we create a BlackjackTable subclass to use a Hand object when creating a Bet instance, we can have this method do both tasks: it can attach the Bet object to the Hand instance, and it can save the Bet object on the Table instance, also.

BlackjackTable Class

class BlackjackTable

The BlackjackTable class is an extension to Table that handles the additional association between Bet instances and specific Hand instances in Blackjack.

Constructors

BlackjackTable.__init__(self) → None

Uses the superclass constructor to create an empty Table instance.

Methods

BlackjackTable.placeBet(self, bet: Bet, hand: Hand) → None
Parameters
  • bet (Bet) – A bet for this hand; an ante bet is required. An insurance bet, even money bet or double down bet is optional.

  • hand (Hand) – A hand on which the player is creating a Bet.

Updates the given hand to reference the given bet. Then uses the superclass placeBet() to add this bet to the list of working bets.

BlackjackTable.__str__(self) → str

Provides a nice string display of the state of the table.

Hand Rework

The Hand class contains a collection of individual Card instances, and determines an appropriate total point value for the hand.

We need to add a field and some appropriate methods for associating a Bet with a Hand.

Fields

Hand.ante

Holds a reference to the ante Bet for this hand. When this hand is resolved, the associated bet is paid and removed from the table.

Methods

We have two implementation choices here. We’ll show these as setters and getters. However, it’s common to make these both properties of a hand.

setBet(self, ante: Bet) → None
Parameters

ante (Bet) – The initial bet required to play

Sets the ante Bet that will be resolved when this hand is finished.

getBet(self) → Bet

Returns the ante Bet for this hand.

Here’s the alternative implementation. We can use properties for this feature.

Properties for getter and setter

class Hand:

    @property
    def bet(self):
        return self.ante

    @bet.setter
    def bet(self, bet):
        self.ante = bet

In this example, we’ve created a property, bet, so that can write code like this: h.bet to fetch the bet associated with the hand.

By itself, this isn’t too useful. The setter property, however, allows us to write code like this h.bet = Bet("Ante",1). We can then implement any additional processing in the hand that needs to be done when the bet is changed.

Blackjack Table Deliverables

There are four deliverables for this exercise.

  • The revised Hand class.

  • A class which performs a unit tests of the Hand class. The unit test should create several instances of Card, FaceCard and AceCard, and add these to instances of Hand, to create various point totals. Additionally, the unit test should create a Bet and associate it with the Hand.

  • The BlackjackTable class.

  • A class which performs a unit tests of the BlackjackTable class. The unit test should create several instances of Hand and Bet to create multiple Hand instances, each with unique Bet instances.

Looking Forward

Now that we have the core objects – card, deck, hand, and table – we can look at the details of how the game proceeds. This involves creating multiple hands, oferring specialized betting and playing choices, and tracking the evolving state of a number of hands. The next chapter will look at the Game subclass for Blackjack.