Skip to content

Instantly share code, notes, and snippets.

@sesteva
Last active February 20, 2020 14:31
Show Gist options
  • Save sesteva/c48d51f8787b9a09bee29e816c452e1d to your computer and use it in GitHub Desktop.
Save sesteva/c48d51f8787b9a09bee29e816c452e1d to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
const results = [
{
"category":"Entertainment: Video Games",
"type":"multiple",
"difficulty":"easy",
"question":"Which game did "Sonic The Hedgehog" make his first appearance in?",
"correct_answer":"Rad Mobile",
"incorrect_answers":[
"Sonic The Hedgehog",
"Super Mario 64",
"Mega Man"
]
},
{
"category":"Science & Nature",
"type":"boolean",
"difficulty":"easy",
"question":"Igneous rocks are formed by excessive heat and pressure.",
"correct_answer":"False",
"incorrect_answers":[
"True"
]
},
{
"category":"General Knowledge",
"type":"multiple",
"difficulty":"easy",
"question":"Which company did Valve cooperate with in the creation of the Vive?",
"correct_answer":"HTC",
"incorrect_answers":[
"Oculus",
"Google",
"Razer"
]
}
]
function shuffle(array) {
var currentIndex = array.length, temporaryValue, randomIndex;
// While there remain elements to shuffle...
while (0 !== currentIndex) {
// Pick a remaining element...
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;
// And swap it with the current element.
temporaryValue = array[currentIndex];
array[currentIndex] = array[randomIndex];
array[randomIndex] = temporaryValue;
}
return array;
}
function getQuestionsAndRandomize(context) {
return new Promise((resolve, reject) => {
setTimeout( function() {
resolve(shuffle(results))
}, 250)
})
// return fetch('/api/users/${context.userId}').then(response =>
// response.json()
// );
}
const incrementDisplayedQuestions = assign({
answers: (context, event) => ({
...context.answers,
total:context.answers.total + 1
})
});
const pickNextQuestion = assign({
display: (context, event) => {
const questionIndex = context.display === null ? 0 : context.display.index+1
return {
...context.data[questionIndex],
index: questionIndex
}
},
})
const logResponse = assign({
answers: ({ answers, display }, {payload}) => {
const {correct, incorrect} = answers
const isCorrect = payload === display.correct_answer
const correctCount = isCorrect?correct+1:correct
const incorrectCount = isCorrect?incorrect:incorrect+1
return {
...answers,
correct: correctCount,
incorrect: incorrectCount
}
}
})
const calculateScore = assign({
answers: ({answers}, event) => {
const { correct, total } = answers
const ratio = correct/total
return {
...answers,
score: ratio.toFixed(2)
}
}
})
const quizMachine = Machine({
id: 'quiz',
initial: 'idle',
context: {
data: [],
display: null,
answers: {
correct: 0,
incorrect: 0,
total: 0,
score: 0
}
},
states: {
idle: {
on: {
START: 'gettingQuestions'
}
},
gettingQuestions: {
invoke: {
src: 'getQuestionsAndRandomize',
onDone: {
target: 'question',
actions: assign({
data: (context, event) => event.data
})
}
}
},
question: {
entry: ['incrementDisplayedQuestions', 'pickNextQuestion']
,
on: {
NEXT: [
{
target: 'summary',
cond: (context, event) => context.data.length === context.answers.total,
actions: 'calculateScore'
},
{ target: 'question' }
]
},
exit: ['logResponse']
},
summary: {
on:{
RESTART: 'question'
}
}
}
}, {
actions: {incrementDisplayedQuestions,pickNextQuestion, logResponse, calculateScore},
services: {
getQuestionsAndRandomize
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment