Novice to Ninja chapter 8 question

So I am working on the next chapter of this book and again running into issues. I have added a form to the html and removed the alert prompts. When making all the adjustments for this chapter the questions are not being asked. I have tried to figure out this for a few hours and not moving forward at all.

Current issues I am running into. My form is not showing up to ask questions. It goes straight to the gameOver function and shows me a score of 0. The start button is not disapearing when I start the quiz.

Code:
HTML


<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="description" content="A quiz game for ninjas">
  <meta name="author" content="DAZ">
  <title>Quiz Ninja</title>
  <link rel="stylesheet" href="css/styles.css">
</head>
<body>
  <header>
    <h1>Quiz Ninja!</h1>
    <p>Score: <strong id="score">0</strong></p>
  </header>
  <section id="question"></section>
  <form id="answer">
    <input type="text">
    <button>Submit Answer</button>
  </form>
  <section id="feedback"></section>



<button id="start">Click To Play Quiz Ninja</button>
<script src="js/scripts.js"></script>

</body>
</html>

JS


//// dom references ////
var $question = document.getElementById("question");
var $score = document.getElementById("score");
var $feedback = document.getElementById("feedback");
var $start = document.getElementById("start");
var $form = document.getElementById("answer");


////view functions ////
function update(element, content, klass) {
    var p = element.firstChild || document.createElement("p");
    p.textContent = content;
    element.appendChild(p);
    if(klass) {
        p.className = klass;
    }
}

//// Event Listeners////
$start.addEventListener('click', function() { play(quiz) } , false);

quiz={
    "name": "Super Hero Name Quiz",
    "description": "How many super heroes can you name?",
    "question" : "What is the real name of ", 
    "questions" : [
        {"question": "Superman", "answer": "Clarke Kent"},
        {"question": "Batman", "answer": "Bruce Wayne"},
        {"question": "Wonder Woman", "answer": "Dianna Prince"}
    ]
}

var score = 0; // initialize score

function hide(element) {
    element.style.display = "none";
}

function show(element) {
    element.style.display = "block";
}

//hide the form at the start of the game
hide($form);

function play(quiz) {
    //hide button and show form
    hide($start);
    show($form);
    //main game loop
    update($score,score);
    
    $form.addEventListener('submit', function(event) {
        event.preventDefault();
        check($form[0].value);
    }, false);
    
    
    var i = 0;
    chooseQuestion();
    //end of main game loop
    
    gameOver();
    
    function chooseQuestion() {
        var question = quiz.questions[i].question;
        ask(question);
    }
    
    function ask(question) {
        update($question, quiz.question + question);
        $form[0].value=" ";
        $form[0].focus();
    }
    
    function check(answer) {
        if(answer === quiz.questions[i].answer){  
        update($feedback, "Correct!","right");
        //increase score by 1
        score++;
        update($score,score)
        } else {
        update ($feedback, "Wrong!", "wrong");
        }
        i++;
        if(i===quiz.questions.length) {
        gameOver();
        } else {
            chooseQuestion();
        }
        
    }
    
    function gameOver() {
        //inform the player that the game has finished and tell them how many points they have scored
        update($question , "Game Over, you scored " + score + " points");
        hide($form);
        show($start);
    }
}

CSS


*{
  margin: 0;
  padding: 0;
}
body {
    width: 400px;
    margin: 0 auto;
    background: #fff;
    height: 100vh;
}

html {
    background: #444;
}

header {
  font: bold 36px/120% Arial, Helvetica, sans-serif;
  background: #333;
  color: #c00;
  text-transform: uppercase;
}

section p {
    font: bold 24px/150% Arial, Helvetica, sans-serif;
    background: #ccc;
    border: #999 2px solid ;
    color: #666;
    text-align: center;
    padding: 10px;
    margin: 10px;
    width: 300px;
}

.right {
    background: #0c0;
    border: #090 2px solid;
    color: #600;
}

.wrong {
    background: 
}

input, button {
  font: bold 24px/150% Arial, Helvetica, sans-serif;
  display: block;
  width: 300px;
  padding: 10px;
  margin: 10px auto;
}

Is there a reason for
gameOver();
to be in the play function?

I removed the gameOver (); and gameOver function from the play function. That got the questions working and the buttons hiding and showing as it should. Every time I put in an answer it is wrong though.

This book did not mention moving the function out side of the play function and I am now noticing that the check function does mention the gameOver function in its block. As I am still new to this, would there be an issue with gameOver inside of the check function being used local to the play function and now the gameOver function is now more of a global function???

I wouldn’t remove the gameOver function, only the line that calls it inside the play function. (actually, better to leave it there for now and only comment it out.)

I look at functions inside of functions as being similar to methods inside of classes, just that they aren’t named as such. And yes, where they are defined does affect the scope.

If it didn’t instruct you to yet, probably better to not.
It might be the book will ask you to later, but I’ve found things to go more smoothly going step by step.
On the other hand, I think I’ve learned more by breaking and fixing code than I have from either copy/paste or using “as shown only” code

I am still stuck. Currently trying to debug why check function is not working correctly. I put a break point on the if statement. Even though the it looks like to me answer === quiz.questions[i].answer. It skips directly to the else statement.

Close, but " Bruce Wayne" != “Bruce Wayne”

aaaaaaaaaaaaaaaaarrrrrrrrrrrrrrrrrrrrrrrrggggggggggggggggggggggggggggggg

lol thanks

There are a few problems in the script. You might like to check the starting and ending brackets for each of the functions {}. There is an extra one in there.

You need to run the script from function play(), rather than having chooseQuestion() and gameOver() in the main loop. You can delete these calls as they are not needed.

Change the function play(quiz) to the following :

function play(quiz) 
   { //hide button and show form
       show($form);
       hide($start);
       chooseQuestion();
    //main game loop
       update($score,score);    
       $form.addEventListener('submit', function(event) 
         { event.preventDefault();
           check($form[0].value);
         }, false);
     }    
// ------------    

In function check(answer) you need to strip the incoming answer of blank characters and set both the incoming answer and the comparison answer to lower case before making the comparison like this:

function check(answer) 
   { answer=answer.replace(" ","");
      if(answer.toLowerCase()== quiz.questions[i].answer.toLowerCase())
       { update($feedback, "Correct!","right");
        //increase score by 1
         score++;
         update($score,score)
        } 
       else { update ($feedback, "Wrong!", "wrong"); }
        i++;
        if(i===quiz.questions.length) { gameOver(); } 
        else { chooseQuestion(); }        
    }
// --------- 

In the gameOver() function you need to hide a few elements like this:

function gameOver() {
    update($question , "Game Over, you scored " + score + " points");
    hide($form);
    hide($start);
     hide($feedback);        
   }
// --------- 

At the moment, when you put in a wrong answer the program says “Wrong”, but you can’t try again. This might be something you could consider as a add-on. Also at game end you need to reload the page to start again. maybe a reset button would be more convenient.

I have placed a working model of this quiz on jsFiddle so that you can look at the other aspects of the program.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.