VNUHCM
Previous lesson Next lesson
  • Learning content
  • Help
    Do you have any questions while learning?
    Learning instructions Frequently asked questions Email for support
    • Tiếng Việt
    • English
    • Member's information
    • Registered courses
    • Log out
  • Cohota
  • HƯỚNG DẪN HỌC TẬP

  • View detail >>
    You have completed 0% of the course
  • HƯỚNG DẪN SINH VIÊN ĐĂNG NHẬP HỆ THỐNG
    • Hướng dẫn đăng nhập
    • Hướng dẫn vào khóa học
  • Introduction
    • Welcome
  • Unit 1: Values
    • Introduction - Unit 1: Values
    • Get Started With Values
    • Play with Values
    • Playground Basics
    • Naming and Identifiers
    • Simulation
    • Strings
    • Constants and Variables
    • Word Games
    • Build a PhotoFrame App
    • Design for People
  • Episode 1: The TV Club
    • Introduction - Episode 1: The TV Club
    • Searching for Content
    • Sharing Personal Information
    • Ordering Online
    • Reflection: Episode 1
  • Unit 2: Algorithms
    • Introduction - Unit 2: Algorithms
    • Get Started with Algorithms
    • Play with Programs
    • Functions
    • Types
    • Parameters and Results
    • Making Decisions
    • BoogieBot
    • Data Visualization
    • Build a QuestionBot App
    • Design an Experience
  • Episode 2: The Viewing Party
    • Introduction - Episode 2: The Viewing Party
    • Accessing the Show
    • Streaming on the Network
    • Reflection: Episode 2
  • Unit 3: Organizing Data
    • Introduction - Unit 3: Organizing Data
    • Get Started with Organizing Data
    • Play with Complex Data
    • Instances, Methods, and Properties
    • Arrays and Loops
    • Structures
    • Enums and Switch
    • Testing Code
    • Processing Data
    • Pixel Art
    • Password Security
    • Visualization Revisited
    • Build a BouncyBall App
    • Design a Prototype
  • Episode 3: Sharing Photos
    • Introduction - Episode 3: Sharing Photos
    • Capturing Images
    • Posting on Social Media
    • Reflection: Episode 3
  • Unit 4: Building Apps
    • Introduction - Unit 4: Building Apps
    • Get Started with App Development
    • Play with App Components
    • Color Picker
    • ChatBot
    • Rock, Paper, Scissors
    • MemeMaker
    • Build an ElementQuiz App
    • Design for Impact
  • Appendix
    • Episode Technical Concepts
    • Glossary
Course overview
Assessment

Progress
Criteria name Weighting (%) Score Progress (%)
Unit 4: Building Apps

Rock, Paper, Scissors

Unit 4: Building Apps|Play

What you'll build

A Rock, Paper, Scissors game.

What you'll learn

  • How to build game logic using the skills you've learned so far in this course.
  • How to apply the Model-View-Controller (MVC) design pattern in your code.

Key Vocabulary

  • Model-View-Controller
  • Random number

Introduction

Think back to your first coding lessons in this course. You’ve come a long way​ from counting animals at a pet show!

In previous lessons, the focus has been on learning new things: programming topics in Swift, and app-building topics in Xcode and​ Interface Builder. Here, you'll focus on using what you’ve learned to create an​ app from scratch. The instructions you'll be following are less detailed, which will challenge you to recall all your skills and knowledge.

The game you're building is 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.

Rock, Paper, Scissors showing choice of signs

The app will randomly choose a responding sign and show the results:

Paper covers rock, you win!

Paper covers rock, you win!

The Play Again button goes back to the first screen.

Both screens are in fact just one storyboard scene whose components change depending on the state of the game.

You'll use the Model-View-Controller (MVC) design pattern to make this app. The purpose of MVC is to separate the parts of your app, giving clearly defined responsibilities to each part. That way, you'll keep your code easy to read and easy to think about. MVC is the default pattern used natively in the iOS SDK, Cocoa Touch; and consequently many (or most) iOS developers follow this pattern.

Recall that you've already seen the value of separation between different app components in QuestionBot and Chatbot. You worked on a brain and a data source that had a focused set of tasks that they performed, which enabled you to create a functioning app without touching the rest of the project. You also worked on connecting UI elements, such as switches, to your controller code in the ColorMix app.

You’ll build the game logic (the model) first, followed by the UI (the view). Then you’ll put the two together with the controller. By now you’ve learned everything you need to build the app on your own. So you won’t get step-by-step guidance, just an outline of what you should do to make the game work.

Part 1 - Creating the Model

