JSFiddle - React, Tailwind, and code Playground
by Josh Pullen
HTML
<script src="//cdnjs.cloudflare.com/ajax/libs/seedrandom/3.0.5/seedrandom.min.js"></script>
JavaScript
const questions = {
a: {
generate({ min, max }) {
const a = Math.floor(Math.random() * (max - min) + min)
const b = Math.floor(Math.random() * (max - min) + min)
return { a, b }
},
check({ sum }, { a, b }) {
return sum === a + b
}
},
b: {
generate({ min, max }) {
const a = Math.floor(Math.random() * (max - min) + min)
const b = Math.floor(Math.random() * (max - min) + min)
return { a, b }
},
check({ difference }, { a, b }) {
return difference === a - b
}
}
}
const challenge = {
questions: {
default: { type: "a", generateParams: { min: 0, max: 10 } },
conditional: [
{
condition: { type: "progress", min: 0.5 },
question: { type: "b", generateParams: { min: 0, max: 10 } }
}
]
}
}
function generate(questionId, parameters, seed) {
Math.seedrandom(seed)
return questions[questionId].generate(parameters)
}
Math.seedrandom("test")
class ChallengeInstance {
constructor(userId) {
this.version = 1.0
this.userId = userId
this.progress = 0.0
this.questions = []
this.questions.push(this.generateQuestion())
}
nextSeedFromQuestions(questions) {
return this.userId + JSON.stringify(questions.map(question => question.answerData))
}
generateQuestion() {
const seed = this.nextSeedFromQuestions(this.questions)
const { type, generateParams } = challenge.questions.default
return new Question(type, generate(type, generateParams, seed))
}
addAnswer(data, time = new Date()) {
const question = this.questions[this.questions.length - 1]
question.setAnswerData(data, time)
if (question.correct) {
this.progress = Math.min(1, this.progress + 0.2)
} else {
this.progress = Math.max(0, this.progress - 0.2)
}
}
}
class Question {
constructor(type, questionData, createdAt = new Date()) {
this.type = type
this.questionData = questionData
...