[Tutorial] Quiz Game

Per a couple requests, I've gone ahead and put together a very simple quiz game. Here's what the game does:

- Loads a welcome screen, with a button to start the game.
- Loads questions with 4 potential answers.
- Provides a simple scoring mechanism; 50 points for right answers, 50 points for wrong ones.
- Allows players a few seconds to answer questions, and gives a brief break between questions.

So, that's the basics of it. The source files are attached below. Please note, this was coded in an afternoon, so there are some error messages that pop up, and some really bad code in the actual quiz itself! I'm going to update this thread once I rewrite the code...

Now I'm going to walk through some parts of the code. This is not the complete program, so to get the complete program please download the source code and run it. I'm just going to show off some of the highlights...

One thing worth noting is that I created an IBOutlet for the buttons; this provides the ability to change the text on them so the answers will be "clickable". I figure that's a pretty straightforward way to program it. As you can see in the header I've initialized some variables like booleans and integers, and most importantly an array that we'll use to actually load the quiz itself.

In IB, there are 3 main labels: The question area, the "score" and the timer counter box (which, I labeled "lives" inadvertently thinking I was going to have a lives counter... just run with it).

So, now in the .m file, here are some of the notable functions... (Please note, these are not in order as they appear in the code, so if you're looking at the source, you may have to scroll a little bit to find these things)

This is just the initialization of the app, but it has some notable activities which might be worth noticing. First off, we've established some values for some of the variables that we'll be using in the game, including questionLive (a boolean), the questionNumber, myScore, etc. myLives will likely be killed in the next iteration of the game, since I'm not using that feature. You'll see how a lot of these get used later on. One of the handy pieces of code that I've used is the [... setTitle:] and [... setHidden:] features for the buttons. The buttons are UIButtons with IBOutlets attached to them in the Interface Builder, so we can manipulate them to be visible or hidden, or change the content of their text label. There are several states that buttons can be in when you set the title, but for convenience sake I only really care about UIControlStateNormal. Press the escape key while you're typing the statement, and a popup will appear with all the options...

The loadQuiz function is pretty straightforward, but it's important to note that this is a TERRIBLE way to program this. It SHOULD be nested arrays based on a dictionary, but for the sake of just getting this done I put it all in a flat NSArray. This is the thing that I'll be updating when I update this program, probably to access an independent file from resources like a plist or a txt file. Stay tuned for that update.

The "game" itself is in the function askQuestion:

-(void)askQuestion
{
// Unhide all the answer buttons.
[answerOne setHidden:NO];
[answerTwo setHidden:NO];
[answerThree setHidden:NO];
[answerFour setHidden:NO];
// Set the game to a "live" question (for timer purposes)
questionLive = YES;
// Set the time for the timer
time = 8.0;
// Go to the next question
questionNumber = questionNumber + 1;

Here you can see some initialization features, such as un-hiding the buttons, setting the questionLive variable to "YES" so that the timer knows it's in a question (I'll explain that in a moment), setting the time for the timer (how long the player gets to answer the question, in this case 8 seconds), and updating the questionNumber to move to the next row.

So all that stuff should be relatively self-explanatory if you just take a little while to look at it. Again, this is shameful programming (by skimming through a flat array to pull the question, answers, and right answer variables) but in short order it was what I came up with. Also, note the activation of the timer object, which uses the "countDown" function to warn the user of how much longer they have to answer the question.

Here's the code for -(IBAction)buttonOne function just so you see what's going on in there:

Note that since button 1 is being used both as an answer button and as the "Let's play" game starter, we have to have a conditional statement in there to change it from the start button to a normal answer statement, which we accomplish by finding out if we're on question #0. If it's a normal question (in the 'else' portion of the conditional, covering all other situations), we set up a variable called theAnswerValue, which is the button number that they pressed, and then send that value to the function checkAnswer. This is creating a warning message in the process, so I need to check my syntax to code it right (it will run, but with warning errors - nothing severe though).

Notice rightAnswer is set in the askQuestion function, and is being compared to the theAnswerValue that was passed from the button action function (depending on what button was pressed, 1-4). If it is a match, they got it right, and they get a plithy response and 50 points. If it's not a match, they got it wrong, get shamed, and lose 50 points.

So, that's essentially the rest of the heavy lifting the the app. The countDown function is worth a look, since that's where the timer runs through, but I think if you take a look at the source you should get what I'm doing in there.

I welcome your questions about what I did, and I eagerly encourage any and all suggestions for improvements, enhancements, and coding short-cuts that I could have taken. Like I said, the main thing that I'm going to work on next is to change the method that the array is assembled (so we're using a series of multidimensional arrays to control questions, answers, etc); provide a mechanism to have variable question difficulty (and award variable points), and set it up so questions & answers will appear randomly. Also, I'd like to add a function to show the user the right answer when they get it wrong (or have that a setting that they can turn on or off).

Yeah, that's the next piece I want to do. Like I said, the method I'm using isn't good at all! Haha. So yes, I'm going to update this file and provide some detail on how to use the plist and file-derived arrays.

All this did was provide a quick way to create the array using a txt file called quizgame.txt moved in the 'Resources' group under "Groups & Files". Everything else in the code stays the same for now...

