0

I've tried several way to try to randomize these quiz questions using math random as a function but I'm afraid I'm too much of a novice to understand what I'm doing wrong. How would I be able to randomize these questions from this quiz?

Is there a simple way to make the questions into an array and then randomizing them as they appear on the browser? I only put two questions in this example to make it easier but can potentially put a lot more.

var quiztitle = "Computer Hardware: Visual Quiz!";

/**
 * Set the information about your questions here. The correct answer string needs to match
 * the correct choice exactly, as it does string matching. (case sensitive)
 *
 */

var quiz = [{
    "question": "Q1: What is the name of this game?",
    "image": "https://lh3.googleusercontent.com/N6XB3KXpnQ4OAz5jDJi74XM8dvwfJxiwrObSLpd7hdy3HzCxW-cZY0Mu5hJORtjeqa0=h900",
    "choices":[
      "Minecraft",
      "Call of Duty",
      "Doom",
      "Toca Boca"
    ],
    "correct": "Minecraft",
    "explanation": "It is a picture of zombies in minecrsft!",
  }, {
    "question": "Q2: What game is this?",
    "image": "https://assets.vg247.com/current//2015/03/crossy_road_header_1.jpg",
    "choices": [
      "Run sackboy",
      "Call of Duty",
      "Minecraft",
      "Crossy road"
    ],
    "correct": "Crossy road",
    "explanation": "A picture of the signiture chicken running across the road",
  },
];



/******* No need to edit below this line *********/
var currentquestion = 0,
  score = 0,
  submt = true,
  picked;

