[Quiz Game] How to prevent Question asked twice. HELP
Hello Everyone, I made a Quiz Game thanks to the Unity Tutorial https://www.youtube.com/watch?v=hLNPjIxf0C8.
Now I have put this code 'int questionIndex = Random.Range(0, questionPool.Length -1);' in the script under 'private void ShowQuestion()'
To pick up random questions, it works. But its take the same questions that is just asked. I want it to go like question is asked and don't come back in the round and go on with the new questions I am 3 days trying to fix this problem but nothing. I hope you guys can help me out.
Here is the script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using System.Linq;
public class GameController : MonoBehaviour
{
public int playerHealth = 30;
int damage = 10;
public Scrollbar HealthBar;
public float Health = 30;
public AudioClip Goed;
public AudioClip Fout;
public AudioClip klikklak;
public Text TotalscoreDisplayText;
public Text questionDisplayText;
public Text scoreDisplayText;
public Text timeRemainingDisplayText;
public SimpleObjectPool answerButtonObjectPool;
public Transform answerButtonParent;
public GameObject questionDisplay;
public GameObject roundEndDisplay;
public Text HighScoreText;
AudioSource GOED;
AudioSource FOUT;
AudioSource KlikKlak;
private DataController dataController;
private RoundData currentRoundData;
private QuestionData[] questionPool;
private bool isRoundActive;
private float timeRemaining;
private int questionIndex;
private int playerScore;
private List<GameObject> answerButtonGameObjects = new List<GameObject>();
void Awake()
{
GOED = GetComponent<AudioSource>();
FOUT = GetComponent<AudioSource>();
KlikKlak = GetComponent<AudioSource>();
}
// Use this for initialization
void Start()
{
dataController = FindObjectOfType<DataController>();
currentRoundData = dataController.GetCurrentRoundData();
questionPool = currentRoundData.questions;
UpdateTimeRemainingDisplay();
playerScore = 0;
questionIndex = 0;
ShowQuestion();
isRoundActive = true;
HighScoreText.text = " " + ((int)PlayerPrefs.GetFloat("HighScore")).ToString();
}
private void ShowQuestion()
{
RemoveAnswerButtons();
int questionIndex = Random.Range(0, questionPool.Length -1);
QuestionData questionData = questionPool[questionIndex];
questionDisplayText.text = questionData.questionText;
for (int i = 0; i < questionData.answers.Length; i++)
{
GameObject answerButtonGameObject = answerButtonObjectPool.GetObject();
answerButtonGameObjects.Add(answerButtonGameObject);
answerButtonGameObject.transform.SetParent(answerButtonParent);
AnswerButton answerButton = answerButtonGameObject.GetComponent<AnswerButton>();
answerButton.Setup(questionData.answers[i]);
timeRemaining = currentRoundData.timeLimitInSeconds;
}
}
private void RemoveAnswerButtons()
{
while (answerButtonGameObjects.Count > 0)
{
answerButtonObjectPool.ReturnObject(answerButtonGameObjects[0]);
answerButtonGameObjects.RemoveAt(0);
}
}
private void UpdateTimeRemainingDisplay()
{
timeRemainingDisplayText.text = "TIJD: " + Mathf.Round(timeRemaining).ToString();
}
public void AnswerButtonClicked(bool isCorrect, bool isNotCorrect, float value)
{
if (isNotCorrect)
{
playerHealth -= damage;
FOUT.PlayOneShot(Fout);
Health -= value = 10;
HealthBar.size -= Health / 40f;
if (Health == 10)
{
KlikKlak.PlayOneShot(klikklak);
}
}
if (isCorrect)
{
GOED.PlayOneShot(Goed);
playerScore += currentRoundData.pointsAddedForCorrectAnswer;
scoreDisplayText.text = "SCORE: " + playerScore.ToString();
TotalscoreDisplayText.text = "Totaal " + playerScore.ToString();
}
if (questionPool.Length > questionIndex + 1)
{
questionIndex++;
ShowQuestion();
}
else
{
EndRound();
}
}
public void EndRound()
{
if (PlayerPrefs.GetFloat("HighScore") < playerScore)
PlayerPrefs.SetFloat("HighScore", playerScore);
isRoundActive = false;
questionDisplay.SetActive(false);
roundEndDisplay.SetActive(true);
}
public void ReturnToMenu()
{
SceneManager.LoadScene("MenuScreen");
}
// Update is called once per frame
void Update()
{
if (isRoundActive)
{
timeRemaining -= Time.deltaTime;
UpdateTimeRemainingDisplay();
if (timeRemaining <= 0f)
{
EndRound();
}
else
if (playerHealth <= 0)
{
playerHealth = 0;
EndRound();
}
}
}
}
Answer by Blue-Mirror · Jan 19, 2017 at 08:29 AM
I didnt perfectly check your code so tell me if Im wrong, but it should be fairly "easy" hehe. All you have to do is change line 78 a bit, where your code says open up a random one.
Well the simplest thing that I can imagine right now is, to add an array of booleans, which does save the questions that have been asked as true or false. What means you get an random number and then you check if that question has already been asked. You do that by saying
private bool[] alreadyAskedQuestions; . . . (this is line 78)
if(alreadyAskedQuestions[questionIndex] == false)
{
QuestionData questionData = questionPool[questionIndex];
alreadyAskedQuestions[questionIndex] == true;
}
else
{
Well this is the part that you can make easy or hard well ... you can either call your function again and hope it picks a new questions ^^ or you would call your function again but an overloaded one that function could take an parameter, and you fill in the parameter you like or you just give the player the next viable question (what means you would search for the next question or you learn about hash tables :D (its actually really easy) but since you //are on it since 3 days ^^ Ive been there too so
for(int i = 0; i < questionsPool.length; i++)
{
if(alreadyAskedQuestions[questionIndex] == false)
{
QuestionData questionData = questionPool[questionIndex];
alreadyAskedQuestions[questionIndex] == true;
i = questionsPool.length;
}
}
}
I hope it works just try it :)
The code is not working :( Thanks for your effort
private void ShowQuestion()
{
RemoveAnswerButtons();
int questionIndex = Random.Range(0, questionPool.Length - 1);
QuestionData questionData = questionPool[questionIndex];
questionDisplayText.text = questionData.questionText;
if (alreadyAskedQuestions[questionIndex] == false)
{
questionData = questionPool[questionIndex];
alreadyAskedQuestions[questionIndex] = true;
}
else
{
for (int i = 0; i < questionPool.Length; i++)
{
if (alreadyAskedQuestions[questionIndex] == false)
{
questionData = questionPool[questionIndex];
alreadyAskedQuestions[questionIndex] = true;
i = questionPool.Length;
}
}
}
for (int i = 0; i < questionData.answers.Length; i++)
{
GameObject answerButtonGameObject = answerButtonObjectPool.GetObject();
answerButtonGameObjects.Add(answerButtonGameObject);
answerButtonGameObject.transform.SetParent(answerButtonParent);
AnswerButton answerButton = answerButtonGameObject.GetComponent<AnswerButton>();
answerButton.Setup(questionData.answers[i]);
timeRemaining = currentRoundData.timeLimitInSeconds;
}
}
Well you have this at the begining
QuestionData questionData = questionPool[questionIndex];
questionDisplayText.text = questionData.questionText;
and then you have it the if part as well, and it should only be in there. Since now you first call it there, and then you do call it agian. Delete the first call.
Follow this Question
Related Questions
How to declare a list of arrays? 1 Answer
How to remove an item from a list of custom variables 1 Answer
How to get all children of a Gameobject with a certain component 2 Answers
Array with pushing values? 0 Answers
How to spawn sprites in a row randomly from a single array without double-ups 0 Answers