- Create custom data models in Swift:
- Declare properties.
- Write initializers.
- Write methods.
- Declare properties as readonly or private.
- Write and utilize private methods.
- Write a custom setter.
- Use calculated properties.
- Subclass in Swift:
- Override the superclass's initializer.
- Extend the class.
- Combine the usage of your classes to assemble a working back-end.
Blackjack, also known as "twenty-one", is a casino card game in which a player attempts to build a hand that is closer to a score of 21 than the house (or dealer's) hand without going over a total of 21 (or "busting"). The Ace's base value is one (1), but can be used as a value of eleven (11) if doing so does not bust a hand. Players are initially dealt two cards and choose to be dealt additional cards (to "hit") or to hold their hand until the end of the round (to "stay").
Open swift-blackjack.xcworkspace
.
You may deselect the target membership of the testing files in order to work on the classes-one-by-one, reenabling each class's test file as you go along. This option is found in the File Inspector pane of the Utilities area when the relevant file is selected in the Project Navigator pane of the Navigator area.
Note: Doing this may report false-positives to your Learn.co profile's local build light, so make sure you have test results for all five custom classes before regarding your solution as complete.
- Create a
Card
class. It will need the following properties:
suit
, a string,rank
, a string,cardLabel
, a string, andcardValue
, an unsigned integer.
- Write an initializer for
Card
that takes two arguments forsuit
andrank
.
- It should also set the
cardLabel
property to string containing both the suit and the rank in the form of♠︎A
(for the Ace of Spades). - It should also set the
cardValue
property appropriately for scoring Blackjack: Aces are worth one, number cards are worth their face values, and face cards are worth ten.
- Set up two class methods called
validSuits
andvalidRanks
that return arrays containing the four suit icons and the thirteen string representations of the ranks (Ace through King).
-
Create a
Deck
class. It should have two private array properties for holding cards: one for holding the remaining (undealt) cards, and the other for holding the dealt cards. The test file cannot see them so name them yourself. -
Write an initializer that generates the 52 unique cards required for modeling a standard 52-card deck. It should hold them in the array of cards that can be dealt.
-
Add a
description
string property that can be used to print information regarding the cards to the console. This string will need to contain information about the remaining cards and dealt cards.
Top-tip: Set this up as a calculated property that calls a private method which returns a string. -
Write a
drawCard()
function to return the next card. It should remove that card from the remaining cards and add it to the dealt cards. -
Write a
shuffle()
method that gathers up the dealt cards and randomizes all 52 cards.
Hint: Thearc4random_uniform()
C function is accessible in Swift also.
- Create a
Player
class. It will need nine properties total:
name
, a string,cards
, an array ofCard
objects,handscore
, an unsigned integer,blackjack
, a boolean,busted
, a boolean,stayed
, a boolean,mayHit
, a boolean,tokens
, an unsigned integer, anddescription
, a string.
-
Write an initializer which takes an argument for the
name
property. Make the initial value of thetokens
property100
. -
Make
description
a calculated property which returns a string detailing the object's current state. -
Make
handscore
a calculated property that evaluates thecards
array. It may use one Ace as a value of 11 if doing so will not bust the hand.
Hint: You can have a calculated property call a private method to keep the property declaration section clean. -
Make
blackjack
a calculated property that determines whether the hand is a blackjack (a score of 21 with only two cards). -
Make
busted
a calculated property that determines whether the hand is busted (over score of 21). -
Leave the
stayed
property initialized tofalse
. It will need to be used to hold state during a round. -
Make
mayHit
a calculated property that determines whether the player may take a new card (if the hand is not busted, is not a blackjack, and if the player has not stayed). -
Write a method called
canPlaceBet()
which takes an unsigned integer argument and returns a boolean of whether or not the player can afford the submitted bet. -
Write two methods called
didWin()
anddidLose()
which both take an unsigned integer for the value of the bet and appropriately update the value oftokens
.
-
Create a
House
class. It should be a subclass of thePlayer
class. -
Override the superclass's initializer to set the
wallet
property to1000
. -
Add a calculated property
mustHit
that returns a boolean of whether the house must take a new card or not. Treat the "house rules" as staying at a score of seventeen (17).
- Create a
Dealer
class. It should have four properties:
- a
Deck
calleddeck
, - a
House
calledhouse
and named "House", - a
House
calledplayer
and named "Player", and - an unsigned integer called
bet
which starts at zero.
Note: In this console-version of the game, since we don't have a user interface for providing input, we're going to use theHouse
class'smustHit
method for the player's decision-making also.
-
Write a method called
placeBet()
which takes an unsigned integer argument and returns a boolean of whether or not the house and the player can both afford the submitted bet. If they can, this method should record the value of the bet being placed. -
Write a method called
deal()
that deals a new round, giving two new cards each to the player and to the house. -
Write a method called
turn()
which takes aHouse
argument (since in this console version both the house and the player will be used with this method). If theHouse
object is allowed to take a card, it should be asked if it wishes to hit or stay. If theHouse
object wishes to hit, the dealer should then give it a card. If theHouse
object wishes to stay, then the decision to stay should be recorded. -
Write a method called
winner()
which returns a string containing the result of the round. It should:
- return
"player"
if the player wins, - return
"house"
if the house wins, and - return
"no"
if there is not yet a winner.
Keep in mind that:- a bust is an immediate victory for the other player,
- the house wins ties, and
- the player can win by holding five cards that are not a bust.
- Write a method called
award()
that uses the result of thewinner()
method to award the bet to the winner of the round. It should add the value of the bet to the winning player and subtract the value of the bet from the losing player. Theaward()
method should also return a string message expressing the result of the round in a phrase or sentence.
Top-tip: Swift'sswitch
statement works with objects—in contrast to Objective-C's which only works with integers and enums.
-
In
AppDelegate.swift
, add aDealer
property calleddealer
. -
Write a method called
playBlackjack()
that calls the different steps in the game in order. The player and house should be offered a maximum of five cards total. -
Add
print()
statements utilizing thedescription
properties that you wrote in order to build a readout of the game as it progresses.
-
Add functionality to handle a "push", the case in which both the house and the player are dealt blackjack hands. A "push" is handled like a "tie", with the player's original bet being returned without modification.
-
Create another subclass of
Player
calledShark
. Give it a method calledwillHit()
that returns a boolean of whether the best strategy is to hit (true) or stay (false) according to a Blackjack strategy card.
- (Easy) Make a decision based upon whether the current hand score is soft (contains an Ace) or hard (without an Ace).
- (Hard) Make a decision also based upon the "visible" cards currently in the House's hand (remember that the house's first card is dealt face-down and only revealed at the end of the round).
- Add functionality to give a player the option to "double down" on the bet.
- If you wrote the
Shark
class, add behavior to the class's decision-making that accounts for this aspect of Blackjack strategy.