If I have seen further it is by standing on the shoulders of Giants. -Isaac Newton
In this lab, you'll implement classes to play a game of Blackjack.
In this lab, you will implement classes to play a game of Blackjack. If you're not familiar with Blackjack, the Wikipedia entry should tell you everything you need to know. The implementation of this game will be fairly simple. You'll create a few classes that are able to interact with each other through methods. Together these classes will simulate a simple game of Blackjack.
You can start the lab by opening up ClassesMagicFun.xcworkspace
in Xcode. This project contains several files in which you will implement the classes needed to run the game. It also includes tests. You can run these tests by select Test from the Product menu, or by pressing Command-U. If you implement the classes correctly, all the tests should pass.
Let's get started!
The tests and game loop have been written for you. In order to complete this lab, you will need to implement the following classes:
The Card
class is defined in Card.swift
. Open that file and add these properties and methods to it:
- A
String
property calledsuit
that holds the card's suit: Either♠️ ,♣️ ,♥️ , or♦️ . - A
String
property calledrank
that holds the card's rank: Either "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", or "K". - A
String
property calledlabel
that returns a string representing both the rank and the suit. For example, the ace of spade'slabel
would return "A♠️ ". - A
value
property that returns the value of the card. Numbered cards are worth their face value, face cards are worth 10, and aces are worth 1. (Aces can be worth 11 at the player's discretion, but this property should return 1 for aces.) - An initializer that takes the suit and rank as parameters.
The Player
class is defined in Player.swift
. Open that file and add these properties and methods to it:
- A
String
property calledname
that will store the name of the player. - A
UInt
property calledwallet
that will store how much money the player has. - A
[Card]
property calledhand
that will store the player's hand. - An
Int
property calledhandSize
that will store the number of cards in the player's hand. - A
UInt
property calledhandValue
that will store the value of the player's hand. In Blackjack, numbered cards are worth the numerical value of the card, face cards are worth 10 points, and aces can be worth 1 or 11 at the player's discretion. Aces are a bit tricky, so you will have to implement some logic to decide if the ace should be worth 1 or 11. (If it makes your implementation simpler, you can assume the player will hold no more than one ace at a time, although this is not guaranteed.) - A
Bool
property calledisBlackjack
that determines if the player's hand value is 21. - A
Bool
property calledisBusted
if the player's hand value is over 21. - An initializer that takes a single parameter, the name of the player. It should assign this value to the
name
property. - A method called
dealCard(_:)
. This method takes one card as a parameter and adds it to the player's hand. - A method called
canPlaceBet(_:)
. This method takes one paramter, the current bet as aUInt
. This returnstrue
if the bet is less than the player'swallet
. - A method called
willHit(_:)
. This method takes one parameter, aUInt
representing the current bet, and returnstrue
if the player will take another card. This player is a bit foolhardy and will take another card if they can afford the bet and their hand size is below 21. - A method called
win(_:)
. This method takes one parameter, aUInt
, that represents the amount the player has won. It should update thewallet
property accordingly. - A method called
lose(_:)
. This method takes one parameter, aUInt
, that represents the amount the player has lost. It should update thewallet
property accordingly.
The House
class is defined in House.swift
. House
is a subclass of Player
. Open that file and add these properties and methods to it:
- Create an initializer that takes no parameters. It should call
super.init()
(thePlayer
superclass's initializer) with the player name of "House". - Override
willHit(_:)
. Like its superclass's implementation, it takes one parameter, aUInt
calledbet
. It should returntrue
if theHouse
's current hand value is below 17.
The Deck
class is defined in Deck.swift
. Open that file and add these properties and methods to it:
- Add a property of type
[Card]
calledcards
. This stores all the cards in the deck. - Implement a
shuffle()
method that will shuffle the deck. (Note that a method calledshuffleInPlace()
has been implemented for you onArray
s. This method will shuffle the elements of a mutable array. You could, for example, callcards.shuffleInPlace()
to shuffle the array ofCard
s.) - Implement a
drawCard()
method. This method should return a value of typeCard?
. If there are cards left in the deck, it should return the next card; otherwise, it should returnnil
.
The Dealer
class is defined in Dealer.swift
. Open that file and add these properties and methods to it:
- Create a
deck
property of typeDeck
to store the deck used to play the game. - Create a
player
property of typePlayer
to store the person who is playing the game. - Create a
house
property of typeHouse
to store the house participating in the game. - Create a
winner
property of typePlayer?
. It should return the winner of the game if the game is over, ornil
if the game is still in progress. - Create an initializer that takes no parameters. It should create a new deck, a new player named "Player", and a
House
. - Implement the method
deal()
. This will be the first deal of the game. Theplayer
should be dealt two cards, and thehouse
should get two cards. If either player has blackjack (21), thewinner
property should be set to the winner of the game. - Implement a
turn(_:)
method. This should take a single parameter,player
, which is thePlayer
whose turn should be taken. The player should be dealt cards until they decide to stay (take no more cards). - Implement a method
award(_:)
. This method should give the winner the current bet, and deduct the current from the losing player.
You can run the test suite to make sure you have implemented the classes correctly. Select Test from the Product menu, or press Command-U. You will get a Test Succeeded message.
You can also run the app. There's no real UI, but you can see whether the house or player won the game by checking the consoler. (The game loop itself is implemented in ViewController.swift
; you can read that to see how the game works.)
Good luck!