Ixion Ixion - 2 months ago 13
C# Question

Unity 3D Quiz game random questions

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");
}
}
}

Answer

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");
    }
}