-1

I have a piece of code that I'm been working it and I'm new to JSON, I'm implementing a randomizer for my quiz and it works, but the problem is it repeats the question. How can I make it not repeat the question when it has been already asked? Here's my code.

      var quiztitle = "Abstraction";
    /**
     * 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": "Which of these keywords are used to define an abstract class?",
            "image": "",
            "choices": [
                "abst",
                "abstract",
                "Abstract",
                "abstract class"
            ],
            "correct": "abstract",
            "explanation": "",
        },
        {
            "question": "Which of these is not abstract?",
            "image": "",
            "choices": [
                "Thread",
                "AbstractList",
                "List",
                "None of the Mentioned"
            ],
            "correct": "Thread",
            "explanation": "Explanation: Thread is not an abstract class.",
        },
        {
            "question": "If a class inheriting an abstract class does not define all of its function then it will be known as?",
            "image": "",
            "choices": [
                "Abstract",
                "A simple class",
                "Static class",
                "None of the Mentioned"
            ],
    ];
    /******* 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']));
            }
            shuffleArray(quiz);
            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);
                    });
                }
            })
        }

        /**
         * Randomize array element order in-place.
         * Using Durstenfeld shuffle algorithm.
         */
        function shuffleArray(array) {
            for (var i = array.length - 1; i > 0; i--) {
                var j = Math.floor(Math.random() * (i + 1));
                var temp = array[i];
                array[i] = array[j];
                array[j] = temp;
            }
            return array;
        }
        /**
         * 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();
    });
zerkms
  • 249,484
  • 69
  • 436
  • 539

2 Answers2

0

What you want isn't a "random number" but a random sort / shuffle.

From your code it looks like you are shuffling after every question.

If you shuffle a deck of cards after drawing a card, you are going to see the same card again.

Shuffle once at the start, and loop through the questions and you will be good.

Ryan Leach
  • 4,262
  • 5
  • 34
  • 71
0

Since your list of questions is at its root an array, you can re-arrange the items in your array in a random order, then iterate over them in the new sequence... with no repeats.

var quiz = [];
quiz.randomize();

Now the above will work, as long as you have a method to randomize the content. There's many ways to do it, but if you need a quick and dirty solution, this method will extend the Array object to include this new method.

Array.prototype.randomize = function(){
  var len = this.length;
  var a,b,j;
  for(var i=0;i<len;i++){
      j = randomNumber(0, (len-1));
      a = this[i];
      b = this[j];
      this[i] = b;
      this[j] = a;
  }
};

Notes:

  1. This isn't a "gambling/science" approved random function
  2. This extends the Array prototype... many would prefer this to be a standalone function, adjust to suit.
scunliffe
  • 62,582
  • 25
  • 126
  • 161