< Previous | Contents | Next >

Designing the Classes

Before you start coding a project with multiple classes, it is helpful to map them out on paper. You might make a list and include a brief description of each class. Table 10.1 shows my first pass at such a list for the Blackjack game.

To keep things simple, all member functions will be public and all data members will be protected. Also, Ill use only public inheritance, which means that each derived class will inherit all of its base class members.

Introducing the Blackjack Game 357



image

Figure 10.6

One player wins; the other is not so lucky.



image

A Blackjack game.

None

GenericPlayer A human Blackjack player.

GenericPlayer The computer player, the house.

Player

House Game

A Blackjack playing card.

A Blackjack hand. A collection of Card objects.

A Blackjack deck. Has extra functionality that Hand doesn’t, such as shuffling and dealing.

A generic Blackjack player. Not a full player, but the common elements of a human player and the computer player.

GenericPlayer Hand

None

None

Hand

Card

Hand Deck

Table 10.1 Blackjack Classes

Class Base Class Description

In addition to describing your classes in words, it helps to draw a family tree of sorts to visualize how your classes are related. Thats what I did in Figure 10.7.

Next, its a good idea to get more specific. Ask yourself about the classes. What exactly will they represent? What will they be able to do? How will they work with the other classes?

358 Chapter 10 n Inheritance and Polymorphism: Blackjack


image

Figure 10.7

Inheritance hierarchy of classes for the Blackjack game. GenericPlayer is shaded because it turns out to be an abstract class.


I see Card objects as real-life cards. You dont copy a card when you deal it from the deck to a hand; you move it. For me, that means Hand will have a data member that is a vector of pointers to Card objects, which will exist on the heap. When a card moves from one Hand to another, its really pointers that are being copied and destroyed.

I see players (the human players and the computer) as Blackjack hands with names. Thats why I derive Player and House (indirectly) from Hand. (Another equally valid view is that players have a hand. If I had gone this route, Player and House would have had Hand data members instead of being derived from Hand.)

I define GenericPlayer to house the functionality that Player and House share, as opposed to duplicating this functionality in both classes.

Also, I see the deck as separate from the house. The deck will deal cards to the human players and the computer-controlled house in the same way. This means that Deck will have a member function to deal cards that is polymorphic and will work with either a Player or a House object.

To really flesh things out, you can list the data members and member functions that you think the classes will have, along with a brief description of each. Thats what I do next in Tables 10.2 through 10.8. For each class, I list only the members I define in it. Several classes will, of course, be inherited members from base classes.

image

Table 10.2 Card Class

Member Description


rank m_Rank Rank of the card (ace, 2, 3, and so on). rank is an enumeration for all 13 ranks.

suit m_Suit Suit of the card (clubs, diamonds, hearts, or spades). suit is an enumeration for the four possible suits.

bool m_IsFaceUp Indicates whether the card is face up. Affects how the card is displayed and the value it has.

int GetValue() Returns the value of the card.

void Flip() Flips a card. Face up becomes face down, and face down becomes face up.

Introducing the Blackjack Game 359





image

image

Table 10.3 Hand Class

Member Description


vector<Card*> m_Cards Collection of cards. Stores pointers to Card objects.

void Add(Card* pCard) Adds a card to the hand. Adds a pointer to Card to the vector m_Cards. void Clear() Clears all cards from the hand. Removes all pointers in the vector m_Cards,

deleting all associated Card objects on the heap.

int GetTotal() const Returns the total value of the hand.

image

string m_Name Generic player’s name.

virtual bool IsHitting() const = 0 Indicates whether the generic player wants another hit. Pure

virtual function.

bool IsBusted() const Indicates whether the generic player is busted.

void Bust() const Announces that the generic player busts.

Description

Member

Table 10.4 GenericPlayer Class (Abstract)

Table 10.5 Player Class

Member Description


virtual bool IsHitting() const void Win() const

void Lose() const void Push() const

Indicates whether the player wants another hit. Announces that the player wins.

Announces that the player loses. Announces that the player pushes.

image

Table 10.6 House Class

Member

Description

virtual bool IsHitting() const

void FlipFirstCard()

Indicates whether the house is taking another hit.

Flips over the first card.

image

Creates a standard deck of 52 cards.

Shuffles cards.

Deals one card to a hand.

Gives additional cards to a generic player for as long as the generic player can and wants to hit.

void Populate()

void Shuffle()

void Deal(Hand& aHand)

void AdditionalCards(GenericPlayer& aGenericPlayer)

Description

Table 10.7 Deck Class

Member

360 Chapter 10 n Inheritance and Polymorphism: Blackjack






image

A deck of cards.

The casino’s hand, the house.

Collection of human players. A vector of Player objects. Plays a round of Blackjack.

Deck m_Deck

House m_House vector<Player> m_Players void Play()

Description

Table 10.8 Game Class

Member