Saturday, 13 April 2013

#P3 Capital Quiz Application


Project Background

Develop Capital Quiz application which can run on iOS platform. The application will display name of the Country and related four capital choices. User can select multiple times to select the correct capital city. For every correct answer the score will be increased by one. User can see next question by pressing next button. User can reset/restart the quiz at any point of time by pressing reset button. For every reset /restart the score will be reset to zero.

Application Screen


Project Stucture

Project Creation

  • Create new Xcode project and select “Single View project” template under iOS->Application
  • Select devices as iPhone
  • Create new group to keep resources such as image files
  • Rename the group to Resources
  • Copy image files to the Resources  folder
  • Sample contents of Resource folder

Modify interface: ViewController.h
First update ViewController.h file so that all IBOutlet and IBAction will available for connections to UI Objects, such as UIButton and UILabel.


#import <UIKit/UIKit.h>

@interface ViewController : UIViewController {
    IBOutlet UILabel *coutryName;
    IBOutlet UIButton *firstChoice;
    IBOutlet UIButton *secondChoice;
    IBOutlet UIButton *thirdChoice;
    IBOutlet UIButton *fourthChoice;
   
    NSMutableArray *questions;
    NSArray *answers;
    NSString *results;
    NSDictionary *displayCapitalChoices;
}

@property (nonatomic, retain) IBOutlet UILabel *coutryName;
@property (nonatomic, retain) IBOutlet UIButton *firstChoice;
@property (nonatomic, retain) IBOutlet UIButton *secondChoice;
@property (nonatomic, retain) IBOutlet UIButton *thirdChoice;
@property (nonatomic, retain) IBOutlet UIButton *fourthChoice;

@property (nonatomic, retain) NSString *results;
- (IBAction)showInfo:(id)sender;
- (IBAction)checkAnswer:(id)sender;
- (IBAction)showNextQuest:(id)sender;
- (NSArray *) getRandomIndex;
- (IBAction)restart;
@end

Build User Interface (UI) and bind it to the application code
  • Double click ViewController.xib UI
  • Add Label(UILabel) and Button (UIButton)
  • Link Button to the method by pressing [CTRL] key+ Drag the mouse pointer towards [File’s Owner] 
  • Copy above button three times to create total four Buttons as shown below (these buttons will be used to display four Capital choices) , the button copy will also copy connections between UIButton and checkAnswer method,  please confirm the connection using “Connection Inspector” as shown below,
Confirm: if selected Button is connected to checkAnswer method for the event “Touch Up Inside”,

