Skip to content

Instantly share code, notes, and snippets.

@emmanuellyautomated
Created January 4, 2018 04:21
Show Gist options
  • Save emmanuellyautomated/335f8d992cb1d7f3c362caf6a1480672 to your computer and use it in GitHub Desktop.
Save emmanuellyautomated/335f8d992cb1d7f3c362caf6a1480672 to your computer and use it in GitHub Desktop.
A simple game of trivia
<!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