To explain what's going on in this function now:
1 - Create an instance of an NSBundle called bundle that we can use to access the file system. This way we don't need to actually write the exact path all the way to the root, this'll do it for us.
2 - Create a string called textFilePath which uses the bundle to create a string with the location of the file we're trying to access. Note that you don't need to include the extension when describing the file, but you do need to set it in the 'ofType'.
3 - Create a string called fileContents which contains the entire contents of the file. Worth noting, each line of the file will designate a new line in the array.
4 - Populate the array quizArray with the contents of the fileContents, using the method componentsSeparatedByString of @\n which means every line break means it's a new element in the array.
5 - Set theQuiz (our standing array of questions & answers) to quizArray and then...
... release quizArray

So that's about it. The only real hiccup that I had in testing this is that the text file cannot have an ending blank line in it, as if you were going to write out more content. It'll record that as a new line in the array, and the game-ending code will fry (because it'll think there are more questions & answers). The formatting is still the same: 1st line is the question, lines 2-5 are answers, and line 6 is the right answer. So the text file might look like this...
quizgame.txt:

Who played the president on the TV show 'The West Wing'?
Alan Alda
Rob Lowe
Martin Sheen
Jack Bauer
3
What year did The Daily Show premier?
1994
1996
1998
2001
2
Who replaced Conan O'Brien on the Late Night show?
Jimmy Kimmel
Jimmy Tudeski
Jimmy Dean
Jimmy Fallon
4

So that's a quick upgrade to the code. Next, I'm trying to decide if I want to try to use a SQLite db or a plist file to actually break out these arrays in to something a little more meaningful (and add some new functionality in the process).

Dru, you should download the zip from the second post on this thread, change the function (void)loadQuiz to what I showed in the follow-up. Then create your own txt file of questions and answers, copy it to your project, and run the game. Should be literally that simple, since the main processes of the game haven't changed.

Your game has 4 answers as buttons, but what i tried to do is basically to have a simple interface where the answers are all embedded in the question, and there are 4 fixed answer buttons A,B,C,and D.

Each time an answer is clicked (or Next button is clicked) the answer variable (ABCD) will be stored, and the next question will be displayed, and so on.
At the end, a table should show the list of questions (1.2.3...), selected answer (user selected) and correct answer (red if wrong), with a total percentage grade.

FIRST THING TO DO:
I have created three string variables and each contains a question.
now what i want to do is to have a loop function attached to button A,B,C, and D to store selected answer and move on to next question.

There's a few things that come to mind. First off, using the UIToolbar is different from using buttons... I haven't really played around with them much, but I think with a little searching you can find out how to trigger the action based upon what button the user presses (it's different from how buttons are treated, but not by much).

It covers NSMutableArray which is a modifiable array you can use to dynamically store your answers. I'm assuming that what you're trying to do is get a user to the end of the quiz before telling them how many they got right or wrong. That just means you'll need to do something simple at the end like:

Okay I've edited this to a little more of my likings. I'm no developer at all, I've never coded in my life. But when ever at the end of the game taping the reset only freezes there. Any way to create a control to reset to the splash?

I took a look at this tutorial thread and it has been very helpful indeed! Kudos to you kind sir!

I am trying to do a similar quiz app and wanted to put images to questions. For instance if its a sports question I would put a sports picture, music question pic of guitar, etc.

Could you perhaps give any guidance on this? I am thinking it would of course be another array with images loaded into it, however I am not sure how to tie the images to transition when the question was answered.

Hello, This tutoril is very good! thx!
I hace a question, how can I make Random Question Apear? I know how to create a random generator, but not to make it work with questions.
Thx

Once you have 'random() % numberOfQuestions', just multiply by 6 (in this case of a flat array) and index into the array. You should also randomize the position of each answer to mix things up.

I started out with random in 'That Ain't It! Trivia Game', but eventually moved to keeping track of which questions were displayed because using random was causing repeat questions more often than we liked.

Once you have 'random() % numberOfQuestions', just multiply by 6 (in this case of a flat array) and index into the array. You should also randomize the position of each answer to mix things up.

I started out with random in 'That Ain't It! Trivia Game', but eventually moved to keeping track of which questions were displayed because using random was causing repeat questions more often than we liked.

Thx Dude! Finnaly ive got an answer.
Can you upload a Sample Code? using the Quiz Game tutorial?

Thx Dude! Finnaly ive got an answer.
Can you upload a Sample Code? using the Quiz Game tutorial?

How do I create random number of questions?

Thx!

Sorry, I don't have any sample code to upload. What do you mean by 'create a random number of questions?' I would probably be more helpful in answering questions about the That Ain't It! trivia app I wrote. You can check out the YouTube video (search IMAKcreations) and I'll be happy to answer any questions about it. It took quite a bit longer to write than 1 day, but I learned a lot.

Okay reading through my old posts I feel bad cause I was kinda rude/true noob.

But thats not what I wanted to ask. I created a new button called endButton and set it to be the button to start the game and end it. I did this because I set my buttons to have a different layout and the start and end buttons look bad. So my problem is when ever i swich the button from this: