0

So i got 10 questions, so when the game starts, example the starting question is "4 out of 10" then if the next question is random to "10 out of 10" the game ends. what i want is to random the 10 questions:

private int idMode;
public Text question;
public Text answerA;
public Text answerB;
public Text answerC;
public Text answerD;
public Text infoAnswer;
public Text stat;
public string[] questions;          
public string[] alternativeA;   
public string[] alternativeB;
public string[] alternativeC;
public string[] alternativeD;
public string[] correct;
private int idQuestion; 
private float points;
private float fact; 
private float average;
private int results;

void Start () {
    idMode = PlayerPrefs.GetInt ("idMode");
    idQuestion = 0;
    fact = questions.Length;
    question.text = questions [idQuestion];
    answerA.text = alternativeA [idQuestion];
    answerB.text = alternativeB [idQuestion];
    answerC.text = alternativeC [idQuestion];
    answerD.text = alternativeD [idQuestion];
    infoAnswer.text = (idQuestion + 1).ToString() + " of " + fact.ToString () + "";
}
public void answer(string alternative)
{
    if (alternative == "A") {

        if (alternativeA [idQuestion] == correct [idQuestion]) {

            points += 1;

        } else {

        }
    }
    if (alternative == "B") {

        if (alternativeB [idQuestion] == correct [idQuestion]) {

            points += 1;
        } else {
    }

}
    if (alternative == "C") {
        if (alternativeC [idQuestion] == correct [idQuestion]) {
            points += 1;
        } else {
    }
}

    if (alternative == "D") {
        if (alternativeD [idQuestion] == correct [idQuestion]) {
            points += 1;
        } else {
    }
}
    nextQuestion ();
} 
void nextQuestion()
{
    idQuestion += Random.Range(0,10);
    if(idQuestion <= (fact-1))
    {
        question.text = questions [idQuestion];
        answerA.text = alternativeA [idQuestion];
        answerB.text = alternativeB [idQuestion];
        answerC.text = alternativeC [idQuestion];
        answerD.text = alternativeD [idQuestion];
        stat.text = " Correct: " + points.ToString () + "";
        infoAnswer.text =  (idQuestion + 1).ToString() + " of " + fact.ToString () + "";
    }
    else
    {
        average = 10 * (points / fact);
        results = Mathf.RoundToInt (average);
        if (results > PlayerPrefs.GetInt ("results" + idMode.ToString ())) {
            PlayerPrefs.SetInt ("results" + idMode.ToString (), results);
            PlayerPrefs.SetInt ("points" + idMode.ToString (), (int)points);
        }
        PlayerPrefs.SetInt ("resultsTemp" + idMode.ToString (), results);
        PlayerPrefs.SetInt ("pointsTemp" + idMode.ToString (), (int)points);
        Application.LoadLevel("results");
    }
}
}
hemalp108
  • 1,209
  • 1
  • 15
  • 23
Magilou
  • 47
  • 10

1 Answers1

2

Change your data structure, make a class that represents the question and the possible answers so you have one array instead of 6.

Once you do that before you start asking questions shuffle the list then just go through the list in the new randomized order.

[Serializeable] 
public class Question
{
    public string Text;
    public string A;
    public string B;
    public string C;
    public string D;
    public string CorrectChoice; //Holds "A", "B", "C", or "D"
}

public static class RandomExtensions
{
    public static void Shuffle<T> (this T[] array)
    {
        int n = array.Length;
        while (n > 1) 
        {
            int k = Random.Range(0, n--);
            T temp = array[n];
            array[n] = array[k];
            array[k] = temp;
        }
    }
}

Then change your code to

private int idMode;
public Text question;
public Text answerA;
public Text answerB;
public Text answerC;
public Text answerD;
public Text infoAnswer;
public Text stat;
public Question[] questions;
private int idQuestion; 
private float points;
private float fact; 
private float average;
private int results;

void Start () {
    idMode = PlayerPrefs.GetInt ("idMode");
    idQuestion = 0;
    fact = questions.Length;
    questions.Shuffle();
    question.text = questions[idQuestion].Text;
    answerA.text = questions[idQuestion].A;
    answerB.text = questions[idQuestion].B;
    answerC.text = questions[idQuestion].C;
    answerD.text = questions[idQuestion].D;
    infoAnswer.text = (idQuestion + 1).ToString() + " of " + fact.ToString () + "";
}
public void answer(string alternative)
{
    if (alternative == questions[idQuestion].CorrectChoice) 
    {
        points += 1;
    }

    nextQuestion ();
} 
void nextQuestion()
{
    idQuestion += Random.Range(0,10);
    if(idQuestion <= (fact-1))
    {
        question.text = questions[idQuestion].Text;
        answerA.text = questions[idQuestion].A;
        answerB.text = questions[idQuestion].B;
        answerC.text = questions[idQuestion].C;
        answerD.text = questions[idQuestion].D;
        stat.text = " Correct: " + points.ToString () + "";
        infoAnswer.text =  (idQuestion + 1).ToString() + " of " + fact.ToString () + "";
    }
    else
    {
        average = 10 * (points / fact);
        results = Mathf.RoundToInt (average);
        if (results > PlayerPrefs.GetInt ("results" + idMode.ToString ())) {
            PlayerPrefs.SetInt ("results" + idMode.ToString (), results);
            PlayerPrefs.SetInt ("points" + idMode.ToString (), (int)points);
        }
        PlayerPrefs.SetInt ("resultsTemp" + idMode.ToString (), results);
        PlayerPrefs.SetInt ("pointsTemp" + idMode.ToString (), (int)points);
        Application.LoadLevel("results");
    }
}

If you really don't want to change your data structure this is the other option I mentioned in the comments about creating a mapping array.

private int idMode;
public Text question;
public Text answerA;
public Text answerB;
public Text answerC;
public Text answerD;
public Text infoAnswer;
public Text stat;
public string[] questions;          
public string[] alternativeA;   
public string[] alternativeB;
public string[] alternativeC;
public string[] alternativeD;
public string[] correct;
private int idQuestion; 
private float points;
private float fact; 
private float average;
private int results;
private int[] questionMapper;

void Start () {
    idMode = PlayerPrefs.GetInt ("idMode");
    idQuestion = 0;
    fact = questions.Length;
    questionMapper = new int[questions.Count];
    for(int i = 0; i < questionMapper.Count; i++)
    {
        questionMapper[i] = i;
    }
    questionMapper.Shuffle();
    question.text = questions [questionMapper[idQuestion]];
    answerA.text = alternativeA [questionMapper[idQuestion]];
    answerB.text = alternativeB [questionMapper[idQuestion]];
    answerC.text = alternativeC [questionMapper[idQuestion]];
    answerD.text = alternativeD [questionMapper[idQuestion]];
    infoAnswer.text = (idQuestion + 1).ToString() + " of " + fact.ToString () + "";
}

//...

void nextQuestion()
{
    idQuestion += Random.Range(0,10);
    if(idQuestion <= (fact-1))
    {
        question.text = questions [questionMapper[idQuestion]];
        answerA.text = alternativeA [questionMapper[idQuestion]];
        answerB.text = alternativeB [questionMapper[idQuestion]];
        answerC.text = alternativeC [questionMapper[idQuestion]];
        answerD.text = alternativeD [questionMapper[idQuestion]];
        stat.text = " Correct: " + points.ToString () + "";
        infoAnswer.text =  (idQuestion + 1).ToString() + " of " + fact.ToString () + "";
    }
    else
    {
        average = 10 * (points / fact);
        results = Mathf.RoundToInt (average);
        if (results > PlayerPrefs.GetInt ("results" + idMode.ToString ())) {
            PlayerPrefs.SetInt ("results" + idMode.ToString (), results);
            PlayerPrefs.SetInt ("points" + idMode.ToString (), (int)points);
        }
        PlayerPrefs.SetInt ("resultsTemp" + idMode.ToString (), results);
        PlayerPrefs.SetInt ("pointsTemp" + idMode.ToString (), (int)points);
        Application.LoadLevel("results");
    }
}
Community
  • 1
  • 1
Scott Chamberlain
  • 124,994
  • 33
  • 282
  • 431
  • thanks but do i really have to change my data structure? no other ways? – Magilou Oct 03 '16 at 13:48
  • 1
    There are other ways, but the easiest way to maintain it would be to change the data structure. Another option is create an array of `int`s counting up from 0 called `questionMapper`, and shuffle that. Then you do something like `questions[questionMapper[idQuestion]]`. – Scott Chamberlain Oct 03 '16 at 13:57
  • You should try the new data structure though, you should still be able to put the text in to the editor. Also see my latest update, I forgot to put `public` on the members in the `Question` class. – Scott Chamberlain Oct 03 '16 at 13:59
  • @Ixion I updated the question again showing how to do the `questionMapper` solution. You will need to still use the `Shuffle()` extension method I showed in the first part. – Scott Chamberlain Oct 03 '16 at 14:08
  • thanks very much, but i got error on extension tho "error CS1109: `GameManager.RandomExtensions.Shuffle(this T[])': Extension methods cannot be defined in a nested class" i put your shuffle extension above my code – Magilou Oct 03 '16 at 14:37
  • It needs to be outside of the `GameManager` class's `{ }`. Just make a new `RandomExtensions.cs` script at put it in the Assets folder, it should still be acessable by your `GameManager` class even if it is not attached to anything. – Scott Chamberlain Oct 03 '16 at 14:38
  • i changed "[Serializeable]" to "[System.Serializable]" because i got an error on "[Serializeable]" is it same? – Magilou Oct 03 '16 at 14:43
  • Scott thank you very much the random is working properly, but even if i pick the correct answer i dont have a score, should i go to the questionMapper? – Magilou Oct 03 '16 at 15:09
  • Oh I'm sorry my error alright i get it now. thank you tho, you a life saver Scott. hehe – Magilou Oct 03 '16 at 15:11
  • Instead of [System.Serializeable] you can put `using System;` at the top of the file and just use [Serializeable] it is the same. – Scott Chamberlain Oct 03 '16 at 15:17