Goals

In this assignment, you will practice the following computer science concepts:

Computer Science Principles Curriculum


Common Core Standards

Vocabulary

Overview

In this assignment, you will create a trivia game. This assignment allows you to create your own questions and answers for the game. Download this zip file for a template to help you get started. Open the provided project template and navigate to the main.quorum file.

This assignment stores the questions and answers for your game in separate ".txt" files. This allows you to update or change your questions/answers without having to modify your program code. Create two ".txt" files, one for the questions and one for the answers. Come up with the questions and answers for your game and put them in the appropriate files, one question or answer per line.

Understanding FileReaders

Because your questions and answers are stored in separate ".txt" files, your program needs to read those files in order to access your questions. To do this, you need to use the FileReader object from the Libraries.System.FileReader library. The FileReader object reads a Quorum File object sequentially starting from the beginning of the file. To store the questions and answers during the program you use an object known in Quorum as an Array. An Array is simply a container that stores items in a contiguous block of memory. To use the Array object, you need to include the Libraries.Containers.Array library.

In order to use FileReader objects, you first need to declare both File and FileReader objects. Do this below the other declarations but above the line that starts with action CreateGame. Since you have 2 files, one for questions and one for answers, you need two File objects, one that represents the "questions.txt" file and another that represents the "answers.txt" file. You also need two FileReader objects, one to read the "questions.txt" file and another to read the "answers.txt" file.

Example: Declare File and FileReader objects to store the questions.

// this line declares a file object called questionsFile
File questionsFile

// this line declares fileReader object called questionsReader
FileReader questionReader

Activity: Declare File and FileReader objects to store answers.
Declare the needed objects.


You also need to set the paths of the File objects to your questions and answers files. Also do this in action CreateGame, below the existing code, but above the line that starts with end.

Example: Set the path for the question file. Use the SetPath action on the questionFile object.

questionsFile:SetPath("questions.txt")

Activity: Set the path for the answers file.


Your program needs a place to store the questions and answers read from the files. To do this, we can use arrays. Navigate back up to where you placed your declarations for the File and FileReader objects. You will place the declarations for the Arrays below these declarations.

Example: Declare an Array object to store the questions.

// this line declares an array called questions. The <text> part tells the Array
// that it will store text
Array<text> questions

Activity: Declare an Array object to store the answer text.
Declare the needed object.


Goal 1: Reading Files

To get your questions and answers from their files into your program, you need to tell your program to read the files. In order to read a file, it must first be opened. In Quorum, you must also tell files what they are being opened for (reading, writing, reading and writing). Since we are going to be reading our file once it has been opened, we use the OpenForRead action on our FileReader objects. This action takes a single parameter that represents the File object we want to open for read. Call these actions in the action CreateGame action, below the code you wrote to set the paths of the File objects.

Example: Open question file to be read.

    questionsReader:OpenForRead(questionsFile)

Activity: Open the answers file to be read.


Now, your file is open and ready to read. We will read our files in the action CreateGame action, below the code that opened the files for reading. There are many options for actions to read your file. The Read action reads and returns the entire contents of the file. The ReadLine action reads and returns a single line from the file. The ReadLines action reads and returns all the remaining lines of the file starting from the current position. You can know if you have read the entire file or not by calling the IsAtEndOfFile action. This action returns true if the end of the file has been reached and false otherwise.

Example: Use the questionsReader object to read the questions file one line at a time into the questions array until the end of the file has been reached.

// This line initially reads the file. This is needed before calling the 
// IsAtEndOfFile action
text question = questionsReader:ReadLine()

// this line adds the question we just read into the questions Array
questions:Add(question)

// this repeat statement reads the rest of the file until the end of the file is
// reached
repeat until questionsReader:IsAtEndOfFile()

   // this line reads in another line from the file
   question = questionsReader:ReadLine()

   // this line adds the question we just read into the questions Array
   questions:Add(question)
end

Example: Use the questionsReader object to read the questions file one line at a time into the questions array until the end of the file has been reached.
The answers file is read in the exact same way.

