iPhone Programming - Spring 2013

Nathan Hull

Assignment 3 - Due: Friday, March 15th


In this assignment you will create a new iPhone application that will demonstrate the use of Views, a Tab Bar, and a Picker.

This app tests the strength of your "Alien ESP" by choosing a random card out of a 52 card deck and challenging you to guess the card!

When the "Alien ESP" program starts, it (secretly) chooses a random card. It then presents you with three views from which to choose: In the first view presented, the "Unlock It" view, you unlock the puzzle by using a two component Picker to 'guess' the hidden card. In addition, this view also displays some brief instructions and at least one picture.

You can then select the "Check It" view (available through the Tab Bar) to see if your guess is correct. In this view, a message is displayed which indicates whether the guess is correct or not. Also displayed is the total number of guesses the player has made. If the player's guess is correct, a celebratory musical phrase is played and the program exits. Otherwise, the player may elect to reselect the "Unlock It" view in order to try another guess.

The third view is the "Get Hint" view. In fact, it is more than a hint: it simply tells you which card the computer picked. That way, you don't have to try all 52 possibilities! (Of course, true Aliens never have to choose this option...)

Alien Card

 

The Play

The random card should be chosen when the application loads. There is only one card per run. Note that there needs to be a Tab Bar controller in your root controller which links the three views, and that you should provide custom icons for each of the buttons.

"Unlock It" View: This is the first view which is displayed and is the one in which you 'unlock' (aka, 'guess') the puzzle. There should be thirteen possible positions for the first component (face value), and four for the second (suit). Note that the picker used for the suit must be represented using graphics. There should be no hint on this page about what the solution might be. In the Interface Builder, be certain to check "User Interaction Enabled" on the "Picker View Attributes" window so that the player can move the wheels by hand.

"Check It" View: In this view, you should print out the name of the card the player guessed (e.g., "The Jack of Spades" or "The Two of Hearts") and a message as to whether that guess is correct or not. You should also print out the total number of guesses which the player has made. If the guess is correct, you should play the musical phrase, wait awhile for it to finish playing, and then quit the application. (You only have to wait an approximate amount of time - It doesn't have to be exact.)

"Hint" View: Don't display the answer directly: Make the player push a button to display the answer. You might even press the issue with a "Are you Sure?" response. Make certain to register your dismay that you are having to give away the answer.

Some Suggestions

You may want to model your code after the Picker application which was developed in Chapter 7 of our "Beginning iOS 6 Development" book. (If you haven't already downloaded the source files for the book, the code for the Picker application is available here). In particular, look at the "Simple Game" which is described on page 209. The code for the game is in the files BIDCustomPickerViewController.h and BIDCustomPickerViewController.m.

In order to play the audio file, you will need to include an .mp3 or .wav file in your build. Then, you will use the Audio Toolbox Framework to play it. You will need to link to the Audio Toolbox Framework manually, and that process is described on page 215.

For the random number, use the standard C function:

  random( )

Don't forget to seed the random number generator:

 srandom(time(NULL));

Here is something interesting: You can actually terminate an application under program control. In the header file, place this "Category" which is an extension to the existing class:

   @interface UIApplication (extended)
   -(void) terminateWithSuccess;
   @end

Then in your code (perhaps as the result of a button being pressed or some other condition) you can place the following instruction:

   [[UIApplication sharedApplication] terminateWithSuccess];

Here is a method from the book's Picker application which uses Audio. Note that after playing the audio file, it waits awhile before calling the next routine:

#import <AudioToolbox/AudioToolbox.h>


-(void)playWinSound
{
if (winSoundID == 0) {
NSURL *soundURL = [[NSBundle mainBundle] URLForResource:@"win"
withExtension:@"wav"];
AudioServicesCreateSystemSoundID((__bridge CFURLRef)soundURL,
&winSoundID);
}
AudioServicesPlaySystemSound(winSoundID);
self.winLabel.text = @"WINNING!";
[self performSelector:@selector(showButton)
withObject:nil
afterDelay:1.5];
}

Communication between the view controllers

This assignment has many view controllers: one "root" controller derived from UITabBarController and one for each view accessed via the tab bar. These controllers need to work together; for example, the hint view controller needs to know the secret card. The best way to get them all to work together is to create a custom root controller that "owns" all the interesting data like the secret card, the count of guesses, etc. You can add methods to the root controller that provide the functionality that each sub-controller needs. For example, your root controller might have a method called "checkGuess" that takes a guess and checks it against the secret card, returning true if the guess is correct.

Note that every class derived from UIViewController has a very useful property called "presentingViewController" which gets set automatically when you add a view controller to the tab bar. This property gets set in navigation and tab bar controllers, among others. You can use this property to access your root view controller, including its methods and data. For example, when the user switches to the "Check it" view, that view might execute code similar to the following:

{
   MyRootController* myRootController = (MyRootController*) [self presentingViewController];
   if ([myRootContoller checkGuessWithValue:value andSuit:suit]) {
   // A correct guess!
   } else {
   // An incorrect guess!
   }
 }
assign4

Note that the Apple-defined presentingViewController returns a generic UIViewController; you should cast it to the correct type before using it.

http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html


Small Extra Credit: In the "Unlock It" view, have the Picker audibly 'click' each time one of wheels is turned. (Actually, if you run this on the iPhone itself rather than the simulator, a sound is automatically played!)

Medium Extra Credit: Save your Low Score from play to play and display it on the "Check It" view page. Since your application quits when the player has successfully solved the puzzle, this Low Score will have to be saved someplace. Also, if this is the first time "Alien ESP" has been played on the machine, there obviously will be no previous Low Score. In that event, do NOT set it to 0 or 52; Instead, print it as "No previous Low Score".

Large Extra Credit: In the "Unlock It" view, don't allow the wheels to stop at combinations which have already been chosen. (Among other things, this would limit a player to only 52 choices and guarantee that on the 52nd turn that the wheels could only be turned to the actual solution!)


Zip your entire project, and post it on "NYU CLASSES".

This assignment is a work-in-progress, so check back for any additions, corrections, clarifications, helpful hints, etc., etc.