ether ether - 1 month ago 14
Javascript Question

randomly populating a quiz using javascript arrays?

I am trying to figure out how I can populate my jeopardy-esque quiz game with arrays, so I can have randomly generated questions. Currently I am setting my questions up like this:

Array reading as

Question ID | Question | Question Options | Correct Answer


var cat1question1easy = ["1", "What color is the sky?", "Red", "Pink", "Blue", "Green", "Bluecorrect"];
cat1question1easy.name = "cat1question1easy";

var cat2question2easy = ["2", "What color is grass", "Yellow", "Purple", "Black", "Green", "Greencorrect"];
cat1question2easy.name = "cat1question2easy";

var cat3question3easy = ["3", "What color is dirt?", "Brown", "White", "Turqouise", "Gray", "Browncorrect"];
cat1question3easy.name = "cat1question3easy";


Then I store them into an array for easy questions:

var cat1easyquestions = newArray(cat1question1easy, cat1question2easy, cat1question1easy);


Then I pull my random question for the 'question 1' slot by using:

var randomcat1easyquestion = cat1easyquestions[Math.floor(Math.random()*items.length)]


Which brings me to my main question, if my html for my question looks like this:

<h3></h3>
<input type="radio" name="" value="">
<input type="radio" name="" value="">
<input type="radio" name="" value="">
<input type="radio" name="" value="">


How could I populate it so it pulls my array's info so it shows as:

<h3>What color is the sky?</h3>
<input type="radio" value="Red">
<input type="radio" value="Pink">
<input type="radio" value="Blue">
<input type="radio" value="Green">


Is this a viable way to generate a random jeopardy board? or should I be looking at a better route?

Answer

I would propose to use a different data structure for storing your questions and answers:

var questions = [{
    question: "What color is the sky?",
    answers: ["Blue", "Red", "Pink", "Green"]
}, {
    question: "What color is grass?",
    answers: ["Green", "Yellow", "Purple", "Black"]
}, {
    question: "What color is dirt?",
    answers: ["Brown", "White", "Turqouise", "Gray"]
}];

In this structure you would put the correct answer always first. When actually displaying the options you would first shuffle them. This has two advantages:

  • You don't have to separately mention what the correct answer is in your data structure
  • The user will get the options in a random order, which may be different the next time

Also, you might not need to actually mention the question number. The position of the question in the overall array defines the number.

Your HTML would need to have labels for the answers as well:

<input type="radio" name="answer" value="" id="a1"><label for="a1"></label>
<input type="radio" name="answer" value="" id="a2"><label for="a2"></label>
<input type="radio" name="answer" value="" id="a3"><label for="a3"></label>
<input type="radio" name="answer" value="" id="a4"><label for="a4"></label>

The content of those labels show the answers to the user.

Here is working code:

// List of questions. First mentioned answer is correct one.
var questions = [{
    question: "What color is the sky?",
    answers: ["Blue", "Red", "Pink", "Green"]
}, {
    question: "What color is grass?",
    answers: ["Green", "Yellow", "Purple", "Black"]
}, {
    question: "What color is dirt?",
    answers: ["Brown", "White", "Turqouise", "Gray"]
}];

// Generic function to return a shuffled array:
function shuffled(arr) {
    arr = arr.slice(); // shallow copy
    for (var i = 0; i < arr.length; i++) {
        var j = Math.floor(Math.random() * (arr.length - i)) + i;
        [arr[i], arr[j]] = [arr[j], arr[i]]; // swap
    }
    return arr;
}

// define variables for some of the HTML elements:
var domQuestion = document.querySelector('#question');
var domAnswers = Array.from(document.querySelectorAll('input[name=answer]'));
var domNext = document.querySelector('#next');

function displayQuestion() {
    // get a random order for the answers:
    var answers = shuffled(questions[questionId].answers);
    // Display question
    domQuestion.textContent = (questionId+1) + '. ' + 
                              questions[questionId].question;
    domAnswers.forEach(function (input, i){
        // Set checkbox value and unselect it
        input.value = answers[i];
        input.checked = false;
        // Display the answer text
        input.nextElementSibling.textContent = answers[i];
    });
}

// Initialise and display first question
var questionId = 0;
var correctAnswers = 0;
displayQuestion();

// Respond to a click on the Next button 
domNext.addEventListener('click', function () {
    // update correct answer counter:
    var domAnswer = domAnswers.find(input => input.checked);
    if (!domAnswer) return; // nothing was selected
    // update number of correctly answered questions:
    if (domAnswer.value == questions[questionId].answers[0]) correctAnswers++;
    // next question
    questionId++;
    if (questionId >= questions.length) {
        alert('You have answered ' + correctAnswers + 
              ' of ' + questions.length + ' questions correctly.');
        // restart
        questionId = 0;
        correctAnswers = 0;
    }
    displayQuestion();
});
<h3 id="question"></h3>
<input type="radio" name="answer" value="" id="a1"><label for="a1"></label>
<input type="radio" name="answer" value="" id="a2"><label for="a2"></label>
<input type="radio" name="answer" value="" id="a3"><label for="a3"></label>
<input type="radio" name="answer" value="" id="a4"><label for="a4"></label>
<p>
<button id="next">Next</button>