1

I have a Quiz game with multiple choices. I Want to show random question however sometimes the same Questions is being picked more than once. I want to remove the selected questions out of my list so it doesn't get picked anymore..

This is the Game Manager that shows my question's ** Check the ShowQuestion Function there where i do my random. i basically want when a question is picked to not show again

public class GameController : MonoBehaviour {

private dataController DataController;
private roundData currentRoundData;
// QUestions that we will be working with in this round
private questionData[] questionPool;
private List<GameObject> answerButtonGameobjects = new List<GameObject>();

private List<GameObject> QuestionGameobjects = new List<GameObject>();


[Header("OTHER")]
public SimpleObjectPool answerButtonObjectPool;
public Transform answerButtonParent;


[Tooltip("Variables")]
// is the game going? 
private bool isRoundActive;
private float timerRemaing;
// What number question we are on
private int questionIndex;
private int questionNumber = 1;
private int totalQuestions;



[Header("UI")]
[Header("TEXT ")]
public Text questionText;
public Text scoreDisplayText;
public Text timeRemainingDisplayText;
public Text highScoreText;
public Text questionIndexText;

void Start () {

    DataController = FindObjectOfType<dataController>();

    currentRoundData = DataController.getCurrentRoundData();



    // stores our questions
    questionPool = currentRoundData.questions;

    timerRemaing = currentRoundData.timeLimitInSeconds;

    questionIndex = 0;

   totalQuestions = 10;


    ShowQuestion();

}

// Show our 1st question
private void ShowQuestion()
{
    RemoveAnsweredButtons();


    // Hold current question data from our pool
   questionData QuestionData = questionPool[Random.Range(0, totalQuestions)];

    questionText.text = QuestionData.questionText;

    for (int i = 0; i < QuestionData.answers.Length; i++)
    {
        GameObject answerButtonGameobject = answerButtonObjectPool.GetObject();
        answerButtonGameobject.transform.SetParent(answerButtonParent);
        answerButtonGameobjects.Add(answerButtonGameobject);

        AnswerButton answerButton = answerButtonGameobject.GetComponent<AnswerButton>();
        answerButton.Setup(QuestionData.answers[i]);
    }


}

/// <summary>
/// Removes the old answers button before we display new ones.
/// </summary>
private void RemoveAnsweredButtons()
{
    while (answerButtonGameobjects.Count > 0)
    {
        answerButtonObjectPool.ReturnObject(answerButtonGameobjects[0]);
        answerButtonGameobjects.RemoveAt(0);
    }


}




private void UpdateQuestionIndex()
{
    questionIndex++;

    questionNumber++;
    questionIndexText.text = "Question  " + (questionNumber.ToString()) +  " out of 10";
}



}

The Questions and Answers are being generated using a Simple pool system that was taken from Unity Site.

Here's the pooling class

using UnityEngine;
using System.Collections.Generic;

// A very simple object pooling class
 public class SimpleObjectPool : MonoBehaviour
{
// the prefab that this object pool returns instances of
public GameObject prefab;
// collection of currently inactive instances of the prefab
private Stack<GameObject> inactiveInstances = new Stack<GameObject>();

// Returns an instance of the prefab
public GameObject GetObject() 
{
    GameObject spawnedGameObject;

    // if there is an inactive instance of the prefab ready to return, return that
    if (inactiveInstances.Count > 0) 
    {
        // remove the instance from teh collection of inactive instances
        spawnedGameObject = inactiveInstances.Pop();
    }
    // otherwise, create a new instance
    else 
    {
        spawnedGameObject = (GameObject)GameObject.Instantiate(prefab);

        // add the PooledObject component to the prefab so we know it came from this pool
        PooledObject pooledObject = spawnedGameObject.AddComponent<PooledObject>();
        pooledObject.pool = this;
    }

    // put the instance in the root of the scene and enable it
    spawnedGameObject.transform.SetParent(null);
    spawnedGameObject.SetActive(true);

    // return a reference to the instance
    return spawnedGameObject;
}

// Return an instance of the prefab to the pool
public void ReturnObject(GameObject toReturn) 
{
    PooledObject pooledObject = toReturn.GetComponent<PooledObject>();

    // if the instance came from this pool, return it to the pool
    if(pooledObject != null && pooledObject.pool == this)
    {
        // make the instance a child of this and disable it
        toReturn.transform.SetParent(transform);
        toReturn.SetActive(false);

        // add the instance to the collection of inactive instances
        inactiveInstances.Push(toReturn);
    }
    // otherwise, just destroy it
    else
    {
        Debug.LogWarning(toReturn.name + " was returned to a pool it wasn't spawned from! Destroying.");
        Destroy(toReturn);
    }
}
}

// a component that simply identifies the pool that a GameObject came from
public class PooledObject : MonoBehaviour
{
  public SimpleObjectPool pool;
}
code11
  • 1,986
  • 5
  • 29
  • 37
Nanopili
  • 73
  • 12
  • Looks like too many code, could you please remove irrelevant codes? – sujith karivelil Jan 17 '17 at 13:33
  • Check my answer [here](http://stackoverflow.com/questions/41631918/generate-10-unique-integers-in-c-sharp-for-unity/41632286#41632286). Is that what you want? – Fredrik Schön Jan 17 '17 at 13:35
  • 2
    Shuffle all the questions. Then just feed the questions from 1 to n – bixarrio Jan 17 '17 at 13:38
  • @un-lucky better now? sorry! – Nanopili Jan 17 '17 at 13:43
  • @fredrik no not really =/ – Nanopili Jan 17 '17 at 13:50
  • @bixarrio how excatly? – Nanopili Jan 17 '17 at 13:54
  • @Nanopili A simple way; Shuffle a list with numbers from 1 to pool_size. These are the indices of the questions you wish to display. They are random and unique. Then just get the questions from the pool using each of these in sequence. Here's a [link to the fisher-yates](https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle) shuffling algorithm – bixarrio Jan 17 '17 at 13:59
  • it's a bit confusing because i dont know what should the List type be... Can you write some code? I mean will it be List? or an int? because i already tried with adding to list and then remove but i keep getting error that i can't convert questionData to Int – Nanopili Jan 17 '17 at 14:02

1 Answers1

3

It's untested, and vanilla 'psuedo' C# to give you a guideline

private List<int> _questions = null;
private int _current = 0;
void Start()
{
    _questions = Enumerable.Range(0, questionPool.Length).ToList();
    Shuffle(_questions);
}
void Shuffle(List<int> list)
{
    // put fisher-yates algorithm here to shuffle the numbers
}
void ShowQuestion()
{
    var idx = _questions[_current++];
    var questionData = questionPool[idx];
}
bixarrio
  • 373
  • 1
  • 10
  • Can't i just randomize the index itself and remove the picked index? idk im actually so confused and stuck over this although it's easy... – Nanopili Jan 17 '17 at 15:21
  • You don't need to remove the question. The indices are random and unique. If you just run through the list, you will not use an index that was used already. – bixarrio Jan 18 '17 at 07:04
  • To do what you want, you'd remove the question at the index. It's easier when you use a list for the questions as opposed to an array; `questionPool.RemoveAt(i)`. – bixarrio Jan 18 '17 at 07:10