Once you have read the contents of your questions and answers files into their respective arrays, you are done with those files and FileReader objects. In Quorum, once you are done using a file that you have opened in your program, you need to tell Quorum that you are done with it and that it is okay to close the file. You can do this by calling the Close action on your FileReader objects. Write this code after the code you have just completed.

Example: Close the questions file.

    questionsReader:Close()

Activity: Close the answers file

Goal 2: Using Control Structures

Once the program has read all of the questions and answers, it should start the game. Your program should output all of the questions and ask the user for answers. The user input is captured with a TextBox. The user input should be checked against the answer, and if the answer is correct, a message should be displayed. If the answer is not correct, a different message should be displayed. For the convenience of whoever is playing your game, you may want to ignore any whitespace before and after their answer. Calling the Trim action on the text they inputted will accomplish this.

To accomplish this, we will write code in two places. The first place is in our game's action Update(number seconds) action, where we will display the question for the user to answer if the game is not over, and if the game is over, we will display a message telling them how many questions they got right out of the total number of questions. The second place we will write code is in the action labeled action PressedKey where we will write code to get the user's input guess and check it against the correct answer, displaying a message to the user telling them if they were right or wrong.


Use control structures to ask questions, or display a message when the game is over.

action Update(number seconds)
   // This statement checks if it is time to get a new question for the 
   // user, or if the game is over
   if nextQuestion and not gameOver
       //If the game is not over, the text of the label  used to display
       //the question is set to the next question
       label:SetText(questions:Get(index))

       // once a new question is displayed, a new question will not be
       // ready until the question is answered
       nextQuestion = false
   end

   if gameOver
       // if the game is over, display the game over message, telling
       // the user how many questions they got right
       label:SetText("Game Over! You got " + correctGuesses + "/" + questions:GetSize() + " questions correct!")
   end
end

Our game is declared as a KeyboardListener, which means that the Quorum Game Engine will tell our game any time a key is pressed on the keyboard. When keys are pressed on the keyboard, if they are letters, numbers, or symbols, they will appear in the text box. We can tell our program what to do when a key is pressed by writing code in the action labeled action PressedKey(KeyboardEvent event). If the user hits the enter key, we will then capture whatever is currently in the text box as their guess. That guess can then be checked against the correct answer to determine if the user is right or wrong. It is important to note that there is currently no way to clear text from a TextBox object, so users playing the game will have to backspace over any previously entered input.

Get the user's input from the TextBox when the enter key is pressed and check the guess against the correct answer.

//This line checks if the key being pressed is the enter key.
//If it is, then the input in the textbox is captured. If it is not, then the
//event is ignored
if event:keyCode = event:ENTER and index not= answers:GetSize()
   //This line gets whatever text is in the textbox and stores it as the variable guess
   text guess = box:GetInput()

   //This line removes whitespace from the user's guess.
   guess = guess:Trim()

   //This if statement checks the user's input against the answer to the
   //question. The EqualsIgnoringCase action will return true if the user's
   //guess is the same as the answer ignoring upper/lowercase.
   if guess:EqualsIgnoringCase(answers:Get(index))
       //If the guess was correct, increment the correctGuesses counter.
       correctGuesses = correctGuesses + 1

       //Show the correct message.
       correct:Show()
   else
       //If the guess was not correct, then show the incorrect message.
       incorrect:Show()
   end

   //This line allows the next question and answer to be accessed.
   index = index + 1

   //This line checks if there is another question avaliable to ask.
   //If there is not, then the game is over.
   if index < questions:GetSize()
       nextQuestion = true
   else
       gameOver = true
   end
end

You can now compile and run your game. If there are any errors, fix them and try again. Each question should appear on the screen. The player may enter text into the text box, pressing enter when he/she is done guessing. A message should display that tells the user if they were correct or incorrect.

Next Tutorial

In the next tutorial, we will discuss Challenge 3.4, which describes how Robots work in Quorum..