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®ion=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>