All four buttons are connected to checkAnswer method
  • Add Button to show next question and set its image as next.png
  • Connect method to the next question button by pressing [CTRL] Key and Drag the mouse towards [File's Owner] and finally release [CTRL] key to get list of available methods.

Run the application to confirm UI display in the simulator, at this stage if you click any of the button the application will crash because none of the methods are implemented.
  • Add Connection between Label and ViewController
  • Similarly, Add connection between each Button and ViewController by pressing [CTRL] key and drag mouse from [File Owner] towards the button. After this connection it is possible to update label of the button programmatically.
  •  Add a new Button to restart the application
  • Add connection between restart button and restart method defined in ViewCotroller

Do method implementation : ViewController.m

#import "ViewController.h"

@implementation ViewController

static const int MAX_QUESTIONS_SIZE = 8;
static int NEXT_QUESTION = 0;
static int CORRECT_COUNT = 0;

@synthesize coutryName, firstChoice, secondChoice, thirdChoice, fourthChoice, results;

- (void)viewDidLoad
{
    [super viewDidLoad];

    //Init question array
      questions = [[NSMutableArray alloc] initWithObjects:@"Japan",@"India",@"Nepal",@"Bangladesh",@"America",@"Malasiya",@"South Korea",@"China",nil];
     
    //Init answer array, the order of answer is maintained as per question
      answers = [[NSMutableArray alloc] initWithObjects: @"Tokyo",@"New Delhi",@"Kathmandu",@"Dhaka",@"Washington D.C.",@"Kaulalampur",@"Seoul",@"Beijing",nil];
   
    //Display First Question
    [self showNextQuest: nil];
   
}

- (NSArray *)createChoices:(int) nextQuestionIndex {
      //you can not use NSArray here which is immutable and hence does not have addObjects method
      NSMutableArray *choices = [[NSMutableArray alloc] init];
     
      [choices addObject:[answers objectAtIndex: nextQuestionIndex]]; //correct answer is set
     
      int nextIndex = nextQuestionIndex + 1;
     
      if (nextIndex >= MAX_QUESTIONS_SIZE) {
            nextIndex = 0;
      }
     
      [choices addObject:[answers objectAtIndex: nextIndex]]; //create random number between 0 to 6
      nextIndex++;
     
      if (nextIndex >= MAX_QUESTIONS_SIZE) {
            nextIndex = 0;
      }
     
      [choices addObject:[answers objectAtIndex: nextIndex]];
      nextIndex++;
     
      if (nextIndex >= MAX_QUESTIONS_SIZE) {
            nextIndex = 0;
      }
     
      [choices addObject:[answers objectAtIndex: nextIndex]];
     
      NSLog(@"Choices: %@ ", choices);
     
      return choices;
}

- (IBAction)showNextQuest:(id)sender {
      [firstChoice setBackgroundImage:[UIImage imageNamed:@"white.png"] forState:UIControlStateNormal];
      [secondChoice setBackgroundImage:[UIImage imageNamed:@"white.png"] forState:UIControlStateNormal];
      [thirdChoice setBackgroundImage:[UIImage imageNamed:@"white.png"] forState:UIControlStateNormal];
      [fourthChoice setBackgroundImage:[UIImage imageNamed:@"white.png"] forState:UIControlStateNormal];
   
      if (NEXT_QUESTION >= MAX_QUESTIONS_SIZE) {
            UIAlertView *alert = [[UIAlertView alloc]
                                            initWithTitle: @"Results"
                                            message: [NSMutableString stringWithFormat: @"%@ %i %@ %i \n %@", @"Correct answers: ", CORRECT_COUNT, @" out of ", NEXT_QUESTION, @"Cool !!!"]
                                            delegate: nil
                                            cancelButtonTitle:@"OK"
                                            otherButtonTitles:nil];
            [alert show];
            [alert release];
           
      } else {
            NSLog(@"NEXT_QUESTION:%i", NEXT_QUESTION);
        NSLog(@"COUNTRY NAME:%@", [questions objectAtIndex:NEXT_QUESTION]);
            coutryName.text = [questions objectAtIndex:NEXT_QUESTION];
            NSArray *choices = [[self createChoices:NEXT_QUESTION] autorelease];
           
            //get random number for setting Button Title
            NSArray *randomIndex = [self getRandomIndex];
            [firstChoice setTitle: [choices objectAtIndex:[[randomIndex objectAtIndex:0] intValue]] forState: UIControlStateNormal];
            [secondChoice setTitle:[choices objectAtIndex:[[randomIndex objectAtIndex:1] intValue]]   forState: UIControlStateNormal];
            [thirdChoice setTitle:[choices objectAtIndex:[[randomIndex objectAtIndex:2] intValue]]   forState: UIControlStateNormal];
            [fourthChoice setTitle:[choices objectAtIndex:[[randomIndex objectAtIndex:3] intValue]]   forState: UIControlStateNormal];
           
            NEXT_QUESTION++;
           
      }
}

-(NSArray *) getRandomIndex {
      NSMutableArray *tempIndexArray = [[[NSMutableArray alloc] init] autorelease];
     
      int randomNo =  arc4random() % 4 ;
     
      for (int i = 0; i < 4; i++) {
           
            [tempIndexArray addObject:[NSString stringWithFormat:@"%d", randomNo]];
           
            if (randomNo == 3) { //max no.
                  randomNo = 0; //reset
            } else {
                  randomNo++;
            }
           
      }
     
      return tempIndexArray;
     
}

- (IBAction)checkAnswer:(id)sender {
     
      NSString *correctAnswer = [answers objectAtIndex:NEXT_QUESTION - 1];
     
      BOOL answerFlag = NO;
     
      if (sender == firstChoice) {
           
            NSString *currentAnswerSelection = firstChoice.currentTitle;
           
            if ([correctAnswer isEqualToString:currentAnswerSelection]) {
                  answerFlag = YES;
            }
           
            if (answerFlag == YES) {
                  //[firstChoice setTitleColor:[UIColor greenColor] forState:UIControlStateNormal];
                  [firstChoice setBackgroundImage:[UIImage imageNamed:@"maru.png"] forState:UIControlStateNormal];
                  CORRECT_COUNT++;
            } else {
                  [firstChoice setBackgroundImage:[UIImage imageNamed:@"batsu.png"] forState:UIControlStateNormal];
                }
      }
     
      if (sender == secondChoice) {
           
            NSString *currentAnswerSelection = secondChoice.currentTitle;
           
            if ([correctAnswer isEqualToString:currentAnswerSelection]) {
                  answerFlag = YES;
            }
           
            if (answerFlag == YES) {
                  [secondChoice setBackgroundImage:[UIImage imageNamed:@"maru.png"] forState:UIControlStateNormal];
                  CORRECT_COUNT++;
            } else {
                  [secondChoice setBackgroundImage:[UIImage imageNamed:@"batsu.png"] forState:UIControlStateNormal];
            }
      }
     
      if (sender == thirdChoice) {
           
            NSString *currentAnswerSelection = thirdChoice.currentTitle;
           
            if ([correctAnswer isEqualToString:currentAnswerSelection]) {
                  answerFlag = YES;
            }
           
            if (answerFlag == YES) {
                 
                  [thirdChoice setBackgroundImage:[UIImage imageNamed:@"maru.png"] forState:UIControlStateNormal];
                  CORRECT_COUNT++;
            } else {
                  [thirdChoice setBackgroundImage:[UIImage imageNamed:@"batsu.png"] forState:UIControlStateNormal];
            }
      }
     
     
      if (sender == fourthChoice) {
           
            NSString *currentAnswerSelection = fourthChoice.currentTitle;
           
            if ([correctAnswer isEqualToString:currentAnswerSelection]) {
                  answerFlag = YES;
            }
           
            if (answerFlag == YES) {
                  [fourthChoice setBackgroundImage:[UIImage imageNamed:@"maru.png"] forState:UIControlStateNormal];
                  CORRECT_COUNT++;
            } else {
                  [fourthChoice setBackgroundImage:[UIImage imageNamed:@"batsu.png"] forState:UIControlStateNormal];
            }
      }
     
}

- (IBAction)restart {
    NEXT_QUESTION = 0;
    CORRECT_COUNT = 0;
   [self showNextQuest:nil];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)dealloc {
      [coutryName release];
      [firstChoice release];
      [secondChoice release];
      [thirdChoice release];
      [fourthChoice release];
      [results release];
    [super dealloc];
}

@end

No comments:

Post a Comment