Created
January 4, 2018 04:21
-
-
Save emmanuellyautomated/335f8d992cb1d7f3c362caf6a1480672 to your computer and use it in GitHub Desktop.
A simple game of trivia
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en-us"> | |
<head> | |
<meta charset="UTF-8"> | |
<title>Trivia</title> | |
</head> | |
<body> | |
<div id="timer"></div> | |
<div id="trivia"></div> | |
</body> | |
<script> | |
function Timer(gameLength) { | |
this.timeLeft = gameLength; | |
this.done = null; | |
this.reset = function() { | |
clearInterval(timer); | |
this.timeLeft = 0; | |
document.querySelector("#timer").innerHTML = this.render(); | |
}; | |
this.render = function() { | |
return "<div>Time Left: " + this.timeLeft + "</div><br>"; | |
}; | |
var that = this; | |
var countdown = function() { | |
that.timeLeft--; | |
document.querySelector("#timer").innerHTML = that.render(); | |
if (that.timeLeft === 0) { // game over | |
that.reset(); | |
that.done = true; | |
document.dispatchEvent(new Event('timerDone')); | |
} | |
}; | |
var timer = setInterval(countdown, 1000); | |
} | |
function Answer(content, name) { | |
this.content = content || ""; | |
this.name = name; | |
this.render = function() { | |
return "<input type=radio name=" + this.name + " value='" + this.content + "'>" + this.content; | |
}; | |
} | |
function Question(content, choices) { | |
this.id = generateUniqueId("question"); | |
this.content = content; | |
this.answeredCorrectly = null; | |
this.serialize = function() { | |
var answerID = this.id + "-answer"; | |
var selectedAnswer = document.querySelector("#" + this.id).elements[answerID].value; | |
var result = {}; result[this.content] = {"answer": selectedAnswer, "id": this.id}; | |
return result; | |
}; | |
this.disableAnswering = function() { | |
var radioButtons = document.querySelectorAll("input[name=" + this.id + "-answer]"); | |
radioButtons.forEach(function(radioButton) { radioButton.disabled = true; }); | |
}; | |
this.render = function() { | |
var inputs = this.answers.map(function(answer) { return answer.render(); }); | |
return "<form id=" + this.id + ">" + | |
this.content + "<br>" + | |
inputs.join("") + | |
"</form>"; | |
}; | |
var that = this; | |
this.answers = choices.map(function(choice) { return new Answer(choice, that.id + "-answer"); }); | |
} | |
function Trivia(struct, gameLength) { | |
this.timer = new Timer(gameLength); | |
this.questions = Object.keys(struct).map(function(question) { | |
var choices = struct[question].choices; | |
return new Question(question, choices); | |
}); | |
this.serialize = function() { | |
var serializedQuestions = this.questions.map(function(question) { return question.serialize(); }); | |
return serializedQuestions.reduce(function(acc, obj) { | |
for (var key in obj) { acc[key] = obj[key].answer; } | |
return acc; | |
}, {}); | |
}; | |
this.disableAllAnswering = function() { | |
this.questions.forEach(function(question, index) { question.disableAnswering(); }); | |
document.querySelector("#questions button").disabled = true; | |
}; | |
this.checkUserAnswers = function() { | |
var questions = that.questions; | |
var rubric = getRubric(); | |
var userAnswers = questions.map(function(question) { | |
return question.serialize(); | |
}).reduce(function(acc, obj) { | |
for (var key in obj) { acc[key] = obj[key]; } | |
return acc; | |
}, {}); | |
Object.keys(rubric).forEach(function(key, index) { | |
question = questions.filter(function(question) { return question.id == userAnswers[key].id; }).pop(); | |
if (rubric[key] == userAnswers[key].answer) { // win condition | |
question.answeredCorrectly = true; | |
} else if (userAnswers[key].answer !== "") { | |
question.answeredCorrectly = false; | |
} | |
}); | |
return questions.map(function(question) { return question.answeredCorrectly; }); | |
}; | |
this.calculateScore = function() { | |
// Do something more fancy in the future | |
return this.correct(); | |
}; | |
this.correct = function() { | |
return this.questions.filter(function(question) { return question.answeredCorrectly === true; }).length; | |
}; | |
this.incorrect = function() { | |
return this.questions.filter(function(question) { return question.answeredCorrectly === false; }).length; | |
}; | |
this.unanswered = function() { | |
return this.questions.filter(function(question) { return question.answeredCorrectly === null; }).length; | |
}; | |
this.render = function() { | |
var serialize = this.serialize; | |
var forms = this.questions.map(function(question) { return question.render(); }); | |
return "<div id=questions>" + | |
forms.join("<br>") + | |
"<br><button>" + "Final Answer" + "</button>" + | |
"</div>"; | |
}; | |
var that = this; | |
var getRubric = function() { | |
var result = {}; | |
Object.keys(struct).forEach(function(key, index) { | |
result[key] = struct[key].answer; | |
}); | |
return result; | |
}; | |
var gameOver = function() { | |
that.timer.reset(); | |
that.checkUserAnswers(); | |
that.disableAllAnswering(); | |
console.log(that.serialize(), that.calculateScore()); | |
alert( | |
"Correct: " + that.correct() + "\n" + | |
"Incorrect: " + that.incorrect() + "\n" + | |
"Unanswered: " + that.unanswered() | |
); | |
}; | |
document.addEventListener("DOMContentLoaded", function() { | |
document.querySelector("#timer").innerHTML = that.timer.render(); | |
document.querySelector("#trivia").innerHTML = that.render(); | |
document.querySelector("#questions button").onclick = gameOver; // game over | |
}); | |
document.addEventListener("timerDone", gameOver); | |
} | |
var generateUniqueId = function(prefix) { | |
if (prefix === undefined) { | |
return Math.random().toString(36).substr(2, 16); | |
} else { | |
return prefix + "-" + Math.random().toString(36).substr(2, 16); | |
} | |
}; | |
var questionsAndAnswers = { | |
"What is the circumference of the Earth?": { | |
"choices": [ | |
"24.901 mi", | |
"249.01 mi", | |
"2,490.1 mi", | |
"24,901 mi", | |
], | |
"answer": "24,901 mi" | |
}, | |
"How many Toy Story movies are there?": { | |
"choices": [ | |
"1", | |
"2", | |
"3", | |
"4", | |
], | |
"answer": "3" | |
}, | |
"Who is the current President of France?": { | |
"choices": [ | |
"Emmanuel Macron", | |
"Marie Le Pen", | |
"Christine Lagarde", | |
"Nicholas Sarkozy" | |
], | |
"answer": "Emmanuel Macron" | |
} | |
}; | |
var trivia = new Trivia(questionsAndAnswers, 10); | |
</script> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment