by admin

Blackjack Summary

Jun 10, 2016 Ronald Koltnow rated it liked it This is the eighth adventure of Robert B. Parker's laconic lawmen Virgil Cole and Everett Hitch, and the fourth written by Robert Knott. Like its predecessors, it is mind candy, all fluff and sugar, and a fun way to spend a couple of hours. Mar 28, 2008 Directed by Robert Luketic. With Jim Sturgess, Kate Bosworth, Kevin Spacey, Aaron Yoo. '21' is the fact-based story about six MIT students who were trained to become experts in card counting and subsequently took Vegas casinos for millions in winnings.

  1. Poker Summary
  2. Operation Blackjack Summary

Welcome back to our Deep Dive series on building the casino game Blackjack in C# and Blazor WebAssembly!

In this second part, we're going to use the modeling ideas we wrote down in the previous post to build a complete C# model for a Blackjack game.

You might want to read the previous post in this series before reading this one. Here it is:

Also, there's a sample GitHub repository that has all of the code used in this series.

All caught up? Good! Let's jump right in.

21 blackjack summary

Basic Enumerations

Let's begin our C# modeling with the most basic type we can model: enumerations for the card's suit and value.

We will deal with the score later in this post.

Playing Cards

The next-most-simple object we can model is the individual playing cards. You may recall from the previous post that we decided that the Card object should have the following attributes:

  • A suit
  • A value
  • A score

Suits and values are already defined as enumerations, and by making them properties of the Card object we can calculate a score.

Visibility

We need to consider one additional situation for this model, and that is this: the dealer has one card that is not visible to the player. So what model should that property (visibility) be a part of?

There are several ways to answer this question; the one we are going with is that we will make a new property IsVisible on the Card object. This property will be settable outside of the object so that the Dealer can mark their cards as not visible.

IsTenCard

Lastly, and as a convenience, we can define the property IsTenCard to identify if the given Card instance is a Ten, Jack, Queen, or King, and thus worth ten points.

Image URLs

We are implementing the display for our cards as individual images, with names like cardClubsJack.png, cardHeartsSix.png, cardSpadesAce.png, etc.

The images look like this:

Summary

Our Card object will need a property which stores the name of the image to display for that Card.

The Deck

The next object we can build is the deck of cards.

A Collection of Cards

The deck, at its core, is very simple: it's a collection of Card objects. But what kind of collection?

One of the properties of a real-world deck of cards is that, when drawing a card, we always draw from the top of the deck. There is a collection class in .NET that implements similar functionality: the Stack<T> class. Stack<T> defines a Pop() method, which removes and returns the 'topmost' object in the collection.

Our new CardDeck object will need a property of type Stack<Card> which stores the individual Card objects.

Count, Add, and Draw

We must now consider a few properties. First, we need to keep track of how many cards remain in the deck; if the number of cards gets below a certain value, we need to reshuffle the deck.

As we decided in the previous post, we need methods to add cards to the deck and to draw a card from the deck. These methods are fairly straightforward to implement:

Initialization and Shuffling

The most complex part of the CardDeck implementation is this: when we create a new instance of CardDeck, we need to first populate the cards with the correct number and suits, and then shuffle the cards thoroughly.

Let's start by creating a constructor for our CardDeck object, which first creates and inserts all of the cards needed.

We now need to extend this constructor to shuffle the cards. For this, we'll be using the venerable Fisher-Yates Shuffling Algorithm I blogged about a while back:

Here's that implementation:

Our CardDeck object is now ready for use! We can move on to the more-complex objects, starting with Person.

The Person Object

Poker Summary

Recall from the last post that we need a common Person object that both Player and Dealer will inherit from. That Person needs the following abilities:

Operation
  • Keep a hand of cards
  • Use the hand to calculate a score
  • Use the hand to determine if they are busted

The Visible Score Problem

First, though, we need to solve an unsolved problem from the previous post: how do we deal with the Dealer object's visible score (e.g. the score from only the face-up cards)?

This is one of those places where the modeler (i.e. us) can make 'executive decisions'. There are a couple of ways to model the visible score, such as making it a property of the Dealer object, a property of the Person object, or an external method. For this post, I have chosen the second option: we will make a property VisibleScore that is part of the root Person object, since it is Person that holds the property for Cards. Please note that none of these options are inherently worse than the others, they just require different implementation details.

With all that in mind, we can build a Person object with a set of properties to represent those abilities. Here's the skeleton object:

We now need to fill in the other properties.

True Scores and Visible Scores

The most complex thing the Person object will do is calculate that person's current score. Because we want a property for the VisibleScore and a property Score for the true score, we will use a private method to calculate the score.

