Home > database >  Randomising the answers in a multiple choice quiz game
Randomising the answers in a multiple choice quiz game

Time:05-02

I am making a multiple choice game using Vue and JavaScript. Questions are sourced from an API. I have displayed the questions but I am not sure how to get the answers in a random order.

At the moment the correct answers are always the first option, since in the table I have with the buttons, I bound the correct answer to the first space, and incorrect ones to the rest. I was thinking maybe making a variable array with the correct and incorrect answers in a random order but I am not entirely sure how to randomise them.

Here is the relevant HTML:

<button type="button"  @click="getQ" @click="result = ''">Get Question</button>
    <p >{{question}}</p>
    <table width="100%" height="50%">
      <tr>
        <td width="50%">
          <button type="button"   @click="checkAnswer(correctAnswer)">{{correctAnswer}}</button>
        </td>
        <td width="50%">
          <button type="button"   @click="checkAnswer(incorrectAnswer)">{{incorrectAnswers[0]}}</button>
        </td>
      </tr>
      <tr>
        <td width="50%">
          <button type="button"   @click="checkAnswer(incorrectAnswer)">{{incorrectAnswers[1]}}</button>
        </td>
        <td width="50%">
          <button type="button"   @click="checkAnswer(incorrectAnswer)">{{incorrectAnswers[2]}}</button>
        </td>
      </tr>
    </table>
    <p>{{result}}</p>

I am using some bootstrap styling which is why there are some double classes and stuff. I was thinking maybe making an array with the random answer order and for the button text and function running using {{arrayName[0]}} to make it random.

Here is the relevant JavaScript:

let question = Vue.ref('');
let incorrectAnswers = Vue.ref([]);
let correctAnswer = Vue.ref('');
let result = Vue.ref('');
 
// Methods
let getQ = async function() {
  let response = await fetchURL('https://the-trivia-api.com/api/questions?categories=film_and_tv&limit=1&region=AU');
  this.correctAnswer = response[0].correctAnswer
  this.incorrectAnswers = response[0].incorrectAnswers
  this.question = response[0].question
}

let checkAnswer = function(clicked) {
  if (clicked === correctAnswer.value) { // checks if the button that was clicked is the same as the answers value
    this.result = "Correct!"; //if it does, result changes to Correct!
  } else {
    this.result = "Incorrect!"; //if the answer is incorrect, result changes to Incorrect!
  }
}

// Return variables, computed properties and methods
  return {
    correctAnswer, incorrectAnswers, question, result,
    getQ, checkAnswer,
  }
}

CodePudding user response:

You could use a famous algorithm called Fisher-Yates Algo to randomize items in an array extremely quickly and efficiently, if thats the route you want to take. It takes the following form:

function shuffle(array) {
  var m = array.length, t, i;

  // While there remain elements to shuffle…
  while (m) {

    // Pick a remaining element…
    i = Math.floor(Math.random() * m--);

    // And swap it with the current element.
    t = array[m];
    array[m] = array[i];
    array[i] = t;
  }

  return array;
}

CodePudding user response:

If you create a computed property, containing the shuffled version of your answers array, you can then use v-for to render each of these answers. For the actual shuffling logic, you can see this question.

Here's a basic example:

computed: {
  answers() {
  return this.answers
    .map(value => ({ value, sort: Math.random() }))
    .sort((a, b) => a.sort - b.sort)
    .map(({ value }) => value);
  }, 
},
<td v-for="(answer, index) in answers" :key="index">
  <button type="button"   @click="checkAnswer(answer)">{{ answer }}</button>
</td>
  • Related