Unit 20: Final Project Flashcards
Overview
In this lesson, you’ll use what you’ve learned throughout the course to
build a game: Rock, Paper, Scissors. If you haven’t heard of the game, it
works like this:
Two players face each other.
On the count of three, they both make a sign, at the exact same time,
with one hand. The sign is either a rock (closed fist), paper (open palm),
or scissors (two fingers, open like the victory sign).
Each sign can beat one (and only one) other:
Rock smashes scissors.
Scissors cut paper.
Paper covers rock.
If both players choose the same sign, the game is a draw.
In the game you’ll build, your opponent will be the app itself, so you won’t need to count to three. To play the game, you’ll tap one of the three signs: Rock, Paper, or Scissors.
The app then randomly chooses its own sign and shows the results:
Rock blunts scissors, you win!
The Play Again button goes back to the first screen.
Both screens are in fact the same. The components of the screen change depending on the state of the game.
In this lesson, you’ll build the game logic first, then the UI. Then you’ll put the two together. You won’t get step-by-step guidance, just an outline of what you should do to make the game work. By now you’ve learned everything you need to build the app on your own.
Getting Started
Create a new Xcode project using the Single View Application template. Name the app “RPS.”
The first thing is to build the types and rules that will drive the game.
This will help you think through everything the app will need to do.
There are three different signs that players can use for their turn.
A choice between a limited number of possible values is best represented
as an enum.
You’ll write the Swift code to define each new type in a separate file inside the project. Doing this keeps your project organized and easy to understand.
Sign Enum
Choose File > New > File…, then choose the iOS template set and Swift File from the templates:
After clicking Next, choose the RPS group with the manilla folder icon, and name the file “Sign.swift”:
In the new file, create an enum with cases representing each sign. You can always choose your own names for things you add in this lesson, but it will be easier to follow along if you use names that match these instructions.
Name the enum Sign.
Add a calculated property to give the emoji that represents the Sign.
Game State
There are four different states that the game can be in:
Start. The game displays the three signs and is waiting for the player to
tap one of them.
Win. The player has won and the app displays each move and a winning message.
Lose. The player has lost and the app displays each move and a losing message.
Draw. The game was a draw and the app displays each move and a draw message.
Create another new Swift file to hold an enum with the four cases as named above. Name the file GameState.swift and the enum GameState.
The diagram to the left shows the relationship between the turns and the state of the game.
You need to be able to compare two Sign instances to give a GameState.
For example, a player’s .rock and the app’s .paper would give you .lose.
Add an instance method to Sign that takes another Sign, representing the opponent’s turn, as a parameter. The method should return a GameState based on a comparison between self and the opponent’s turn.
There are many ways that you could write this function. You may wish
to work in a playground first so you can check that all the possible combinations give the correct results.
Random Sign
You need a way to generate a random Sign to act as the app’s turn. The GameplayKit framework contains an API to generate random numbers, as well as to build more complicated aspects of the game. Since you haven’t encountered this framework before now, you’ll get step-by-step instructions. Add import GameplayKit to the top of the Sign.swift file. The import statement makes the API from the framework available for you to use. Add the following line to the file at the top level (not inside any of the struct or enum definitions): let randomChoice = GKRandomDistribution(lowestValue: 0, highestValue: 2) If you call the nextInt() method on randomChoice, the GKRandomDistribution instance will give you a random Int between the two values specified in the initializer.
Add this function to the file at the top level: func randomSign() -> Sign { let sign = randomChoice.nextInt() if sign == 0 { return .rock } else if sign == 1 { return .paper } else { return .scissors } } This function gets a random number, then uses it to create a new Sign instance. You could now play a full game of Rock, Paper, Scissors by calling functions in a playground. But that’s not as much fun as playing it for real. It’s time to build the UI.
Building the UI
Switch to Main.storyboard. Drag a button from the object library onto the scene, and change the button’s title to the (“Fisted hand sign”) emoji.
Set the font size to System 70.0.
Duplicate the button twice and set the titles to the correct emoji:
(“Raised hand”) and (“Victory hand”).
Arrange the buttons in a rough horizontal line, then select them all and embed them in a stack view. Adjust the spacing so there’s a comfortable
gap between the buttons.
Drag in another button below the stack view. This will be the Play Again button.
Drag in a label above the stack view. This will tell the user what’s happening in the game.
Drag in another label at the top of all that. This will show the app’s sign. The font size of this label should be the same as you used for the emoji buttons.
Select the two labels, the stack view, and the button, then embed them in another vertical stack view. Add constraints to pin this stack view to the center of the scene. Adjust the spacing to give some room between the elements.
The final scene should look a little like the screen on the left.”
Making Connections
Create the following outlets so that you can update the screen during play:
The topmost label, which represents the app’s sign
The next label, which represents the status of the game
One for each of the player sign buttons
One for the Play Again button
Create these actions to handle the button taps:
One for each player button
One for the Play Again button
Putting it Together
In this part of the lesson, you’ll be adding code to ViewController.swift to tie together the game logic and the outlets and actions.
Update the user interface
When the game moves from one GameState to another, you have to update the UI.
Add a method on the ViewController class to update the UI based on a GameState parameter. The method should do the following things:
Set the status label’s text property to an appropriate message. Should
the text you use be a calculated property on the GameState enum, or
as a string literal inside the method you’re writing?
Set a different background color to the main view depending on the
state. UIColor is the type that represents a color.
If the game is in the .start state, do the following:
Reset the computer sign label to the emoji.
Hide the Play Again button by setting the value of the button’s
‘isHidden’ property.
Enable and show all of the player sign buttons. (This will make more
sense after you’ve implemented the game features to hide and disable these buttons in a later step.)
There are two places where you should call this method in code right now:
Add a call to the method you’ve just added from viewDidLoad().
Add a call to the method you’ve just added from the action method
linked to the Play Again button.
After you implement the code for when the player has chosen a sign, you’ll need to call this code to update the UI, as well as to create the app’s move and decide the outcome of the game.
Handle Player Button Taps
You should now have separate action methods for each of the player buttons. And each of those methods should call a new method called ‘play’, which takes a Sign parameter.
Add this new ‘play’ method. This method should do the following things:
Get a randomly selected Sign to represent the app’s turn.
Work out the GameState from the two signs, and call the update method you wrote earlier using the new GameState.
Set the app sign label to the appropriate emoji, using the calculated property on Sign you created earlier.
Disable all of the player sign buttons.
Hide all of the player sign buttons except the one the player tapped.
Show the Play Again button.
Make each of the player action methods call the play method, passing in an appropriate value of Sign.
Build and Run
Your game is now complete. Build, run, and have some fun. Congratulations!
20.2: Meme Maker
Overview
Finally, you’re going to build an app that lets you add fun captions to a photo.
Selecting each one of the emoji will change the text above and below its image, so you can mix and match statements to suit your mood.
You’ll be using concepts and skills you’ve already learned. At the same
time, you’ll get to know a new control, the segmented control.
Getting Started
Before you dive in to making the app, spend some time thinking about
the content you’re going to use. The app will need the following:
An image to go in the center
Some text options to go above the image, and an emoji to represent
each one
Some text options to go below the image, and an emoji to represent
each one
Try to think of two, three, or four choices for the top and the bottom. It can be hard to think up working combinations of text. If you get stuck, here’s some inspiration:
Above the image
“You know what’s cool?” could be represented by
“You know what makes me mad?” could be represented by
“You know what I love?” could be represented by
Below the image
“Cats wearing hats” could be represented by
“Dogs carrying logs” could be represented by
“Monkeys being funky” could be represented by
Try to use emoji with different shapes. The segmented control makes them into silhouettes when they’re selected, and it can be hard to tell the difference between a lot of smiley faces.
Once you have your ideas, you can get started building.
Create a new Xcode project using the Single View Application template. Name it “MemeMaker.”
Building the UI
Open Main.storyboard and add the following items, placing them one below the other: A segmented control A label An image view A label
Segmented Control
Change the text of the top label to “Top Caption” and the bottom label to “Bottom Caption.” You’ll be changing these in code later, but this step will help to make your storyboard clear.
Segmented Controls
Segmented controls are used to offer a choice between a limited number of options. For example, a calendar app might have a segmented control to switch between day, week, and month views. Only one option can be selected at a time. You can control the number of segments and the title of each segment.
When the user taps one of the segments, the Value Changed control event is sent. You can access the index of the selected segment from your code. In this app, you’ll update the caption labels when a different option is chosen.
For now, just leave the segmented controls as they are. You’re going to set them up using code instead of in Interface Builder.