Create a new Xcode project using the App template. Name the app “RPS.”

Your first task is to build the types and rules that will drive the game—the model data. This step 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.

Creating a Sign Enum

In the project navigator, right-click (or Control-click) the gray folder named "RPS," choose "New File...", and make sure that Swift File is highlighted in the dialog that appears. 1

New file template chooser with iOS / Swift File selected

After clicking Next, name the file "Sign" (the hidden ".swift" extension will be added automatically). Make sure that the Group is set to the RPS folder you clicked. 1

New file naming screen with group and name entered

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 computed property to give the emoji that represents the Sign.

Defining Game State

There are four different states that the game can be in:

  • Start. The game is showing the three signs and is waiting for the user to tap one of them.
  • Win. The player has won and the app is showing each move and a winning message.
  • Lose. The player has lost and the app is showing each move and a losing message.
  • Draw. The game was a draw and the app is showing each move and a drawn message..

Create another new Swift file to hold an enum with the four cases as named above. Name the file (and the enum) GameState.

This diagram to the left shows the relationship between the turns and the state of the game:

Diagram showing the game states

You need to be able to compare two Sign instances to give a GameState. For example, a player’s .rock and the computer’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.

Generating a Random Sign

You need a way to generate a random Sign to act as the app’s turn. If you hand-code an array of arbitrary values, your app might look random at first glance, but users would soon notice that it repeats the same sequence each time it runs. What you want is a process to generate a sequence of values that are completely different each time the app runs.

The Int type has a method for generating random values called random(in:) which takes a Range argument. The Range type simply describes a range of values. The easiest way to create a Range is to specify its upper and lower bounds separated by the closed range operator, .... The resulting range contains all the values including the upper and lower bounds. For example, the expression 1...100 represents all integers between 1 and 100.

Add this function to the file at the top level (outside the declaration of the Sign enum):

func randomSign() -> Sign {
    let sign = Int.random(in: 0...2)
    if sign == 0 {
        return .rock
    } else if sign == 1 {
        return .paper
    } else {
        return .scissors
    }
}

This function gets a random number and 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.

Part 2 - Building the View

The UI of your app is the view component in the MVC design pattern. You'll create it first, then bring the app to life with the controller in the final part of the lesson.

Switch to the Main storyboard. Click the Devices icon at the bottom of the window and select iPhone 14 Pro. 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 to System 70.0.

Arranging UI Elements

Duplicate the button twice and set the titles to the correct emoji - ✋ (“Raised hand”) and ✌️ (“Victory hand”). ️

Arrange the buttons in a horizontal line at the center of the scene. To ensure they're aligned vertically, you can use the guides as you drag. Space them out horizontally, estimating their positions so that they're as evenly distributed as possible. (If you want, you can do the work necessary to position them exactly. If you hold down Option while moving your mouse around the scene, you'll get indicators for the exact distance between the currently selected object and its surroundings.)

Drag in another button underneath the three hand sign buttons. This will be the “Play Again” button. Set its font to Title 1 in the Text Styles section of the menu.

Drag in a label above the three hand sign buttons. This will tell the user what's happening in the game. Make it the full width of the view, and choose Title 1 for the font.

Drag in another label above everything else. This will show the app's sign. The font of this label should be the same as the font used for the emoji buttons.

Both labels should have center-aligned text.

The final scene should look a little like this. 1

Storyboard scene showing the elements of the game in place

Making Connections

Show the assistant editor, then create 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

Next, create actions to handle the button taps:

  • One for each player button
  • One for the “Play Again” button

Part 3 - Building the Controller

In this part of the lesson you’ll be adding code to ViewController to tie together the game logic and the outlets and actions. As the file name implies, this is your controller code—it connects your game model to the views in your UI. When you're done, you'll have a simple example of a functioning MVC app, programmed in a way that's similar to many iOS apps.

Updating the User Interface

When the game moves from one GameState to another, you have to update the UI.

Add a method 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 computed 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. Remember, UIColor is the type that represents a color. To access the main view, use the view property.
  • 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, passing in .start as an argument in each call:

  • 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.

Handling 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 computed 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 and run on the iPhone 14 Pro simulator, and have some fun. Congratulations!

Reflection Questions

Can you think of other use cases for random behavior in apps?

Examine some of your favorite apps. Break each of them down into model, view, and controller components, describing what each component would do in that app.

Summary

Congratulations! You’ve built an app from scratch using what you’ve learned in the course. The next lesson gives you another opportunity to practice building a complete app from start to finish—one that's more creative both for you and for the user.

Report error