Adventure Game Studio

AGS Support => Advanced Technical Forum => Topic started by: madradubhcroga on Tue 15/05/2012 10:18:54

Title: Making a quiz game.
Post by: madradubhcroga on Tue 15/05/2012 10:18:54

Hi everybody.

I'm getting the hang of AGS, and I like it very much.
But I'm going to put my Adventure Game project on hold:
I want to make a 'quiz' game using AGS.

I think it'll be good, with trivia categories, reflex based games, puzzles, picture, memory, and audio challenges.

But there are distinct technical issues.


The big one is making databases to hold categories of questions, and difficulty levels of those questions.

I'd like to represent the category selection as a big spinning 'wheel of fortune' so not quite random but rather the wheel slows to a stop on a category (eg 'Animals').  Then Animals appears on the Question Map(GUI), with  10 20 30 40 and 50 point buttons (randomly from the relevent databases).  They spin the wheel again and so on until the Question Map(GUI) looks like this:



animals music mystery literature
10       10     10      10         10
20       20     20      20         20
30       30     30      30         30


Like in 'Jeopardy'
I want the player(s) to be able to select a question (EG Animals, for 30 points).  Then the computer should select an Animals question randomly from the correct database of 30 point animal questions.

I think I can just about make that happen.  But does anybody know the best way to proceed?  I don't see how to make it easy to go back and upload more questions when the structure is in place. Assuming I get that far. without haduken-ing my monitor.

I don't mean to make someone else do all the work for me;
but collaborators opinions and colossal insights are all alike welcome.

Title: Re: Making a quiz game.
Post by: Monsieur OUXX on Tue 15/05/2012 11:29:53
First, I don't think this should be in "Advanced technical forum" because even though it's technical, the difficulty comes from the algorithms rather than AGS itself. the AGS points you raise are rather simple.

You ask quite many questions:

1) How do I display my spinning wheel?

- There is a plugin that allows you to rotate sprites and draw them into a dynamicSprite. I can't remember the exact name but it has "3D" in it and it's still within the first 2 pages of the "Modules and plugins" forum.
- Alternative solution: Create a short animation or video of a spinning wheel.

2) How do I load questions from a database?

Well, it's not too hard to have one file per duet "[category]x[number of points]". For example, "Animals_30points.txt". Then you just read the question and its answer from the file.
The difficulty is: How big are the files? Can you afford to perform a random-access in the file every time ? (which means you have to re-read a lot of it everytime, which can stall your game if the file is huge). Should you load the file contents into memory? Should you devise a clever "partition" system to split the file into smaller files? Etc. that's all up to you.

3) How to I display more and more buttons in columns and rows?

Well, just create a GUI with 40 buttons and then make them invisible. Show them only when needed.
If you hit the limit of buttons per GUI (I believ a GUI cannot have more than 20 controls) then use several GUIs.

Title: Re: Making a quiz game.
Post by: Khris on Tue 15/05/2012 14:08:45
I'd implement reading CSV files. That way you (or anybody else) can easily just type random questions into any spreadsheet app and save it as .csv.
As an example:



animals 10    This ape is known for flinging poo and eating babies.    Chimpanzee   
literature    20  The arch enemy of Sherlock Holmes is?  Dr. Moriarty

Exported as CSV, it'll look like this:
animals;10;This ape is known for flinging poo and eating babies.;Chimpanzee
literature;20;The arch enemy of Sherlock Holmes is?;Dr. Moriarty

At the start of the game, every CSV file in a set data dir is imported into a database (a struct array).

One could in addition specify which pack a csv belongs to, then add an option to only use certain question packs.

To parse a CSV file, read it line by line and split the lines at a , or ;
That's quite easily done using the File.Open() and File.ReadRawChar() commands.
Title: Re: Making a quiz game.
Post by: Monsieur OUXX on Tue 15/05/2012 14:45:01
Quote from: Khris on Tue 15/05/2012 14:08:45
I'd implement reading CSV files.

+1. Simplest structure ever: Just read each line in the file and then parse the line, looking for commas
Title: Re: Making a quiz game.
Post by: madradubhcroga on Tue 15/05/2012 21:38:31
Thank you for your consideration.

I understand that I may not have selected the appropriate forum, sorry for any inconvenience.

Khris- that CSV system sounds promising, I may try that eventually.  Maybe another way would be to implement your solution to my Re: Where is the 'Room message editor?' question.


I'm going to sketch out a plan and then I'll be able to ask more specific questions.

Best regards

MDC

MDC
Title: Re: Making a quiz game.
Post by: Khris on Tue 22/05/2012 18:50:15
Ok, here's a module with basic support for importing a CSV database of questions with categories, points and four answers.

QuizModule.scm (https://www.dropbox.com/s/z2ylkxywfefqd8l/QuizModule.scm) (Right-click the Scripts node and choose "Import script...")

Here's an example CSV file: misc.csv (https://www.dropbox.com/s/vbbuktyxh6qsi2e/misc.csv) (Inside the Compiled folder, create a folder called "questions" and put it in there.)

And some example code you can put in a room script:
Code (ags) Select
void on_key_press(eKeyCode k) {
 
  if (k == eKeySpace) {
    QuizModule.ImportQuestions("misc");
    int noq = QuizModule.NumberOfQuestions();
   
    Display(String.Format("Loaded %d questions.", noq));
    int i;
    String questions = "";
    while (i < noq) {
      questions = questions.Append(q[i].question);
      if (i < noq-1) questions = questions.Append("[---[");
      i++;
    }
    Display(questions);
  }
}


If you press space while in the room, this will import the file questions/misc.csv, show the number of successfully imported questions and then display the questions.
q is a global struct array holding all the questions data. I've decided that specifying the right answer isn't really necessary if you put it as first of the four possible answers in the database, then put them on four buttons in random order.

Btw, the module assumes that the CSV file uses ; as delimiter and doesn't have "s around text.
Title: Re: Making a quiz game.
Post by: madradubhcroga on Tue 22/05/2012 23:31:30
How do I put the answers on the buttons?
Title: Re: Making a quiz game.
Post by: Khris on Wed 23/05/2012 00:11:42
Create a GUI called gQuestion, add a label first, then four buttons to it, so the latter have the IDs 1-4.
Now append this to Quiz.asc:

Code (ags) Select
int correct_id;
export correct_id;

static void QuizModule::SetupQuestionGUI(int question) {
  Label*l = gQuestion.Controls[0].AsLabel;
  l.Text = q[question].question;
 
  // positions 0-3
  int p[4];
  int i;
  while (i < 4) {
    p[i] = i;
    i++;
  }
  // shuffle
  i = 0;
  while (i < 20) {
    int a = Random(3);
    int b = Random(3);
    int sum = p[a] + p[b];
    p[a] = sum - p[a];
    p[b] = sum - p[b];
    i++;
  }
  // put answers on buttons
  i = 0;
  while (i < 4) {
    int id = i + 1;
    Button*b = gQuestion.Controls[id].AsButton;
    b.Text = q[question].ans[p[i]];
    // if we put the correct answer (ans[0]) on the button, store its id
    if (p[i] == 0) correct_id = id;
    i++;
  }
}


and add this to Quiz.ash:
Code (ags) Select
import int correct_id;

(I have also updated the module download in my Dropbox.)

Now open GlobalScript.asc and add this at the end:
Code (ags) Select
function QuizButton_OnClick(GUIControl*control, MouseButton button)
{
  if (button != eMouseLeft) return;
  if (control.ID == correct_id) Display("Correct!");
  else Display("False!");
}


Final step: open the event pane of each of the four buttons and put "QuizButton_OnClick" without quotes in the empty field next to "OnClick".

You can test this by calling  QuizModule.SetupQuestionGUI(0); after you've imported some questions.
Title: Re: Making a quiz game.
Post by: madradubhcroga on Wed 23/05/2012 22:49:23

Hi.

I havn't gotten it working yet.

I get an error  on line 114
Code (AGS) Select


  l.Text = q[question].question;



the error is highlighted in yellow and the message reads

Null string supplied to CheckForTranslations



Title: Re: Making a quiz game.
Post by: Khris on Wed 23/05/2012 22:58:32
When you call QuizModule.SetupQuestionGUI(x);, make sure that you have already imported a CSV file and that x is smaller than the total number of questions.
Otherwise, q[question].question won't just be empty, it'll be null, and AGS doesn't seem to like assigning null to a Label's .Text property.
Title: Re: Making a quiz game.
Post by: madradubhcroga on Wed 23/05/2012 23:03:50
Legend. 
I'll try that, thank you.
Title: Re: Making a quiz game.
Post by: FrankT on Thu 24/05/2012 12:20:29
Couldn't help but notice this. I'm looking at a concept for a quiz too! If I ever get it done, I'll be sure to thank you for it!
Title: Re: Making a quiz game.
Post by: madradubhcroga on Thu 24/05/2012 19:08:03
I haven't successfully implemented the code yet, the same error is being reported.


I used Google spreadsheets to make test.csv and replaced the , with ;
Test.csv has 10 questions and is saved in Q3/Compiled/Questions.

(Q3 is a new game project, with nothing in it except the quiz script.)

the room script file looks like this:

Code (AGS) Select


// room script file
    void on_key_press(eKeyCode k) {
     
      if (k == eKeySpace) {
        QuizModule.ImportQuestions("test");
        int noq = QuizModule.NumberOfQuestions();
       
        Display(String.Format("Loaded %d questions.", noq));
        int i;
        String questions = "";
        while (i < noq) {
          questions = questions.Append(q[i].question);
          if (i < noq-1) questions = questions.Append("[---[");
          i++;
        }
        Display(questions);
      }
   
   
   }
   
   

   
function room_FirstLoad()
{
QuizModule.SetupQuestionGUI(5);
}


Title: Re: Making a quiz game.
Post by: Khris on Thu 24/05/2012 19:40:42
Yeah, just like I said in my previous port, you can't call QuizModule.SetupQuestionGUI(5); until after you've imported the file.
The example code I posted containing the on_key_press funtion won't do anything until you press the space key. Thus, room_FirstLoad is executed first and throws the error.

Try this:
Code (ags) Select
function room_FirstLoad()
{
  QuizModule.ImportQuestions("test");
  QuizModule.SetupQuestionGUI(5);
}
Title: Re: Making a quiz game.
Post by: madradubhcroga on Thu 24/05/2012 21:30:09
No joy. 
The same error message:

Null string supplied to CheckForTranslations

appears in relation to 
Code (AGS) Select


l.Text = q[question].question;


In the morning, I'll start again from the beginning.  Maybe I've strayed from the recipe somewhere.
Title: Re: Making a quiz game.
Post by: Khris on Thu 24/05/2012 22:15:28
Alright, remove the QuizModule.SetupQuestionGUI(5); line.
Put the on_key_press code in a room and in-game, go to that room and press space.
The game should say how many questions were imported and then list them.

If that does work, you can try putting the line back in.

Edit: Judging by this post (http://www.adventuregamestudio.co.uk/yabb/index.php?topic=33570.msg435753#msg435753), the error occurs if you try to set a label's text to a null string. In other words, you're trying to put a question on a label but there aren't any questions loaded (yet). Either your code is still wrong, or the CSV doesn't have the right format.
Title: Re: Making a quiz game.
Post by: madradubhcroga on Thu 24/05/2012 22:42:12

Re: "Either your code is still wrong, or the CSV doesn't have the right format."
Both, I think.



In the configuration, without  the QuizModule.SetupQuestionGUI(5); line,
when I press space,

the message

'0 questions loaded'

appears.

When I change 'test' to 'misc' in both the on_key_press code and in the
function room_FirstLoad,
the message

'loaded 4 questions'
appears, followed by the message:


the arch enemy of Sherlock holmes is?
----
Which of these actually exist?
----
the arch enemy of Sherlock holmes is?
----
Which of these actually exist?
----


So:
a) Your sample questions file (misc) is accessable, but mine (test) is not.  (Both are .csv files saved in the Questions folder in the Compiled folder. I'm going to compare them more carefully now)
b) My GUI 'gQuestion'  is not being called.   
Title: Re: Making a quiz game.
Post by: Khris on Fri 25/05/2012 01:29:41
The questions appear twice because you have imported my csv twice.
To be clear, the on_key_press code was just for testing/demo purposes; you don't need it for the quiz stuff to work.

All you need is the import command, followed by the SetupQuestionsGUI command(s).

As for parsing the CSV file, I put zero error-checking in there. Could you upload your CSV somewhere so I can take a look at it?
Title: Re: Making a quiz game.
Post by: madradubhcroga on Fri 25/05/2012 11:44:02


The csv is here

https://www.dropbox.com/s/6bf25xlw3diky7s/test.csv
Title: Re: Making a quiz game.
Post by: Khris on Fri 25/05/2012 12:15:08
I've taken a look at it and it seems fine, however it's UTF-8/unicode, whereas mine is an ASCII file. I suspect that's the reason why the import routine fails.
I tried converting it to ascii, which converted all the special characters to question marks, and it still didn't work. I'll look into it later and report back.