I want the answers to appear messy along with the question, so the answers don't always look the same, but the answers seem messy with the question.
example in question 1 Who is really a chef? respond, 'Monica', 'Chandler', 'Rachel', 'Ross' I want those responses to be displayed randomly as' Chandler', 'Ross'' Rachel ',' Monica 'or' Monica ',' Rachel ',' Ross', 'Chandler'
$(document).ready(function() {
$("#remaining-time").hide();
$("#start").on("click", trivia.startGame);
$(document).on("click", ".option", trivia.guessChecker);
});
var trivia = {
correct: 0,
incorrect: 0,
unanswered: 0,
currentSet: 0,
// "seen" property will keep track of the seen questions so we don't re-display them again
seen: [],
// Update: limit the number of question per game. Usong a property so you can change its value whenever you want to change the limit
limit: 4,
timer: 20,
timerOn: false,
timerId: "",
// questions options and answers data
questions: {
q1: "Who is actually a chef?",
q2: "What does Joey love to eat?",
q3: "How many times has Ross been divorced?",
q4: "How many types of towels does Monica have?",
q5: "Who stole Monica's thunder after she got engaged?",
q6: "Who hates Thanksgiving?",
q7: "Who thinks they're always the last to find out everything?"
},
options: {
q1: ["Monica", "Chandler", "Rachel", "Ross"],
q2: ["Fish", "Apples", "Oranges", "Sandwhiches"],
q3: ["5", "2", "1", "3"],
q4: ["3", "8", "11", "6"],
q5: ["Rachel", "Phoebe", "Emily", "Carol"],
q6: ["Joey", "Chandler", "Rachel", "Ross"],
q7: ["Ross", "Phoebe", "Monica", "Chandler"]
},
answers: {
q1: "Monica",
q2: "Sandwhiches",
q3: "3",
q4: "11",
q5: "Rachel",
q6: "Chandler",
q7: "Phoebe"
},
// random number generator
random: (min, max) => Math.floor(Math.random() * (max - min + 1)) + min,
startGame: function() {
trivia.currentSet = 0;
// set "seen" to an empty array for a new game
trivia.seen = [];
trivia.correct = 0;
trivia.incorrect = 0;
trivia.unanswered = 0;
clearInterval(trivia.timerId);
$("#game").show();
$("#results").html("");
$("#timer").text(trivia.timer);
$("#start").hide();
$("#remaining-time").show();
trivia.nextQuestion();
},
nextQuestion: function() {
trivia.timer = 10;
$("#timer").removeClass("last-seconds");
$("#timer").text(trivia.timer);
if (!trivia.timerOn) {
trivia.timerId = setInterval(trivia.timerRunning, 1000);
}
// get all the questions
const qts = Object.values(trivia.questions);
// init the random number
let rq = null;
// firstly, if no more questions to show set rq to -1 to let us know later that the game has finished
// Update: checking if we reached the "limit"
if (trivia.seen.length >= trivia.limit) rq = -1
else {
// otherwise generate a random number from 0 inclusive to the length of the questions - 1 (as array indexing starts from 0 in JS) also inclusive
do {
// generate a random number using the newly added "random" method
rq = trivia.random(0, qts.length - 1);
} while (trivia.seen.indexOf(rq) != -1); // if the question is already seen then genrate another number, do that till we get a non-seen question index
// add that randomly generated index to the seen array so we know that we have already seen it
trivia.seen.push(rq);
// increment the counter
trivia.counter++;
}
// current question index is the generated random number "rq"
trivia.currentSet = rq;
var questionContent = Object.values(trivia.questions)[rq];
$("#question").text(questionContent);
var questionOptions = Object.values(trivia.options)[trivia.currentSet];
$.each(questionOptions, function(index, key) {
$("#options").append(
$('<button class="option btn btn-info btn-lg">' + key + "</button>")
);
});
},
timerRunning: function() {
if (
trivia.timer > -1 &&
// all the questions have already been seen
// Update: now we check against the limit property
trivia.seen.length < trivia.limit
) {
$("#timer").text(trivia.timer);
trivia.timer--;
if (trivia.timer === 4) {
$("#timer").addClass("last-seconds");
}
} else if (trivia.timer === -1) {
trivia.unanswered++;
trivia.result = false;
clearInterval(trivia.timerId);
resultId = setTimeout(trivia.guessResult, 1000);
$("#results").html(
"<h3>Out of time! The answer was " +
Object.values(trivia.answers)[trivia.currentSet] +
"</h3>"
);
}
// if the game ended as we know that -1 means no more questions to display
else if (trivia.currentSet === -1) {
$("#results").html(
"<h3>Thank you for playing!</h3>" +
"<p>Correct: " +
trivia.correct +
"</p>" +
"<p>Incorrect: " +
trivia.incorrect +
"</p>" +
"<p>Unaswered: " +
trivia.unanswered +
"</p>" +
"<p>Please play again!</p>"
);
$("#game").hide();
$("#start").show();
}
},
guessChecker: function() {
var resultId;
var currentAnswer = Object.values(trivia.answers)[trivia.currentSet];
if ($(this).text() === currentAnswer) {
//turn button green for correct
$(this).addClass("btn-success").removeClass("btn-info");
trivia.correct++;
clearInterval(trivia.timerId);
resultId = setTimeout(trivia.guessResult, 1000);
$("#results").html("<h3>Correct Answer!</h3>");
} else {
$(this).addClass("btn-danger").removeClass("btn-info");
trivia.incorrect++;
clearInterval(trivia.timerId);
resultId = setTimeout(trivia.guessResult, 1000);
$("#results").html(
"<h3>Better luck next time! " + currentAnswer + "</h3>"
);
}
},
guessResult: function() {
// no need to increment trivia.currentSet anymore
$(".option").remove();
$("#results h3").remove();
trivia.nextQuestion();
}
};
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="header text-center clearfix">
<h1 class="text-muted">Friends trivia game</h1>
</div>
<div class="jumbotron jumbotron-fluid">
<div class="container">
<div id="game">
<h2>FRIENDS Trivia Game</h2>
<p id="remaining-time" class="lead">Remaining Time: <span id="timer"></span></p>
<p id="question" class="lead"></p>
</div>
<div id="results">
</div>
</div>
<div class="row">
<div id="choices" class="text-center">
<button id="start" class="btn btn-info btn-lg">Start Game</button>
<div id="options">
</div>
</div>
</div>
</div>
<!-- /container -->
Where you begin adding answers to the page, try this code instead:
$.each(Object.values(trivia.options)[trivia.currentSet].sort( () => {
return .5 - Math.random();
}), key => {
$("#options").append(
$('<button class="option btn btn-info btn-lg">' + key + "</button>")
);
});
This is not a secure or efficient way of randomizing an array, but it does the trick for something like this. It just picks a random number between 0 and 1 and subtracts it from 0.5, so the returned number is between -0.5 and 0.5. The sort function does the rest.
This whole thing belongs at the end of your trivia.nextQuestion function.
This whole thing could be done without jQuery. If you're not using it for any particular reason, it might be worth your while to try this in vanilla JavaScript. To get you started, here's the same chunk of code:
const options = document.getElementById("options");
Object.values(trivia.options)[trivia.currentSet].sort( () => {
return .5 - Math.random();
}).forEach(key => {
options.innerHTML += `<button class="option btn btn-info btn-lg">${key}</button>';
});
And while you're at it, look at whether trivia.questions, trivia.options, or trivia.answers need to be objects, or if arrays would work fine. But that belongs mroe on Code Review...
Related
This question already has answers here:
How to get a number of random elements from an array?
(25 answers)
Closed last month.
I'm trying to make simple javascript quiz with like 10 questions, and show random 5 on each page load.
I have following code for questions:
var mojaPitanja = [
{
tekst: "What is the color of the sky?",
odgovori: {
a: 'Blue',
b: 'Red',
c: 'Green'
},
indeks_korektnog_odgovora: 'a'
},
{
tekst: "In which country is located town Rome?",
odgovori: {
a: 'France',
b: 'Austria',
c: 'Italy'
},
indeks_korektnog_odgovora: 'c'
},
{
tekst: "Who was Elvis Presley?",
odgovori: {
a: 'Singer',
b: 'Writer',
c: 'Dancer'
},
indeks_korektnog_odgovora: 'a'
}
...................
];
Out of that list (with 10 questions) I want to get 5 random questions and show them on page.
This is the other part of the code I'm using to show the whole quiz on my page:
function generisiKviz(teksts, quizContainer, rezContainer, posaljiDugme){
function prikazPitanja(teksts, quizContainer){
// prostor za output i opcije odgovora
var output = [];
var odgovori;
// za svako pitanje...
for(var i=0; i<teksts.length; i++){
// prvo resetujemo listu odgovora
odgovori = [];
// za svaku opciju odgovora na dato pitanje...
for(letter in teksts[i].odgovori){
// ...dodajemo radio button
odgovori.push(
'<label>'
+ '<input type="radio" name="tekst'+i+'" value="'+letter+'">'
+ letter + ': '
+ teksts[i].odgovori[letter]
+ '</label>'
);
}
// dodajemo specificno pitanje i odgovore za dato pitanje
output.push(
'<div class="pitanje"><div class="tekst">' + teksts[i].tekst + '</div>'
+ '<div class="odgovori">' + odgovori.join('') + '</div></div>'
);
}
// finalni output koji se stavlja na stranicu
quizContainer.innerHTML = output.join('');
}
function showResults(teksts, quizContainer, rezContainer){
// prikupljanje odgovora iz celog kviza
var answerContainers = quizContainer.querySelectorAll('.odgovori');
// sacuvati odgovore korisnika..
var userAnswer = '';
var numCorrect = 0;
// za svako pitanje...
for(var i=0; i<teksts.length; i++){
// pronalazenje svakog odgovora
userAnswer = (answerContainers[i].querySelector('input[name=tekst'+i+']:checked')||{}).value;
// ako je odgovor tacan
if(userAnswer===teksts[i].indeks_korektnog_odgovora){
// dodati na sumarnu listu i sabrati koliko je tacnih...
numCorrect++;
// tacni odg zeleni
answerContainers[i].style.color = 'green';
}
// ako je odgovor netacan ili prazan
else{
// boja je, logicno, crvena...
answerContainers[i].style.color = 'red';
}
}
// prikaz ukupnog broja tacnih odgovora od sumarnog broja pitanja
rezContainer.innerHTML = numCorrect + ' pogođenih od ukupno ' + teksts.length;
}
// prikaz odgovora
prikazPitanja(teksts, quizContainer);
// kad se klikne "posalji" dugme prikaz rezultata
posaljiDugme.onclick = function(){
showResults(teksts, quizContainer, rezContainer);
}
}
var quizContainer = document.getElementById('quiz');
var rezContainer = document.getElementById('results');
var posaljiDugme = document.getElementById('submit');
And html:
<title>Page title</title>
<link rel="stylesheet" href="index.css">
<div id="quiz"></div>
<button id="submit">Pošalji odgovore</button> <button id="reloadfazon" onClick="window.location.reload()">Nova pitanja / reload</button>
<div id="results"></div>
<script src="script.js"></script>
<script>
generisiKviz(mojaPitanja, quizContainer, rezContainer, posaljiDugme);
</script>
And html:
<title>Quiz project</title>
<link rel="stylesheet" href="index.css">
<div id="quiz"></div>
<button id="submit">Pošalji odgovore</button> <button id="reloadfazon" onClick="window.location.reload()">Nova pitanja / reload</button>
<div id="results"></div>
<script src="script.js"></script>
<script>
generisiKviz(mojaPitanja, quizContainer, rezContainer, posaljiDugme);
</script>
I'm trying to use Math.floor(Math.random() but I'm lost. Any suggestions about the best approach here please? :)
Thanks!
Math.random() gives you a number between 0 and 1, so if you want a number between 0 and 9 (for the index of the question list), you multiply this by 10 (to get a number between 0 and 10) and use Math.floor() to remove decimals and the possiblility of getting a ten. The code could look something like this:
your_questions_list = [...]
let chosen_questions = []
for (let i = 0; i < 5; i++) {
let index = Math.floor(Math.random() * 10)
while (chosen_questions.includes(index)){
index = Math.floor(Math.random() * 10)
}
chosen_questions.push(i)
}
// and now to populate the list with actual questions
for (let i = 0; i < chosen_questions.length; i++) {
chosen_questions[i] = your_questions_list[chosen_questions[i]];
}
console.log(chosen_questions);
This will give you a list (chosen_questions) of 5 random questions from the list of questions
Even better, to adapt to a varying question list size you could use the .length property of a list like this:
let index = Math.floor(Math.random() * your_questions_list.length))
Update:
Here's very short way of doing it (method is from comment above):
const shuffled = your_questions_list.sort(() => 0.5 - Math.random());
let selected = shuffled.slice(0, 5); // 5 is number of questions
I guess shuffling is an option. But simple and logical would be to loop to 5 keeping randomizing an item which hasn't been chosen before.
questions = 10 // 1 based
pick = 5
chosen = [];
for (var i = 0; i < pick; i++) {
do {
r = Math.trunc(Math.random() * 10) + 1 // or other random function
} while (chosen.indexOf(r) > -1)
chosen.push(r)
}
console.log(chosen)
if you can help me show the order of the random answers.
example in question 1 Who is really a chef? Respond, 'Monica', 'Chandler', 'Rachel', 'Ross' I want those responses to be displayed randomly as' Chandler', 'Ross'' Rachel ',' Monica 'or' Monica ',' Rachel ',' Ross', 'Chandler'
another example
"How many types of towels does Monica have?"
["3", "8", "11", "6"] I would like the answers to the question to appear disordered ["8", "3", "6", "11"] or ["6", "11", "8", "3"]
$(document).ready(function() {
$("#remaining-time").hide();
$("#start").on("click", trivia.startGame);
$(document).on("click", ".option", trivia.guessChecker);
});
var trivia = {
correct: 0,
incorrect: 0,
unanswered: 0,
currentSet: 0,
// "seen" property will keep track of the seen questions so we don't re-display them again
seen: [],
// Update: limit the number of question per game. Usong a property so you can change its value whenever you want to change the limit
limit: 4,
timer: 20,
timerOn: false,
timerId: "",
// questions options and answers data
questions: {
q1: "Who is actually a chef?",
q2: "What does Joey love to eat?",
q3: "How many times has Ross been divorced?",
q4: "How many types of towels does Monica have?",
q5: "Who stole Monica's thunder after she got engaged?",
q6: "Who hates Thanksgiving?",
q7: "Who thinks they're always the last to find out everything?"
},
options: {
q1: ["Monica", "Chandler", "Rachel", "Ross"],
q2: ["Fish", "Apples", "Oranges", "Sandwhiches"],
q3: ["5", "2", "1", "3"],
q4: ["3", "8", "11", "6"],
q5: ["Rachel", "Phoebe", "Emily", "Carol"],
q6: ["Joey", "Chandler", "Rachel", "Ross"],
q7: ["Ross", "Phoebe", "Monica", "Chandler"]
},
answers: {
q1: "Monica",
q2: "Sandwhiches",
q3: "3",
q4: "11",
q5: "Rachel",
q6: "Chandler",
q7: "Phoebe"
},
// random number generator
random: (min, max) => Math.floor(Math.random() * (max - min + 1)) + min,
startGame: function() {
trivia.currentSet = 0;
// set "seen" to an empty array for a new game
trivia.seen = [];
trivia.correct = 0;
trivia.incorrect = 0;
trivia.unanswered = 0;
clearInterval(trivia.timerId);
$("#game").show();
$("#results").html("");
$("#timer").text(trivia.timer);
$("#start").hide();
$("#remaining-time").show();
trivia.nextQuestion();
},
nextQuestion: function() {
trivia.timer = 10;
$("#timer").removeClass("last-seconds");
$("#timer").text(trivia.timer);
if (!trivia.timerOn) {
trivia.timerId = setInterval(trivia.timerRunning, 1000);
}
// get all the questions
const qts = Object.values(trivia.questions);
// init the random number
let rq = null;
// firstly, if no more questions to show set rq to -1 to let us know later that the game has finished
// Update: checking if we reached the "limit"
if (trivia.seen.length >= trivia.limit) rq = -1
else {
// otherwise generate a random number from 0 inclusive to the length of the questions - 1 (as array indexing starts from 0 in JS) also inclusive
do {
// generate a random number using the newly added "random" method
rq = trivia.random(0, qts.length - 1);
} while (trivia.seen.indexOf(rq) != -1); // if the question is already seen then genrate another number, do that till we get a non-seen question index
// add that randomly generated index to the seen array so we know that we have already seen it
trivia.seen.push(rq);
// increment the counter
trivia.counter++;
}
// current question index is the generated random number "rq"
trivia.currentSet = rq;
var questionContent = Object.values(trivia.questions)[rq];
$("#question").text(questionContent);
var questionOptions = Object.values(trivia.options)[trivia.currentSet];
$.each(questionOptions, function(index, key) {
$("#options").append(
$('<button class="option btn btn-info btn-lg">' + key + "</button>")
);
});
},
timerRunning: function() {
if (
trivia.timer > -1 &&
// all the questions have already been seen
// Update: now we check against the limit property
trivia.seen.length < trivia.limit
) {
$("#timer").text(trivia.timer);
trivia.timer--;
if (trivia.timer === 4) {
$("#timer").addClass("last-seconds");
}
} else if (trivia.timer === -1) {
trivia.unanswered++;
trivia.result = false;
clearInterval(trivia.timerId);
resultId = setTimeout(trivia.guessResult, 1000);
$("#results").html(
"<h3>Out of time! The answer was " +
Object.values(trivia.answers)[trivia.currentSet] +
"</h3>"
);
}
// if the game ended as we know that -1 means no more questions to display
else if (trivia.currentSet === -1) {
$("#results").html(
"<h3>Thank you for playing!</h3>" +
"<p>Correct: " +
trivia.correct +
"</p>" +
"<p>Incorrect: " +
trivia.incorrect +
"</p>" +
"<p>Unaswered: " +
trivia.unanswered +
"</p>" +
"<p>Please play again!</p>"
);
$("#game").hide();
$("#start").show();
}
},
guessChecker: function() {
var resultId;
var currentAnswer = Object.values(trivia.answers)[trivia.currentSet];
if ($(this).text() === currentAnswer) {
//turn button green for correct
$(this).addClass("btn-success").removeClass("btn-info");
trivia.correct++;
clearInterval(trivia.timerId);
resultId = setTimeout(trivia.guessResult, 1000);
$("#results").html("<h3>Correct Answer!</h3>");
} else {
$(this).addClass("btn-danger").removeClass("btn-info");
trivia.incorrect++;
clearInterval(trivia.timerId);
resultId = setTimeout(trivia.guessResult, 1000);
$("#results").html(
"<h3>Better luck next time! " + currentAnswer + "</h3>"
);
}
},
guessResult: function() {
// no need to increment trivia.currentSet anymore
$(".option").remove();
$("#results h3").remove();
trivia.nextQuestion();
}
};
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="header text-center clearfix">
<h1 class="text-muted">Friends trivia game</h1>
</div>
<div class="jumbotron jumbotron-fluid">
<div class="container">
<div id="game">
<h2>FRIENDS Trivia Game</h2>
<p id="remaining-time" class="lead">Remaining Time: <span id="timer"></span></p>
<p id="question" class="lead"></p>
</div>
<div id="results">
</div>
</div>
<div class="row">
<div id="choices" class="text-center">
<button id="start" class="btn btn-info btn-lg">Start Game</button>
<div id="options">
</div>
</div>
</div>
</div>
<!-- /container -->
Just an Array.sort with a Math.random callback to shuffle your array of option should be enough like so:
$(document).ready(function() {
$("#remaining-time").hide();
$("#start").on("click", trivia.startGame);
$(document).on("click", ".option", trivia.guessChecker);
});
var trivia = {
correct: 0,
incorrect: 0,
unanswered: 0,
currentSet: 0,
// "seen" property will keep track of the seen questions so we don't re-display them again
seen: [],
// Update: limit the number of question per game. Usong a property so you can change its value whenever you want to change the limit
limit: 4,
timer: 20,
timerOn: false,
timerId: "",
// questions options and answers data
questions: {
q1: "Who is actually a chef?",
q2: "What does Joey love to eat?",
q3: "How many times has Ross been divorced?",
q4: "How many types of towels does Monica have?",
q5: "Who stole Monica's thunder after she got engaged?",
q6: "Who hates Thanksgiving?",
q7: "Who thinks they're always the last to find out everything?"
},
options: {
q1: ["Monica", "Chandler", "Rachel", "Ross"],
q2: ["Fish", "Apples", "Oranges", "Sandwhiches"],
q3: ["5", "2", "1", "3"],
q4: ["3", "8", "11", "6"],
q5: ["Rachel", "Phoebe", "Emily", "Carol"],
q6: ["Joey", "Chandler", "Rachel", "Ross"],
q7: ["Ross", "Phoebe", "Monica", "Chandler"]
},
answers: {
q1: "Monica",
q2: "Sandwhiches",
q3: "3",
q4: "11",
q5: "Rachel",
q6: "Chandler",
q7: "Phoebe"
},
// random number generator
random: (min, max) => Math.floor(Math.random() * (max - min + 1)) + min,
startGame: function() {
trivia.currentSet = 0;
// set "seen" to an empty array for a new game
trivia.seen = [];
trivia.correct = 0;
trivia.incorrect = 0;
trivia.unanswered = 0;
clearInterval(trivia.timerId);
$("#game").show();
$("#results").html("");
$("#timer").text(trivia.timer);
$("#start").hide();
$("#remaining-time").show();
trivia.nextQuestion();
},
nextQuestion: function() {
trivia.timer = 10;
$("#timer").removeClass("last-seconds");
$("#timer").text(trivia.timer);
if (!trivia.timerOn) {
trivia.timerId = setInterval(trivia.timerRunning, 1000);
}
// get all the questions
const qts = Object.values(trivia.questions);
// init the random number
let rq = null;
// firstly, if no more questions to show set rq to -1 to let us know later that the game has finished
// Update: checking if we reached the "limit"
if (trivia.seen.length >= trivia.limit) rq = -1
else {
// otherwise generate a random number from 0 inclusive to the length of the questions - 1 (as array indexing starts from 0 in JS) also inclusive
do {
// generate a random number using the newly added "random" method
rq = trivia.random(0, qts.length - 1);
} while (trivia.seen.indexOf(rq) != -1); // if the question is already seen then genrate another number, do that till we get a non-seen question index
// add that randomly generated index to the seen array so we know that we have already seen it
trivia.seen.push(rq);
// increment the counter
trivia.counter++;
}
// current question index is the generated random number "rq"
trivia.currentSet = rq;
var questionContent = Object.values(trivia.questions)[rq];
$("#question").text(questionContent);
var questionOptions = Object.values(trivia.options)[trivia.currentSet];
//Array Sorted randomly
if(questionOptions){
questionOptions = questionOptions.sort(() => Math.random() - 0.5);
}
$.each(questionOptions, function(index, key) {
$("#options").append(
$('<button class="option btn btn-info btn-lg">' + key + "</button>")
);
});
},
timerRunning: function() {
if (
trivia.timer > -1 &&
// all the questions have already been seen
// Update: now we check against the limit property
trivia.seen.length < trivia.limit
) {
$("#timer").text(trivia.timer);
trivia.timer--;
if (trivia.timer === 4) {
$("#timer").addClass("last-seconds");
}
} else if (trivia.timer === -1) {
trivia.unanswered++;
trivia.result = false;
clearInterval(trivia.timerId);
resultId = setTimeout(trivia.guessResult, 1000);
$("#results").html(
"<h3>Out of time! The answer was " +
Object.values(trivia.answers)[trivia.currentSet] +
"</h3>"
);
}
// if the game ended as we know that -1 means no more questions to display
else if (trivia.currentSet === -1) {
$("#results").html(
"<h3>Thank you for playing!</h3>" +
"<p>Correct: " +
trivia.correct +
"</p>" +
"<p>Incorrect: " +
trivia.incorrect +
"</p>" +
"<p>Unaswered: " +
trivia.unanswered +
"</p>" +
"<p>Please play again!</p>"
);
$("#game").hide();
$("#start").show();
}
},
guessChecker: function() {
var resultId;
var currentAnswer = Object.values(trivia.answers)[trivia.currentSet];
if ($(this).text() === currentAnswer) {
//turn button green for correct
$(this).addClass("btn-success").removeClass("btn-info");
trivia.correct++;
clearInterval(trivia.timerId);
resultId = setTimeout(trivia.guessResult, 1000);
$("#results").html("<h3>Correct Answer!</h3>");
} else {
$(this).addClass("btn-danger").removeClass("btn-info");
trivia.incorrect++;
clearInterval(trivia.timerId);
resultId = setTimeout(trivia.guessResult, 1000);
$("#results").html(
"<h3>Better luck next time! " + currentAnswer + "</h3>"
);
}
},
guessResult: function() {
// no need to increment trivia.currentSet anymore
$(".option").remove();
$("#results h3").remove();
trivia.nextQuestion();
}
};
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="header text-center clearfix">
<h1 class="text-muted">Friends trivia game</h1>
</div>
<div class="jumbotron jumbotron-fluid">
<div class="container">
<div id="game">
<h2>FRIENDS Trivia Game</h2>
<p id="remaining-time" class="lead">Remaining Time: <span id="timer"></span></p>
<p id="question" class="lead"></p>
</div>
<div id="results">
</div>
</div>
<div class="row">
<div id="choices" class="text-center">
<button id="start" class="btn btn-info btn-lg">Start Game</button>
<div id="options">
</div>
</div>
</div>
</div>
<!-- /container -->
$(document).ready(function() {
$("#remaining-time").hide();
$("#start").on("click", trivia.startGame);
$(document).on("click", ".option", trivia.guessChecker);
});
var trivia = {
correct: 0,
incorrect: 0,
unanswered: 0,
currentSet: 0,
// "seen" property will keep track of the seen questions so we don't re-display them again
seen: [],
// Update: limit the number of question per game. Usong a property so you can change its value whenever you want to change the limit
limit: 4,
timer: 20,
timerOn: false,
timerId: "",
// questions options and answers data
questions: {
q1: "Who is actually a chef?",
q2: "What does Joey love to eat?",
q3: "How many times has Ross been divorced?",
q4: "How many types of towels does Monica have?",
q5: "Who stole Monica's thunder after she got engaged?",
q6: "Who hates Thanksgiving?",
q7: "Who thinks they're always the last to find out everything?"
},
options: {
q1: ["Monica", "Chandler", "Rachel", "Ross"],
q2: ["Fish", "Apples", "Oranges", "Sandwhiches"],
q3: ["5", "2", "1", "3"],
q4: ["3", "8", "11", "6"],
q5: ["Rachel", "Phoebe", "Emily", "Carol"],
q6: ["Joey", "Chandler", "Rachel", "Ross"],
q7: ["Ross", "Phoebe", "Monica", "Chandler"]
},
answers: {
q1: "Monica",
q2: "Sandwhiches",
q3: "3",
q4: "11",
q5: "Rachel",
q6: "Chandler",
q7: "Phoebe"
},
// random number generator
random: (min, max) => Math.floor(Math.random() * (max - min + 1)) + min,
startGame: function() {
trivia.currentSet = 0;
// set "seen" to an empty array for a new game
trivia.seen = [];
trivia.correct = 0;
trivia.incorrect = 0;
trivia.unanswered = 0;
clearInterval(trivia.timerId);
$("#game").show();
$("#results").html("");
$("#timer").text(trivia.timer);
$("#start").hide();
$("#remaining-time").show();
trivia.nextQuestion();
},
nextQuestion: function() {
trivia.timer = 10;
$("#timer").removeClass("last-seconds");
$("#timer").text(trivia.timer);
if (!trivia.timerOn) {
trivia.timerId = setInterval(trivia.timerRunning, 1000);
}
// get all the questions
const qts = Object.values(trivia.questions);
// init the random number
let rq = null;
// firstly, if no more questions to show set rq to -1 to let us know later that the game has finished
// Update: checking if we reached the "limit"
if (trivia.seen.length >= trivia.limit) rq = -1
else {
// otherwise generate a random number from 0 inclusive to the length of the questions - 1 (as array indexing starts from 0 in JS) also inclusive
do {
// generate a random number using the newly added "random" method
rq = trivia.random(0, qts.length - 1);
} while (trivia.seen.indexOf(rq) != -1); // if the question is already seen then genrate another number, do that till we get a non-seen question index
// add that randomly generated index to the seen array so we know that we have already seen it
trivia.seen.push(rq);
// increment the counter
trivia.counter++;
}
// current question index is the generated random number "rq"
trivia.currentSet = rq;
var questionContent = Object.values(trivia.questions)[rq];
$("#question").text(questionContent);
var questionOptions = Object.values(trivia.options)[trivia.currentSet];
questionOptions =randomSort(questionOptions);
$.each(questionOptions, function(index, key) {
$("#options").append(
$('<button class="option btn btn-info btn-lg">' + key + "</button>")
);
});
},
timerRunning: function() {
if (
trivia.timer > -1 &&
// all the questions have already been seen
// Update: now we check against the limit property
trivia.seen.length < trivia.limit
) {
$("#timer").text(trivia.timer);
trivia.timer--;
if (trivia.timer === 4) {
$("#timer").addClass("last-seconds");
}
} else if (trivia.timer === -1) {
trivia.unanswered++;
trivia.result = false;
clearInterval(trivia.timerId);
resultId = setTimeout(trivia.guessResult, 1000);
$("#results").html(
"<h3>Out of time! The answer was " +
Object.values(trivia.answers)[trivia.currentSet] +
"</h3>"
);
}
// if the game ended as we know that -1 means no more questions to display
else if (trivia.currentSet === -1) {
$("#results").html(
"<h3>Thank you for playing!</h3>" +
"<p>Correct: " +
trivia.correct +
"</p>" +
"<p>Incorrect: " +
trivia.incorrect +
"</p>" +
"<p>Unaswered: " +
trivia.unanswered +
"</p>" +
"<p>Please play again!</p>"
);
$("#game").hide();
$("#start").show();
}
},
guessChecker: function() {
var resultId;
var currentAnswer = Object.values(trivia.answers)[trivia.currentSet];
if ($(this).text() === currentAnswer) {
//turn button green for correct
$(this).addClass("btn-success").removeClass("btn-info");
trivia.correct++;
clearInterval(trivia.timerId);
resultId = setTimeout(trivia.guessResult, 1000);
$("#results").html("<h3>Correct Answer!</h3>");
} else {
$(this).addClass("btn-danger").removeClass("btn-info");
trivia.incorrect++;
clearInterval(trivia.timerId);
resultId = setTimeout(trivia.guessResult, 1000);
$("#results").html(
"<h3>Better luck next time! " + currentAnswer + "</h3>"
);
}
},
guessResult: function() {
// no need to increment trivia.currentSet anymore
$(".option").remove();
$("#results h3").remove();
trivia.nextQuestion();
}
}
function randomSort(myArray){
if (typeof(myArray)=='undefined')return myArray;
var bucket = [];
for(var i=0;i<myArray.length;i++){
bucket.push(i);
}
var sort =[];
while(sort.length < bucket.length){
var ri = parseInt(Math.floor(Math.random()*bucket.length));
if(bucket[ri] == ri){
bucket[ri] = 'abc';
sort.push(ri);
}
}
var newArray=[];
for(let i = 0;i<myArray.length;i++){
newArray[i] = myArray[sort[i]];
}
return newArray;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="header text-center clearfix">
<h1 class="text-muted">Friends trivia game</h1>
</div>
<div class="jumbotron jumbotron-fluid">
<div class="container">
<div id="game">
<h2>FRIENDS Trivia Game</h2>
<p id="remaining-time" class="lead">Remaining Time: <span id="timer"></span></p>
<p id="question" class="lead"></p>
</div>
<div id="results">
</div>
</div>
<div class="row">
<div id="choices" class="text-center">
<button id="start" class="btn btn-info btn-lg">Start Game</button>
<div id="options">
</div>
</div>
</div>
</div>
<!-- /container -->
I am trying to make a quizz with random questions. I would like each question to be accompanied by a sound clip that plays automatically as soon as the question is shown. I would also like to have a button that makes it possible for the user to replay the sound clip. How can I achieve this, exactly?
I know how to play individual audio clips with audioClips.play();.
But how about playing audio clips from an array, "synchronized" with the questions?
This is what I have so far:
var country = ["Italy", "Spain", "Portugal", "France", "Greece", "Ireland", "Germany"];
var audioClips = ["italy.mp3", "spain.mp3", "portugal.mp3", "france.mp3", "greece.mp3", "ireland.mp3", "germany.mp3"];
var capital = ["rome", "madrid", "lisbon", "paris", "athens", "dublin", "berlin"];
var random001 = Math.floor(Math.random() * country.length);
document.getElementById("country").textContent = country[random001];
function submit001() {
var b = input001.value.toLowerCase();
var text;
if (b === capital[random001]) {
goToNextQuestion();
text = "Correct!";
} else {
text = input001.value.bold() + " is not correct!";
}
document.getElementById("input001").value = "";
document.getElementById("answer001").innerHTML = text;
}
function goToNextQuestion() {
document.getElementById("answer001").innerHTML = "";
random001 = Math.floor(Math.random() * country.length);
document.getElementById("country").innerHTML = country[random001];
document.getElementById("input001").focus();
}
<p id="message001">What is the capital of <text id="country"></text>?</p>
<input type="text" id="input001" autofocus onKeyDown="if(event.keyCode==13) submit001()">
<p id="answer001"></p>
<button onclick="playAudio()" type="button">Replay Audio</button>
With this problem you're thinking in terms of Arrays and you need to think in terms of Objects. Combine the related information into an Object and you can accomplish your goal with clear, easy-to-read code.
To make this work I had to extensively refactor your code. Here's what I came up with.
HTML
<head>
<style>
#startButton {
display: block;
}
#quiz {
display: none;
}
</style>
</head>
<body>
<div id="startButton">
<button type="button" onclick="startQuiz()">Start Quiz</button>
</div>
<div id="quiz">
<p id="message001">What is the capital of <text id="country"></text>?</p>
<input type="text" id="input001" autofocus onKeyDown="if(event.keyCode==13) checkAnswer()" value="">
<p id="answer001"></p>
<button id="replayButton" type="button" onclick="setAudio()">Replay Audio</button>
</div>
</body>
Javascript
<script>
var country = {
"Italy": {
"audio": "italy.mp3",
"capital": "rome"
},
"Spain": {
"audio": "spain.mp3",
"capital": "madrid"
},
"Portugal": {
"audio": "portugal.mp3",
"capital": "lisbon"
},
"France": {
"audio": "france.mp3",
"capital": "paris"
},
"Greece": {
"audio": "greece.mp3",
"capital": "athens"
},
"Ireland": {
"audio": "ireland.mp3",
"capital": "dublin"
},
"Germany": {
"audio": "germany.mp3",
"capital": "berlin"
}
};
var countryArray = Object.keys(country);
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function nextCountryName(){
let randIndex = getRandomInt(1, countryArray.length) - 1;
return countryArray[randIndex];
};
function playAudio(file){
let playFile = new Audio(file);
playFile.play();
}
function newCountry(newCountryName) {
document.getElementById("country").textContent = newCountryName;
document.getElementById("input001").value = "";
}
function isAnswerCorrect(answer, useCountry) {
let answerId = document.getElementById("answer001");
let ans = answer.toLowerCase();
let text;
if(ans == country[useCountry].capital){
answerId.innerHTML = "Correct!";
return true;
} else {
answerId.innerHTML = ans.bold() + " is not correct!";
return false;
}
};
function setAudio(){
let thisCountry = document.getElementById("country").textContent;
let audioFile = country[thisCountry].audio;
let callStr = "playAudio(\'" + audioFile + "\')";
document.getElementById('replayButton').setAttribute('onclick', callStr);
}
function checkAnswer(){
let inputId = document.getElementById('input001');
let answer = inputId.value;
let thisCountry = document.getElementById("country").textContent;
let audioFile = country[thisCountry].audio;
let result = isAnswerCorrect(answer, thisCountry);
if(result) {
let cntryName = nextCountryName();
newCountry(cntryName);
playAudio(country[cntryName].audio);
}
};
function startQuiz(){
let startingCountry = nextCountryName();
newCountry(startingCountry);
document.getElementById('startButton').style.display = "none";
document.getElementById('quiz').style.display = "block";
playAudio(country[startingCountry].audio);
};
</script>
I converted var country, var audioClips, and var capital arrays into a single Object named var country. This way you can use country.capital or country.audio to get the value you're looking for.
According to this answer it is suggested that you set the audio file type new Audio("file_name") before calling the .play() method.
While answer002, answer003, input002, input003, etc is beyond the scope of your question this code could be easily modified accept such parameters to account for a more extensive quiz.
function playAudio() {
// if you know how to play audio then follow these step
//1. get file name from audioClips array at index randome001 like
audioClip = audioClips[random001]
// do whatever you need to do before playing audio like loading audio file or whatever
//2. play audioClip.
}`
I am currently making a quiz in Javascript that randomizes questions and answers. I have the questions randomizing but how do I add the answers to go along with a certain question? I also want each answer to be placed in a div of its own, like so: http://imgur.com/a/l9w9j
Here's the code I have so far:
var display = document.getElementById("questions");
var questions = ['What is the weather like?',
'What time of day is it?',
'Whats your favourite music?',
'Which season is your favourite?',
'What colour are your eyes?'];
var questionTracker = [];
var questionAmount = 1;
// Iterate however many times
for (var i = 0; i < questionAmount; i++) {
// Keep creating random numbers until the number is unique
do {
var randomQuestion = Math.floor(Math.random() * questions.length);
} while (existingQuestions());
display.innerHTML += questions[randomQuestion] + '<br>';
// Add the question to the tracker
questionTracker.push(randomQuestion);
}
// If the current random number already exists in the tracker, return true
function existingQuestions() {
for (var i = 0; i < questionTracker.length; i++) {
if (questionTracker[i] === randomQuestion) {
return true;
}
}
return false;
}
And my HTML:
<div id="questions">
</div>
<div id="answers">
<div class="answers-left">
<div class="answer1" tabIndex="1">Sunny</div>
<div class="answer2" tabIndex="2">Raining</div>
</div>
<div class="answers-right">
<div class="answer3" tabIndex="3">Cloudy</div>
<div class="answer4" tabIndex="4">Windy</div>
</div>
<div class="clear"></div>
</div>
Her you can use of object instead of array
var questionData= {
"questions":[
{
"question":"this is hard question to answer",
"answers":[
"yes","no","why not","none"
]
},
{
"question":"this is 2nd hard question to answer",
"answers":[
"yes","no","why not","none"
]
}
]
}
questionData.map(function(question){
//Here you can write the dom structure that you like
})
You can store your questions and answers inside an array of objects
Each object hold a question and an answers property. answers is an array that contains each possible answers.
The following code will take a random question using Math.random() to find a random index. With this index, you can select the object in the array and then select the question and answers.
I added some CSS to add the desired effect. This can be improved with the colors/size/margins/... you want
var questionElement = document.getElementById("questions");
var answersElements = document.getElementsByClassName("answer");
var data = [{
question: 'What is the weather like?',
answers: ['Sunny', 'Raining', 'Cloudy', 'Windy']
}, {
question: 'What time of day is it?',
answers: ['Morning', 'Lunch', 'Evening', 'Night']
}];
var randomIndex = Math.floor(Math.random() * data.length);
questionElement.innerHTML = data[randomIndex].question;
for (let i = 0; i < answersElements.length; i++) {
answersElements[i].innerHTML = data[randomIndex].answers[i];
}
.answer {
display: inline-block;
background-color: #00BCD4;
margin: 1em;
}
<div id="questions">
</div>
<div id="answers">
<div class="answers-left">
<div class="answer" tabIndex="1">Sunny</div>
<div class="answer" tabIndex="2">Raining</div>
</div>
<div class="answers-right">
<div class="answer" tabIndex="3">Cloudy</div>
<div class="answer" tabIndex="4">Windy</div>
</div>
<div class="clear"></div>
</div>
Why not add the answers to the questions in an object array?
var display = document.getElementById("questions");
var answers = document.getElementById("answers");
var answersLeft = document.getElementById("answers-left");
var answersRight = document.getElementById("answers-right");
var questions = [{
"q": "What is the weather like?",
"a": [
"Sunny",
"Raining",
"Cloudy",
"Windy"
]
},
{
"q": "What time of day is it?",
"a": [
"Sunny",
"Raining",
"Cloudy",
"Windy"
]
},
{
"q": "Whats your favourite music?",
"a": [
"Sunny",
"Raining",
"Cloudy",
"Windy"
]
},
{
"q": "Which season is your favourite?",
"a": [
"Sunny",
"Raining",
"Cloudy",
"Windy"
]
},
{
"q": "What colour are your eyes?",
"a": [
"Sunny",
"Raining",
"Cloudy",
"Windy"
]
}
];
var questionTracker = [];
var questionAmount = 1;
// Iterate however many times
for (var i = 0; i < questionAmount; i++) {
// Keep creating random numbers until the number is unique
do {
var randomQuestion = Math.floor(Math.random() * questions.length);
} while (existingQuestions());
display.innerHTML += questions[randomQuestion].q + '<br>';
var answersToQ = questions[randomQuestion].a;
for (var j = 0; j < answersToQ.length; j++) {
var answer = "<p>" + answersToQ[j] + "</p>";
if (j % 2 === 0) {
answersLeft.innerHTML += answer;
} else {
answersRight.innerHTML += answer;
}
}
// Add the question to the tracker
questionTracker.push(randomQuestion);
}
// If the current random number already exists in the tracker, return true
function existingQuestions() {
for (var i = 0; i < questionTracker.length; i++) {
if (questionTracker[i] === randomQuestion) {
return true;
}
}
return false;
}
<style type="text/css">
#answers-left {
position: relative;
float: left;
width: 50%;
}
#answers-right {
position: relative;
float: right;
width: 50%;
}
#answers p {
background-color: blue;
width: 50%;
text-align: center;
color: #fff;
cursor: pointer;
}
</style>
<div id="questions">
</div>
<div id="answers">
<div id="answers-left">
</div>
<div id="answers-right">
</div>
</div>
Here is example that i made for you with following code.
Sorry but i did not have time to make ccs rules, but you can see that questions are mixed and answers for them all mixed all so.
http://devel.vis25.com/test.php
I recommend you to use something like this, for my example you will need Jquery and Jquery templates
Here is link to Jquery download jquery tempaltes
Here is example of you'r tempaltes and html.
<html>
<head>
<script src="https://devel.vis25.com//Vendors/JqueryUI/external/jquery/jquery.js"></script>
<script src="http://devel.vis25.com/Vendors/jquery.tmpl.min.js"></script>
</head>
<body onload="RenderQuestions();">
<div id="Questions"></div>
<script id="Question-Tempalte" type="text/x-jQuery-tmpl">
<div class="Question" id=question-"${ID}">
<div class="Question-text">${QuestionText}</div>
<div class="Question-answer-container" id="Question-answer-container-${ID}"></div>
</div>
</script>
<script id="Answer-Tempalte" type="text/x-jQuery-tmpl">
<div class="answer" id="answer-${ID}">
<div class="answer-text" tabIndex="${ID}">${answerText}</div>
</div>
</script>
</body>
</html>
with javascript do something like this.
//Function that is called in body 'onload' event.
function RenderQuestions(){
//Array of you'r questions as json objects
var questions = [
{ ID : '1', QuestionText : 'What is the weather like?' },
{ ID : '2', QuestionText : 'What time of day is it?' },
{ ID : '3', QuestionText : 'Whats your favourite music?' },
{ ID : '4', QuestionText : 'Which season is your favourite?' },
{ ID : '5', QuestionText : 'What colour are your eyes?' },
];
//Call shuffle function for your questions, so they are mixed randomly.
var ShuffledQuestions = shuffle( questions );
//Loop true all of your questions and render them inside of your questions <div>
//Allso call functions 'RenderAnswers()' by question id value[ 'ID' ].
$.each(ShuffledQuestions, function(index, value){
$( '#Question-Tempalte' ).tmpl( value ).appendTo( '#Questions' );
RenderAnswers( value[ 'ID' ] );
});
}
//Shuffle function return randomly mixed array.
function shuffle( array ) {
var currentIndex = array.length, temporaryValue, randomIndex;
while (0 !== currentIndex) {
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;
temporaryValue = array[currentIndex];
array[currentIndex] = array[randomIndex];
array[randomIndex] = temporaryValue;
}
return array;
}
//RenderAnswers function takes QuestionID as argument so we can render answer elements for right questions, and we have right answers.
function RenderAnswers( QuestionID ){
var Answers = [];
//Check which question are we rendering.
//Answers for question ID 1 ( 'What is the weather like?' ).
if( QuestionID == 1){
Answers = [
{ AnswersID : 1 , answerText : 'Sunny' },
{ AnswersID : 2 , answerText : 'Raining'},
{ AnswersID : 3 , answerText : 'Cloudy'},
{ AnswersID : 4 , answerText : 'Windy'},
];
}
//Answers for question ID 2 ( 'What time of day is it?' ).
if( QuestionID == 2){
Answers = [
{ AnswersID : 1 , answerText : '8:00' },
{ AnswersID : 2 , answerText : '12:00'},
{ AnswersID : 3 , answerText : '18:00'},
{ AnswersID : 4 , answerText : '00:00'},
];
}
//Answers for question ID 3 ( 'Whats your favourite music?' ).
if( QuestionID == 3){
Answers = [
{ AnswersID : 1 , answerText : 'Rock' },
{ AnswersID : 2 , answerText : 'pop'},
{ AnswersID : 3 , answerText : 'rap'},
{ AnswersID : 4 , answerText : 'EDM'},
];
}
//Answers for question ID 4 ( 'Which season is your favourite?' ).
if( QuestionID == 4){
Answers = [
{ AnswersID : 1 , answerText : 'Summer' },
{ AnswersID : 2 , answerText : 'Winter'},
{ AnswersID : 3 , answerText : ''},
{ AnswersID : 4 , answerText : ''},
];
}
//Answers for question ID 5 ( 'What colour are your eyes?' ).
if( QuestionID == 4){
Answers = [
{ AnswersID : 1 , answerText : 'blue' },
{ AnswersID : 2 , answerText : 'brown'},
{ AnswersID : 3 , answerText : 'green'},
{ AnswersID : 4 , answerText : ''},
];
}
//Shuffle answers.
var ShuffledAnswers = shuffle( Answers );
//Renders answer elements for question.
$( '#Answer-Tempalte' ).tmpl( ShuffledAnswers ).appendTo( '#Question-answer-container-'+QuestionID );
}
Hope i was able to help you, and feel free to ask anything is i did not understand your question right !
Best regards,
Vis25
I'd like to change the value of a <h2> with its id within a "on" function but it doesn't change.
Here's the code:
<div id="boardGame">
</div>
<script type="text/javascript">
json_dic = {"Too Much to Ask": "oHRjgi6sniY", "Sketchead": "GEfpkuCPjXs", "If You Were There, Beware": "ZVOwOzL9uDQ", "Plastic Tramp": "BiVXU2jt1Xo", "The Death Ramps": "p7cijGnXUJM", "Don't Sit Down 'Cause I've Moved Your Chair": "h1vYbHHhqYE", "R U Mine?": "VQH8ZTgna3Q", "2013": "O4vkZUC4VPA", "The Bakery": "P_D1Eqa2Lk4", "Potion Approaching": "Urw780t52zc", "Still Take You Home": "FKPKSK1nCKY", "Chun-Li's Spinning Bird Kick": "4lOdBxVS16o", "Come Together": "a-5tTz8flYI", "Snap Out of It": "PHoSRT2fNME", "Cigarette Smoker Fiona": "Wg89x455WK4", "Why'd You Only Call Me When You're High?": "6366dxFf-Os", "Brick by Brick": "qOTRx3ZqjjI", "Temptation Greets You Like Your Naughty Friend ": "VEWNOzgnmq0", "The Blond-O-Sonic Shimmer Trap": "EyBrLYN2Yok", "The Bad Thing": "3xTHjLf-ONg", "All My Own Stunts": "Er3r_J-mwII", "Love Is a Laserquest": "wxQVpRSxOZ0", "Dance Little Liar": "hf-B3Y3B0TQ", "Mardy Bum": "Lp1fQ51YZMM", "Stickin' to the Floor": "AQVMJkZGpSc", "Only Ones Who Know": "m-seRFY7-cw", "Crying Lightning": "fLsBJPlGIDU", "From the Ritz to the Rubble ": "givRh52Ic3A", "I.D.S.T.": "V6yORYEiLyU", "She's Thunderstorms": "tvHz5Rti0cU", "Catapult": "U3LsJMLWN2k", "Stop the World I Wanna Get Off with You": "3PyoxMSEHYI", "The Hellcat Spangled Shalalala": "dAlRXC19hmE", "Do I Wanna Know?": "bpOSxM0rNPM", "Knee Socks": "00bk5E7gecI", "That's Where You're Wrong": "tLOUVbemjro", "Leave Before the Lights Come On": "SEukS2YN9B8", "I Want It All": "SDTxuAEPfdY", "Secret Door": "ibyGhbvo94Q", "Suck It and See": "rjFGapDkSM0", "7": "R2t6vgC_OWw", "Brianstorm": "30w8DyEJ__0", "Baby I'm Yours": "EDLhMf6voq8", "Arabella": "Nj8r3qmOoZ8", "Old Yellow Bricks": "xLaeOrDmWQ4", "Don't Forget Whose Legs You're On": "qL0Z3Ly0CEw", "Riot Van": "j052-ROwPFM", "What If You Were Right the First Time?": "t2cFvzmqmwc", "Fire and the Thud": "VGlhSSP4nTk", "I Wanna Be Yours": "Y4NGoS330HE", "Mad Sounds": "J_-FwyoeV3E", "Fireside": "PG8yTUeptFU", "The Afternoon's Hat": "qbNKclt42Xc", "Reckless Serenade": "PY2FQ-LgmYo", "No Buses": "WK4wISbGvJw", "Electricity": "g-cukZ10j8A", "Little Illusion Machine (Wirral Riddler) ": "WlMzuzud8U4", "Piledriver Waltz": "njirT4N-JxU", "When the Sun Goes Down": "EqkBRVukQmE", "No. 1 Party Anthem": "83hFiC-siDs", "Evil Twin": "xwir-pg7WiA", "This House Is a Circus": "oDB-MGsWzQQ", "I Haven't Got My Strange": "a9yrz_psfLc", "Black Treacle": "1wznj4lD1Bs", "505": "ifZfUVp2chE", "Dangerous Animals": "qHe3E366_Po", "Perhaps Vampires Is a Bit Strong But..": "SjzOUf0AEiQ", "Fluorescent Adolescent": "ma9I9VBKPiw", "Library Pictures": "bmVerkoFPJU", "The View from the Afternoon": "PeQAZsyucbQ", "Despair in the Departure Lounge": "ZLS8ffCYN80", "I Bet You Look Good on the Dancefloor": "pK7egZaT3hs", "Bigger Boys and Stolen Sweethearts": "rLkikLrImnk", "Balaclava": "6LBCqG0YnTM", "Fake Tales of San Francisco": "ePg1tbia9Bg", "D Is for Dangerous": "zOlhvxPC3MQ", "Put Your Dukes Up John": "O8Wuv1WKldk", "My Propeller": "Z5vZovv8cPk", "Red Right Hand": "hcvGOUuDGXc", "One for the Road": "qN7gSMPQFss", "Joining the Dots": "wkvUl_l3o1c", "Red Light Indicates Doors Are Secured": "hdmR58BIHOg", "You and I ": "9zXkAaoBOLU", "Teddy Picker": "2A2XBoxtcUA", "Settle for a Draw": "IQ7NH2jcAAw", "Bad Woman ": "YnkJHU3qYIA", "Cornerstone": "LIQz6zZi7R0", "Fright Lined Dining Room": "qrqtD4TiO5c", "A Certain Romance": "WGyj5JyA5Ms", "If You Found This It's Probably Too Late": "SqKl1vcmvOU", "Who the Fuck Are Arctic Monkeys?": "oFeuKVkau6U", "Do Me a Favour": "lXJEDlLepD4", "You Probably Couldn't See for the Lights but You Were Staring Straight at Me": "j8iV3tK717s", "Dancing Shoes": "3aQELo7tXyI", "The Jeweller's Hands": "1rq0Ag15sAI", "Matador/Da Frame 2R": "DxoPxvJ0FNM", "Pretty Visitors": "4n7iaY22Do0", "You're So Dark": "6eoAwXkI3RA"}
var score = 0
var nb = 0
var iter = 0
var song
var start
var click
var listSongs = []
getHome()
$(document).on("click", '.calc_btn', function() {
iter++
$("#valueIter").html(iter+"/10")
if(iter == 10)
{
gameOver(score)
}
else
{
click = new Date()
time = (click.getTime() - start.getTime())/1000
if($(this).val() == song){
if(time <= 15)
score += parseInt((-1000/14)*time+929)
$("#valueScore").html(score)
$("#valueScore").css( "color", "green" )
}
else
{
$("#valueScore").html(score)
$("#valueScore").css( "color", "red" )
}
nb += 1
getSong()
}
})
function getHome()
{
score = 0
iter = 0
listSongs = []
$("#boardGame").html("<h2>Welcome to The Game of Monkeys</h2><table class='calculatrice' id='calc'><tbody><tr><td class='calc_td_btn'><input type='button' class='stres' value='Start' onclick='getSong()'></td></tr></tbody></table")
}
function getSong()
{
var keys = [];
for (var prop in json_dic) {
if (json_dic.hasOwnProperty(prop)) {
keys.push(prop);
}
}
song = keys[ keys.length * Math.random() << 0 ];
listSongs = [ song ]
url = json_dic[song]
while(listSongs.length <= 4)
{
var keys = [];
for (var prop in json_dic) {
if (json_dic.hasOwnProperty(prop)) {
keys.push(prop);
}
}
song_random = keys[ keys.length * Math.random() << 0 ];
listSongs.push(song_random)
}
$("#boardGame").html('<table class="calculatrice" id="calc"> '+
'<tbody>' +
'<tr>' +
'<td class="calc_td_btn">' +
'<div style="position:relative;width:380px;height:25px;overflow:hidden;">' +
'<div id="yt_video" style="position:absolute;top:-276px;left:-5px">' +
'</div>' +
'</div>' +
'</td>' +
'</tr>');
for(var i = 0; i <= 4; i++)
{
var randomIndex = Math.floor(Math.random() * listSongs.length);
var randomString = listSongs[randomIndex];
$("#boardGame").append('<tr>'+
'<td class="calc_td_btn">' +
'<input type="button" class="calc_btn" value="'+randomString+'">' +
'</td>' +
'</tr>')
var index = listSongs.indexOf(randomString);
listSongs.splice(index, 1);
}
$("#boardGame").append('<tr>' +
'<td class="calc_td_btn">' +
'<h2 id="valueScore">0 points</h2>' +
'<h2 id="valueIter">0/10</h2>' +
'<input type="button" class="stres" onclick="getHome()" value="Restart">' +
'</td>' +
'</tr>' +
'</tbody>' +
'</table>')
var nb = getRandomInt(0,100)
$("#yt_video").html("<iframe src='https://www.youtube.com/embed/"+url+"?autoplay=0&start="+nb+"' id='yt_video' width='380' height='300'></iframe>")
start = new Date()
}
function getRandomInt (min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function gameOver(score){
$("#boardGame").html("<h2>You scored "+score+" points</h2><table class='calculatrice' id='calc'><tbody><tr><td class='calc_td_btn'><input type='button' onclick='getHome()' class='stres' value='Restart'></td></tr></tbody></table")
}
</script>
</body>
</html>
And it's the value of #valueScore that doesn't want to change. I think it it a scope problem but I can't get my way around it.
I can the value of #valueScore in the console or if I put the piece of code $("#valueScore").html(score) somewhere else in my JavaScript.
EDIT : added the whole code
The problem is that you're blowing away the DOM of all the elements at line 93-106 and you're re-creating them all. So the element that you're setting the score on is being destroyed and replaced with a completely different <h2>.
Instead of destroying everything (line 82 is where you replace the html of '#boardGame') you need to use JQuery to modify the buttons that already exist to give them the names of the song list.
As an alternative, try doing this:
Give all the multiple-choice buttons a class: '.choice_button'
Put a <div id="button_wrapper"> around all the buttons so that you have something to insert the new buttons into.
Instead of replacing the HTML for '#boardGame' simply destroy all the buttons: $('#button_wrapper .choice_button').remove()
Now you can insert the new buttons using that for loop just like you're doing on line 93
Now $('#valueScore') hasn't been blown away so the score should remain.
I've modified your code to get it to where I think it's what you're after:
<div id="boardGame">
</div>
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script type="text/javascript">
json_dic = {"Too Much to Ask": "oHRjgi6sniY", "Sketchead": "GEfpkuCPjXs", "If You Were There, Beware": "ZVOwOzL9uDQ", "Plastic Tramp": "BiVXU2jt1Xo", "The Death Ramps": "p7cijGnXUJM", "Don't Sit Down 'Cause I've Moved Your Chair": "h1vYbHHhqYE", "R U Mine?": "VQH8ZTgna3Q", "2013": "O4vkZUC4VPA", "The Bakery": "P_D1Eqa2Lk4", "Potion Approaching": "Urw780t52zc", "Still Take You Home": "FKPKSK1nCKY", "Chun-Li's Spinning Bird Kick": "4lOdBxVS16o", "Come Together": "a-5tTz8flYI", "Snap Out of It": "PHoSRT2fNME", "Cigarette Smoker Fiona": "Wg89x455WK4", "Why'd You Only Call Me When You're High?": "6366dxFf-Os", "Brick by Brick": "qOTRx3ZqjjI", "Temptation Greets You Like Your Naughty Friend ": "VEWNOzgnmq0", "The Blond-O-Sonic Shimmer Trap": "EyBrLYN2Yok", "The Bad Thing": "3xTHjLf-ONg", "All My Own Stunts": "Er3r_J-mwII", "Love Is a Laserquest": "wxQVpRSxOZ0", "Dance Little Liar": "hf-B3Y3B0TQ", "Mardy Bum": "Lp1fQ51YZMM", "Stickin' to the Floor": "AQVMJkZGpSc", "Only Ones Who Know": "m-seRFY7-cw", "Crying Lightning": "fLsBJPlGIDU", "From the Ritz to the Rubble ": "givRh52Ic3A", "I.D.S.T.": "V6yORYEiLyU", "She's Thunderstorms": "tvHz5Rti0cU", "Catapult": "U3LsJMLWN2k", "Stop the World I Wanna Get Off with You": "3PyoxMSEHYI", "The Hellcat Spangled Shalalala": "dAlRXC19hmE", "Do I Wanna Know?": "bpOSxM0rNPM", "Knee Socks": "00bk5E7gecI", "That's Where You're Wrong": "tLOUVbemjro", "Leave Before the Lights Come On": "SEukS2YN9B8", "I Want It All": "SDTxuAEPfdY", "Secret Door": "ibyGhbvo94Q", "Suck It and See": "rjFGapDkSM0", "7": "R2t6vgC_OWw", "Brianstorm": "30w8DyEJ__0", "Baby I'm Yours": "EDLhMf6voq8", "Arabella": "Nj8r3qmOoZ8", "Old Yellow Bricks": "xLaeOrDmWQ4", "Don't Forget Whose Legs You're On": "qL0Z3Ly0CEw", "Riot Van": "j052-ROwPFM", "What If You Were Right the First Time?": "t2cFvzmqmwc", "Fire and the Thud": "VGlhSSP4nTk", "I Wanna Be Yours": "Y4NGoS330HE", "Mad Sounds": "J_-FwyoeV3E", "Fireside": "PG8yTUeptFU", "The Afternoon's Hat": "qbNKclt42Xc", "Reckless Serenade": "PY2FQ-LgmYo", "No Buses": "WK4wISbGvJw", "Electricity": "g-cukZ10j8A", "Little Illusion Machine (Wirral Riddler) ": "WlMzuzud8U4", "Piledriver Waltz": "njirT4N-JxU", "When the Sun Goes Down": "EqkBRVukQmE", "No. 1 Party Anthem": "83hFiC-siDs", "Evil Twin": "xwir-pg7WiA", "This House Is a Circus": "oDB-MGsWzQQ", "I Haven't Got My Strange": "a9yrz_psfLc", "Black Treacle": "1wznj4lD1Bs", "505": "ifZfUVp2chE", "Dangerous Animals": "qHe3E366_Po", "Perhaps Vampires Is a Bit Strong But..": "SjzOUf0AEiQ", "Fluorescent Adolescent": "ma9I9VBKPiw", "Library Pictures": "bmVerkoFPJU", "The View from the Afternoon": "PeQAZsyucbQ", "Despair in the Departure Lounge": "ZLS8ffCYN80", "I Bet You Look Good on the Dancefloor": "pK7egZaT3hs", "Bigger Boys and Stolen Sweethearts": "rLkikLrImnk", "Balaclava": "6LBCqG0YnTM", "Fake Tales of San Francisco": "ePg1tbia9Bg", "D Is for Dangerous": "zOlhvxPC3MQ", "Put Your Dukes Up John": "O8Wuv1WKldk", "My Propeller": "Z5vZovv8cPk", "Red Right Hand": "hcvGOUuDGXc", "One for the Road": "qN7gSMPQFss", "Joining the Dots": "wkvUl_l3o1c", "Red Light Indicates Doors Are Secured": "hdmR58BIHOg", "You and I ": "9zXkAaoBOLU", "Teddy Picker": "2A2XBoxtcUA", "Settle for a Draw": "IQ7NH2jcAAw", "Bad Woman ": "YnkJHU3qYIA", "Cornerstone": "LIQz6zZi7R0", "Fright Lined Dining Room": "qrqtD4TiO5c", "A Certain Romance": "WGyj5JyA5Ms", "If You Found This It's Probably Too Late": "SqKl1vcmvOU", "Who the Fuck Are Arctic Monkeys?": "oFeuKVkau6U", "Do Me a Favour": "lXJEDlLepD4", "You Probably Couldn't See for the Lights but You Were Staring Straight at Me": "j8iV3tK717s", "Dancing Shoes": "3aQELo7tXyI", "The Jeweller's Hands": "1rq0Ag15sAI", "Matador/Da Frame 2R": "DxoPxvJ0FNM", "Pretty Visitors": "4n7iaY22Do0", "You're So Dark": "6eoAwXkI3RA"}
var score = 0
var nb = 0
var iter = 0
var song
var start
var click
var listSongs = []
getHome()
$(document).on("click", '.calc_btn', function() {
iter++
$("#valueIter").html(iter+"/10")
if(iter == 10)
{
gameOver(score)
}
else
{
click = new Date()
time = (click.getTime() - start.getTime())/1000
if($(this).val() == song){
if(time <= 15)
score += parseInt((-1000/14)*time+929)
$("#valueScore").html(score)
$("#valueScore").css( "color", "green" )
}
else
{
$("#valueScore").html(score)
$("#valueScore").css( "color", "red" )
}
nb += 1
getSong()
return false;
}
})
function getHome()
{
score = 0
iter = 0
listSongs = []
$("#boardGame").html(
'<h2>Welcome to The Game of Monkeys</h2>'+
'<table class="calculatrice" id="calc">' +
'<tbody>' +
'</tbody>' +
'</table>' +
'<div id="gameButtons" style="display: none;">' +
'<h2 id="valueScore">0 points</h2>' +
'<h2 id="valueIter">0/10</h2>' +
'<input type="button" class="stres" onclick="getHome()" value="Restart">' +
'</div>' +
'<input type="button" class="stres" value="Start" onclick="getSong()">'
)
}
function getSong()
{
var keys = [];
for (var prop in json_dic) {
if (json_dic.hasOwnProperty(prop)) {
keys.push(prop);
}
}
song = keys[ keys.length * Math.random() << 0 ];
listSongs = [ song ]
url = json_dic[song]
while(listSongs.length <= 4)
{
var keys = [];
for (var prop in json_dic) {
if (json_dic.hasOwnProperty(prop)) {
keys.push(prop);
}
}
song_random = keys[ keys.length * Math.random() << 0 ];
listSongs.push(song_random)
}
// adds the music player, of course
$('#calc tbody').html (
'<tr>' +
'<td class="calc_td_btn">' +
'<div style="position:relative;width:380px;height:25px;overflow:hidden;">' +
'<div id="yt_video" style="position:absolute;top:-276px;left:-5px">' +
'</div>' +
'</div>' +
'</td>' +
'</tr>');
// adds the multiple choice buttons
for(var i = 0; i <= 4; i++)
{
var randomIndex = Math.floor(Math.random() * listSongs.length);
var randomString = listSongs[randomIndex];
$("#calc tbody").append('<tr>'+
'<td class="calc_td_btn">' +
'<input type="button" class="calc_btn" value="'+randomString+'">' +
'</td>' +
'</tr>')
var index = listSongs.indexOf(randomString);
listSongs.splice(index, 1);
}
// shows the score and the restart button
$('#gameButtons').show();
var nb = getRandomInt(0,100)
$("#yt_video").html("<iframe src='https://www.youtube.com/embed/"+url+"?autoplay=0&start="+nb+"' id='yt_video' width='380' height='300'></iframe>")
start = new Date()
}
function getRandomInt (min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function gameOver(score){
$("#boardGame").html("<h2>You scored "+score+" points</h2><table class='calculatrice' id='calc'><tbody><tr><td class='calc_td_btn'><input type='button' onclick='getHome()' class='stres' value='Restart'></td></tr></tbody></table")
}
</script>
</body>
</html>
Oh I think I see the problem. You do not need to use the .html function.
Using jQuery:
$("#valueIter").val(iter+"/10");
$("#valueScore").val(score);
The html function is used to populate an element with raw html. The difference here is that jQuery provides .val() and .text() as getters and setters for any element which equate to the javascript equivelent of
element.value = score;