jQuery(document).ready(function($) {

  /**
   * HTML Encoding function for alt tags and attributes to prevent messy
   * data appearing inside tag attributes.
   */
  function htmlEncode(value) {
    return $(document.createElement('div')).text(value).html();
  }

  /**
   * This will add the individual choices for each question to the ul#choice-block
   *
   * @param {choices} array The choices from each question
   */
  function addChoices(choices) {
    if (typeof choices !== "undefined" && $.type(choices) == "array") {
      $('#choice-block').empty();
      for (var i = 0; i < choices.length; i++) {
        $(document.createElement('li')).addClass('choice choice-box').attr('data-index', i).text(choices[i]).appendTo('#choice-block');
      }
    }
  }

  /**
   * Resets all of the fields to prepare for next question
   */
  function nextQuestion() {
    submt = true;
    $('#explanation').empty();
    $('#question').text(quiz[currentquestion]['question']);
    $('#pager').text('Question ' + Number(currentquestion + 1) + ' of ' + quiz.length);
    if (quiz[currentquestion].hasOwnProperty('image') && quiz[currentquestion]['image'] != "") {
      if ($('#question-image').length == 0) {
        $(document.createElement('img')).addClass('question-image').attr('id', 'question-image').attr('src', quiz[currentquestion]['image']).attr('alt', htmlEncode(quiz[currentquestion]['question'])).insertAfter('#question');
      } else {
        $('#question-image').attr('src', quiz[currentquestion]['image']).attr('alt', htmlEncode(quiz[currentquestion]['question']));
      }
    } else {
      $('#question-image').remove();
    }
    addChoices(quiz[currentquestion]['choices']);
    setupButtons();
  }

  /**
   * After a selection is submitted, checks if its the right answer
   *
   * @param {choice} number The li zero-based index of the choice picked
   */
  function processQuestion(choice) {
    if (quiz[currentquestion]['choices'][choice] == quiz[currentquestion]['correct']) {
      $('.choice').eq(choice).css({
        'background-color': '#50D943'
      });
      $('#explanation').html('<strong>Correct!</strong> ' + htmlEncode(quiz[currentquestion]['explanation']));
      score++;
    } else {
      $('.choice').eq(choice).css({
        'background-color': '#D92623'
      });
      $('#explanation').html('<strong>Incorrect.</strong> ' + htmlEncode(quiz[currentquestion]['explanation']));
    }
    currentquestion++;
    $('#submitbutton').html('NEXT QUESTION &raquo;').on('click', function() {
      if (currentquestion == quiz.length) {
        endQuiz();
      } else {
        $(this).text('Check Answer').css({
          'color': '#222'
        }).off('click');
        nextQuestion();
      }
    })
  }

  /**
   * Sets up the event listeners for each button.
   */
  function setupButtons() {
    $('.choice').on('mouseover', function() {
      $(this).css({
        'background-color': '#e1e1e1'
      });
    });
    $('.choice').on('mouseout', function() {
      $(this).css({
        'background-color': '#fff'
      });
    })
    $('.choice').on('click', function() {
      picked = $(this).attr('data-index');
      $('.choice').removeAttr('style').off('mouseout mouseover');
      $(this).css({
        'border-color': '#222',
        'font-weight': 700,
        'background-color': '#c1c1c1'
      });
      if (submt) {
        submt = false;
        $('#submitbutton').css({
          'color': '#000'
        }).on('click', function() {
          $('.choice').off('click');
          $(this).off('click');
          processQuestion(picked);
        });
      }
    })
  }

  /**
   * Quiz ends, display a message.
   */
  function endQuiz() {
    $('#explanation').empty();
    $('#question').empty();
    $('#choice-block').empty();
    $('#submitbutton').remove();
    $('#question').text("You got " + score + " out of " + quiz.length + " correct.");
    $(document.createElement('h2')).css({
      'text-align': 'center',
      'font-size': '4em'
    }).text(Math.round(score / quiz.length * 100) + '%').insertAfter('#question');
  }

  /**
   * Runs the first time and creates all of the elements for the quiz
   */
  function init() {
    //add title
    if (typeof quiztitle !== "undefined" && $.type(quiztitle) === "string") {
      $(document.createElement('h1')).text(quiztitle).appendTo('#frame');
    } else {
      $(document.createElement('h1')).text("Quiz").appendTo('#frame');
    }

    //add pager and questions
    if (typeof quiz !== "undefined" && $.type(quiz) === "array") {
      //add pager
      $(document.createElement('p')).addClass('pager').attr('id', 'pager').text('Question 1 of ' + quiz.length).appendTo('#frame');
      //add first question
      $(document.createElement('h2')).addClass('question').attr('id', 'question').text(quiz[0]['question']).appendTo('#frame');
      //add image if present
      if (quiz[0].hasOwnProperty('image') && quiz[0]['image'] != "") {
        $(document.createElement('img')).addClass('question-image').attr('id', 'question-image').attr('src', quiz[0]['image']).attr('alt', htmlEncode(quiz[0]['question'])).appendTo('#frame');
      }
      $(document.createElement('p')).addClass('explanation').attr('id', 'explanation').html('&nbsp;').appendTo('#frame');

      //questions holder
      $(document.createElement('ul')).attr('id', 'choice-block').appendTo('#frame');

      //add choices
      addChoices(quiz[0]['choices']);

      //add submit button
      $(document.createElement('div')).addClass('choice-box').attr('id', 'submitbutton').text('Check Answer').css({
        'font-weight': 700,
        'color': '#222',
        'padding': '30px 0'
      }).appendTo('#frame');

      setupButtons();
    }
  }

  init();
});
  • 1
    Does this answer your question? [How to randomize (shuffle) a JavaScript array?](https://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array) – D. Pardal Jul 03 '20 at 12:56

2 Answers2

1

I recommend using Chancejs and use pickone().

So, you can just use chance.pickone(quiz) and you can expect a random quiz from it very easily.

holydragon
  • 6,158
  • 6
  • 39
  • 62
0

The approach I'd recommend is choosing a random index from the questions array, splicing it out of the array, and returning either the value we just spliced out of the array or an empty string if the array was already empty.

We can do this with regular javascript:

var questions = ['a', 'b', 'c'];

function getNextQuestion(){
  return questions.splice(Math.floor(Math.random() * questions.lengh), 1)[0] || "";
}

//show that it works
for(var i = 0; i < 5; i++) console.log(getNextQuestion());

Or with rando.js, which is a bit more readable and is cryptographically secure:

var questions = ['a', 'b', 'c'];

function getNextQuestion(){
  return questions.splice(rando(questions).index, 1)[0] || "";
}

//show that it works
for(var i = 0; i < 5; i++) console.log(getNextQuestion());
<script src="https://randojs.com/2.0.0.js"></script>

If you want to use the randojs code, just don't forget to include that script tag in the head of your html document.

Aaron Plocharczyk
  • 2,776
  • 2
  • 7
  • 15