Assignment 1: Simon

Overview

For this lab you'll be fleshing out the Simon game we started together in lab/lecture. In doing so, you should:

  1. Familiarize yourself with the Xcode IDE,
  2. Get comfortable with the Objective-C programming language,
  3. Recognize some of the key software design patterns used in iOS development (including target-action, delegation, and MVC)

Preliminaries

Good news: if you've been following along in class and during our lab sessions you're at least halfway done with this assignment (including extras)!

At this point you should have already figured out how to clone the read-only course repository (at http://bitbucket.org/michaelee/cs442) and subsequently add, commit and push to our private, shared repository on BitBucket (named cs442-spring12-yourusername.git). Your only "submission" will be performed by pushing to this shared private repository.

Before proceeding -- even if you've already put some work into the Simon game previously -- make sure you can do the following:

  1. Identify the model, view and controller components of your application, and what their responsibilities are.
  2. Explain how the user interface components are associated with the various properties of the ViewController class (the IBOutlet and IBOutletCollection marked properties).
  3. Explain how the target-action association is made from events that occur in the UI (e.g., button taps) to methods (typically marked IBAction) in your view controller object.
  4. Set breakpoints in your view controller, run till stopped, then step through and examine the state of the application. Make sure you can locate:
    • the current thread's stack trace
    • local variables
    • instance variables (for these last two, remember that you can either hover over symbols in the editor or look in the debug window for a listing)
  5. Log data with NSLog (and find the console output).
  6. Explain why GUI-updates made in event handling functions (e.g., those marked IBAction) are not "seen" until after the functions return.
  7. Run your project through one of the profiling tools (e.g., the Leaks tool) and explain the output.

Requirements

The following paragraphs describe the functional requirements of your final application.

Note that each builds on the one before, and as such there may be some redundancy. If you wish you may certainly read through the entire section and skip ahead to implementing the "final" version of the app from the outset. If you're not entirely comfortable with iOS development or Xcode just yet, however, I recommend that you proceed stepwise.

¶ Basic gameplay

Your app should implement a basic Simon Says game, where the different colored buttons from the original game are replaced with labeled buttons. A "start" button should be incorporated into the interface, which will start playback of the sequence. (If you'd like to see a classic implementation of the original game, see http://www.lilgames.com/simon.shtml.

After playback -- during which all interface elements should be disabled (see UIView's userInteractionEnabled property for affecting this) -- the user will enter her guess from memory and:

At any point during entry, the player may tap the "start" button again to begin a new game (with a different sequence).

Note that:

  1. The sequence should be randomly generated and stored within the app's model object (SimonEngine).
  2. During playback, each button in the sequence should be flashed separately --- if a button is to be flashed more than once in succession, there should be a period between flashes where the button is not highlighted.

¶ Win & Loss

After a sequence of predetermined length (initially hardcoded) has been correctly entered from memory, the player wins, and the game should display a suitable label. Tapping the "start" button will hide the label and start a new game.

If and when the player taps a wrong button while entering the sequence from memory, the game should display a suitable "Game Over" label, while at the same time highlighting the button she should've entered. Note that the button should remain highlighted until the "start" button is tapped, at which point the label will be hidden and the button unhighlighted to commence a new game.

¶ "Reset" (i.e., the cheat button)

Next, you should incorporate a "reset" button into the game view which allows the player to, in essence, cheat. Tapping "reset" will play back the current sequence again (up to the same point) so as to allow the player to refresh her memory.

After playback has been completed the second time, the user will once again be able to enter her guess. If successful, the game advances (or she wins, if it is the last step), and if unsuccessful a new game is started, as before.

Important: the "reset" button can only be used once per playback, and only before starting to enter a sequence from memory! E.g., consider the following scenario:

  1. Player has correctly entered a sequence of length 5
  2. The game plays back the same sequence, with an added 6th step
  3. Player failed to remember the sequence, and hits "reset"
  4. The game plays back the same sequence (including the 6th step)

At this point the "reset" button is no longer useable. The player must either guess or hit "start" to play a new game. If she correctly enters the current sequence, she may use the "reset" button again after the next playback sequence.

¶ Splash screen

Create a separate view (controlled by a separate view controller) that appears when the app is first started. This view should contain a logo of sorts (could be just a large text label) and a "Play game" button that results in the game view you've been working on previously to be displayed.

You should also add a button to the game view that, when tapped, will take you back to the splash screen.

Note that transitioning between the splash screen and the game screen should not affect the current game (if one is already underway). E.g., the following scenario is possible:

  1. Player starts app and taps "Play game" to go to the game screen
  2. Player plays up to a playback sequence of length 4
  3. Player taps button to return to splash screen
  4. Player taps "Play game" button to go back to game
  5. Player taps "Reset" to see sequence that was previously underway

For this assignment, please stick to using the view controller's presentViewController: animated:completion: method (i.e, for presenting a modal view) instead of a navigation controller --- we'll save the latter for the next assignment.

¶ Difficulty level

Incorporate a slider into the splash screen that allows the user to select a difficultly level: the higher the difficulty, the longer the sequence the player must correctly enter to win. Note that dragging the slider should dynamically update a label that indicates the current difficulty level (see below for a possible implementation):

Difficulty slider

Note that when returning to the splash screen from an ongoing game, the difficulty setting should reflect the current level. If the difficulty setting is modified when returning to the splash screen from an ongoing game, tapping "Play game" should end the current game. If the difficulty setting is not modified, however, the current game can be resumed (as previously described).

To accompany the different difficulty levels, an indicator (label) should also be placed in the game view that shows the player the length of the last playback sequence, and the length of the final playback sequence. E.g., if the difficulty setting is 15 and the player is currently entering her guess for a playback of length 8, then the indicator should display "8/15".

Implementation details

There are myriad ways of implementing the different pieces of this assignment, and for the most part you are at liberty to choose your own methodology. There are, however, a few details that I ask you to pay particular attention to:

Suggested Extras

In this and all future assignments, this section provides you with a list of "extra" features you can implement to increase the likelihood of receiving a "check-plus" grade.

  1. Jazz up your UI! You can use colors and/or images for the buttons to really recreate the original "Simon" experience! ;-) More kudos for more polish.
  2. Add yet another difficulty setting that adjusts the speed of playback (i.e., length of button highlights during playback).
  3. Add another splash screen button that takes you to a two-player mode, where the first player is able to "record" a sequence for the other person to guess, and the second player wins by guessing the sequence. Note that the "Reset" button should still be available, and the length of the sequence should be controlled by the difficulty setting described above.

Of course, feel free to implement other extra features you think of -- you may want to run ideas by me first so I can give you an idea of how worthwhile I think they are.

Be sure you list all the extras you implemented in your app in a comment atop your app delegate's header file (i.e., AppDelegate.h), so I don't miss out on anything cool.