The algorithm to calculate the score goes like this:

  1. PASS IN a value that determines whether we calculate the visible score only, or the true score.
  2. IF the sum value of all cards is less than or equal to 21, return that sum.
  3. IF there are no Aces in the person's hand AND the sum is greater than 21, the person has bust, so return the score.
  4. IF there are Aces in the person's hand...
  5. WHILE there are Aces left that have not been converted
  6. CONVERT a single Ace to being worth 1 point.
  7. IF the score is now less than or equal to 21, return the score.
  8. END WHILE
  9. IF the score is STILL greater than 21, the person has bust, so return the score.

The resulting code looks something like this:

We can then make two properties; one for the true score, and one for the visible score.

Checking for Blackjack and Bust

In the previous post, we decided that we wanted a special display that normally displays the Person's score, but will also show when they get a blackjack and when they bust.

To do this, we first need a property that checks to see if the Person has a blackjack. A person has a blackjack if;

  • Their score is exactly 21 AND
  • They have exactly two cards AND
  • One of their cards is an Ace AND
  • The other card is a ten-card

Here's the property for this:

We also want a convenience property that shows if the Person has bust:

The Score Display

Using the properties HasNaturalBlackjack and IsBusted that we just defined, we can now create a property to display the Person object's score. This property uses all of the properties of Person that we have defined so far:

Blackjack Summary

Convenience Methods - Adding a Card and Clearing the Hand

There are two convenience methods we still need, though your implementation may forego them.

Blackjack rules summary

First we need a straightforward method to add cards to the Person's hand:

Finally, we need a method to clear the Person's hand:

With all of that, our root Person object is complete! Now we can move on to the Dealer and Player objects.

The Dealer Object

Let's start with the Dealer object.

The Dealer needs to inherit from the root Person object:

From there, we can add the properties unique to the Dealer

The Card Deck

Let's start with a property for the CardDeck object:

Dealing

The Dealer object will also need three methods:

  • A method that draws a card from the deck.
  • A method that draws a card from the deck to give to the player.
  • A method that draws a card from the deck to give to the dealer.

These methods end up being pretty straightforward:

Has an Ace Showing

We also need one convenience property that is used for the Insurance special play: whether or not the Dealer has an Ace showing.

With that, our Dealer is complete, and we can move on to implementing the Player object.

The Player Object

The Player object, like the Dealer, needs to inherit from Person.

Funds

The most distinguishing characteristic of the Player is that they have funds, i.e. the money they walked up to the table with. Let's create a property for those funds, and set an initial amount:

Bets

We also need properties to keep track of the Player's bets: their main bet they make before each hand, and the optional Insurance bet.

We will also want a convenience property to show whether or not the Player has made an insurance bet:

The Change Amount

After each hand, the player's funds may change based on whether they won or lost the bet. Let's write a property that keeps track of this change amount.

Has Stood

We need a convenience property to show whether or not the player has decided to stand:

Payouts

Finally, we need a method for the player to adjust their Funds property based on whether they won or lost the bet after each hand.

Now our Player object is complete and ready to gamble his/her chips!

Summary

Phew! That was a lot of work. But now our implementation of Blackjack in C# is ready to go, and we can start building the Blazor components which will make up the display area of the game.

We can now build components for:

  • The Player and Dealer hands
  • The Player and Dealer scores (visible and total)
  • The Player's funds and how they change after each hand
  • The current bet
  • The status of the Player (e.g. whether or not they have stood) AND
  • The result of the hand (e.g. whether the Player wins or loses)

Implementing these components and more is exactly what we will do in the next part of this series. Stick around!

Do you have a way you can improve on my design? Submit a pull request or let me know in the comments! I am always looking for input from my dear readers.

Happy Coding!

Preview of BlackJack Summary:

Full of mystery and romance, Black Jack is a suspenseful, action-filled story. Written in a descriptive style, the story includes authentic historical details that bring its eighteenth-century setting to life without ever becoming dull. Touches of ironic humor, aimed mostly at self-important people, enliven the story.

Garfield endows his many unusual, quirky characters with believable personalities, making them recognizable as real people. His depictions reveal a tolerance for human frailty and a belief in every person's potential for good. Nevertheless, his characters are complex, suggesting that there is often more to a person than appears on the surface.

Operation Blackjack Summary

Black Jack explores the often subtle differences between good and evil and shows how difficult it can be to tell them apart. The divisions between kindness and cruelty, love and hate, truth and hypocrisy, trust and jealousy, knowledge and ignorance can be murky as each of these qualities sometimes masquerades...