All right so we're getting to the heart of our website in terms of the game logic.
Now for this part of the module we're gonna have to write the logic that does three things.
We have to one serve up the new questions to check the submitted answers against the correct answer
and 3 reset the game once the game finishes.
We're in the project.
Do you think our gaming logic should live.
What I would propose is putting all the gaming logic into a separate file.
I would like to split out the part of the website that does the data processing from the part that does
the styling from the part that does the drawing logic on the canvas.
So let's right click in here.
Couldn't you file and call this one maths Dot.
J.S. we couldn't write all the logic for our game inside this file.
That way we keep things nice and separate as a first step.
Let's write the logic that serves up a new question for this point.
What we want to do is we want to create a math question.
We want to show the user to different digits that add up to a maximum value of nine and that job is
gonna be handled by a function.
So when I add a code snippet here using the function keyword and I'm gonna call my function next question
and it's not going to take any parameters.
So when I delete that bin and inside this function it's gonna go to logic that generates are random
numbers for a Web site.
So let's try this let's generate a random number between 0 and 4.
How would you do this.
Well lucky for us JavaScript has this capability through the math library the math library has a function
here called random which is exactly what we're going to use.
So how is this random function work.
The random function will generate a floating point number in the range of 0 to 1.
So it's inclusive of zero but not inclusive of one.
So let's use this function in this code.
I want to save the output of the function in a variable called and 1.
And here what I want to do is I'm going to call math that random and I want to take this output that
is between 0 and 1 and I want to multiply it by 5.
So if the random output hit is zero then I'll get zero times five which is zero.
If the random output is one half or zero point five then the result and one will be equal to 2.5.
So that's fair enough right.
Let's try and display this output on our Web site the place I want to display the output is for this
first number right here which currently reads three.
If I right click on it and click inspect then I can see that this number here has I d called and 1.
And what this means is that I can get a hold of this element in my code through its ideas.
Right.
So I can come back in here and grab my document and get an element by I.D. and that element being the
one that has the I.D. and one and then what I wanna do is gonna set the inner H temple so the contents
of this element equal to.
Well the value of the variable.
So the value of the constant right here.
Okay.
So we've created our function but we've actually not used it anywhere.
We have not called it anywhere yet.
Let's call this function when our button gets pressed.
So when that happens then the code inside here in our index HMO gets executed when our button gets pressed
all the code between these two curly braces is triggered.
So what do we want to happen.
Let's leave predict image where it is for now let's leave clear canvas where it is for now but just
below.
Let's make a call to next question.
But that's not all that we need to do right.
There's something that we forgot.
You know what it is.
That's right.
We have to link this index HDL to our maths thought J.S. file and the place we did that for the previous
two files was right here using the script tag and then pointing it to that JavaScript file that we wanted
to include so let's do the same thing.
Let's add a script and for the source we're gonna set it equal to maths thought J.S. and that's it.
So let's save our index age demo let's save our math stock yes and then let's come back in here and
refresh the site then let's draw something on our canvas and hit check.
Answer to trigger our next question method behold a random floating point number appears where we've
previously had our number three.
So at this point I have a challenge for you.
What I'd like you to do is I'd like you to write the logic that will make this first number here not
some floating point number here but an integer that's gonna be between 0 and 4 and then also I'd like
you to add the logic that makes the second number here an integer between 0 and 5.
I'll give you a few seconds to pause the video and give this a go
ready here's the solution.
The key to getting an integer is rounding down this number.
So what I want to do is I want to wrap all of this inside math dot floor math thought floor will round
down the result of this calculation here and because math thought random will never give me the value
1.
It means that this output here is always gonna be between 0 and 4 for the second number here.
I can apply exactly the same logic so I can take these two lines copy them paste them below and just
change this to N2 and I could change this to N2 because the I.D. of this element here this heading is
N2 so I'm going to get the element by Eddie with the I.D. N2 and I'm going to set the value equal to
not this constant here but this one right here.
The only other thing I have to do to make sure that I indeed get a value between 0 and 5 4 and 2 is
change this here to 6.
So math thought random times 6 rounded down will always give me a value between 0 and 5.
That's it.
So let's save refresh and let's try and as you can see both numbers update as they should.
So what we can do now is we can start tracking the correct answer coming back into this code.
Let's create a variable here that reads answer.
So var answer and inside.
Next question what we can do is we can give answer a value we can set it equal to and one plus and 2.
So that's gonna be the correct answer that we're going to check against.
Now the checking logic is gonna live in a separate function and that function is going to have the name
check answer.
And there's also going to be no inputs no parameters.
So what should we put in here.
We've got our answer above.
But the thing we don't have is a prediction.
How do we get hold of the prediction based on what was drawn on the canvas.
Well why don't we modify our predict image function so that it actually returns a prediction that we
predict image will actually have an output namely the prediction that we're after.
At the moment all we're doing is printing out a tensor called result.
But what we would need is the actual value of this tensor here.
How do we actually get a value out of a tensor.
We need this integer right here the way we actually get a value out of a tensor in tensor flow light
is using a method called Data Sync.
And what you can see here from the description is it it downloads the values from a tensor and it provides
as these values in the form of an array.
Because there might be more than one right in a tensor.
So back in V as code let's call this data sync method and let's store the output in a constant called
output and output will get its value from result dot data sync with a capital S and then some parentheses
at the end.
Now as we read it in the documentation data sync will actually provide us with an array but if we look
at our prediction here we've actually only got one value in our array.
It's an array with a single entry and that means we can actually fetch that entry using the square bracket
notation and grabbing the first element in our array.
So square brackets 0.
So this here now is just in number scrolling down to the very end of our method past the cleanup code.
We can now return our output adding the return statement at the very end ensures that all the code above
is actually executed.
If we had the return statement somewhere up here then our cleanup will actually never get triggered.
So that's something to be mindful of.
Returning an output is usually the last thing that you want to do inside a function.
All right.
So now predict damage is returning a value.
Let's change how predict the image is being used inside our index that each team L because instead of
calling predict image every time that the button gets pressed.
How about we actually just check the answer so we check.
Answer instead of predict image after we check their answer we clear the canvas and we move on to the
next question.
That's logical right.
Now that we're checking our answer every time the button gets pressed we can head inside our math start
J us and we can complete the logic that's involved in checking the answer.
We said we needed to get hold of the prediction right.
So let's store the prediction inside a constant called prediction and we're gonna set that equal to
the output from our predict image method.
So predict image was now returning an output and we want to store that inside our prediction.
Now that we've got both our answer and our prediction in hand let's log both of these to the console.
Let's take a look at what it is that we've got.
So I you use that string interpolation again with the back tick.
And I went right and some dollar sign.
Curly braces answer and then I'm going to put our prediction as well with that done save all your files
so I've got unsafe changes in three files up here.
So I want to save this one save this one and save this one.
Now I'm going to head back into chrome refresh and I'm going to draw something in the canvas and hit
check answer.
Now what do you notice.
Well the good news is is that I kept my prediction printed out right here.
I see my log statement executed.
And if you don't try clearing your browser data to make sure that you actually see this lock statement
and make sure that prediction is actually defined.
But what else do we notice here.
We see that answer is in fact undefined.
Why is that.
Let's draw something in this box again and hit check answer again.
So the second time we do this our answer has the value five and our prediction has the value one.
So the first time it was undefined.
But then when we check the answer again it had a value.
Why is that.
Well when does answer actually get its value.
Well it gets its value right hip every time.
Next question is being called and when is next question being called.
Every time we press the button.
So what we're seeing is answer has no value when the Web site actually is being loaded.
Let's fix that by calling.
Next question.
When we actually load our Web site that way we actually get a new question every time the Web site is
being reloaded.
It doesn't always start out being three plus two three plus two or three plus two every single time
to make sure that next question is being called when we load our Web site.
Let's head into the index that HMO and then right here in our script after loading the model and preparing
the canvas we can call next question.
Simple as that.
Now when we save and refresh we see that there's a new question every time that we load the web site
and our answer actually has a value as well.
So where are we now.
Well we've got our answer.
We've got our prediction and we can compare the two.
So wouldn't it be nice to keep score.
Let's increase the use of school every time they get an answer right and let's decrease the use of school
every time they get an answer wrong.
This logic fits perfectly inside our check answer function.
If the prediction is equal to so when you use the double equal sign here just like in Python the answer
then in that case the score should go up.
So let's log something here.
Correct.
Otherwise we're gonna log wrong.
Exclamation mark.
Let's see if this works.
Let's save refresh and well for formulas 2 that's equal to 6.
Check.
Answer and yes it is correct.
And our logic is sound and that puts us in a great position to start keeping score.
Now I want to create a variable up here that reads score and it's going to start out with a score of
zero and then what I can do is I can come down here where we're checking our answer and I can increase
the score by 1.
Every time an answer is correct and the shorthand for this is plus plus.
And then when I log this in my log statement using the back ticks.
So here we'll see.
Correct.
And we'll just provide the score here for our convenience.
And when the answer is incorrect we're gonna subtract one from the score and the shorthand here is unsurprisingly
minus minus so let me update Locke's statement as well.
And now let's give it a try.
So I'll save my changes.
Come back in here refresh and let's see this works.
So six.
Correct.
The score is equal to one three plus four is equal to seven.
So now our scores equal to two.
And if I get one wrong then our score goes down to 1 but that's one problem with this logic.
Right.
What happens for example if we get a couple of questions wrong in a row.
So if this answer is equal to one and this answer is equal to one then what we see is that our score
goes negative.
This is not what we want a negative score is not helpful.
So how can we fix this.
Let me pose that as a challenge to you.
Let me give you a few seconds to pause the video and modify the code so that the score does not drop
below zero.
Ready.
Here's the solution.
All we would have to do is add another if statement before this line executes.
So if the score is not equal to zero then we're going to subtract one.
Otherwise we're going to leave the score as it is.
The exclamation mark here is the logical not in JavaScript just like it is in Python.
So now that we've done this modification let's test it out.
So when I come here and I want to answer the first question incorrectly and my score stays at zero so
I can answer a number of these questions incorrectly and it stays at zero.
And when I start answering the questions correctly again my score starts to increase.
Nice.
That's what we want.
So now we're able to keep score.
Why not give the user a bit of visual feedback as they answer these questions correctly.
Let's make our garden grow.
Every time we get an answer right.
And this is where the images that are part of the stop project come into play.
We've got six vector images that will all act as foliage.
In our garden.
So now all we need to do is write the logic to make sure these images are being displayed on screen.
That's the idea.
And then every time a question is answered incorrectly we take one away that way our garden starts wilting
as the questions are answered incorrectly.
The way we're going to implement this in our code is using an array so that array will hold on to all
the images that should be displayed on the screen.
So when I create that array up here as a global variable and I want to call it background images and
it's going to start its life as an empty array.
So just to empty square brackets every time a question is answered correctly we are going to call the
push method.
And what this will do is it will add an item on the array.
So if you head over to this page here on W3 schools you can try it yourself by adding the kiwi fruit
to this array of fruits.
Now in the example here in the documentation you can see that all these fruits actually just strings.
But what are we working with exactly or what will we work with in our case what our array is actually
gonna hold on to is not strings not numbers.
It's going gonna hold on to a set of you or else.
And those your L's are going to point to these vector images.
Let me show you how this is going to work when our question is answered correctly.
So our score has increased.
What we can do is grab our background images and then push something onto this array.
And the thing we're gonna push on is something called a U R L and that your l is gonna point to our
first image say so our images are inside our image folder.
So single quotes images then a slash a forward slash and then the first name of the image.
And that's background.
One dot SPG.
The spelling here mind you has to match exactly what we've got here.
Now that we've added this first image to our array what we need to do is actually display these on screen
and the way this is gonna work is we're going to grab the body of our document and this will have a
background image prompting.
Here's how we're going to access it.
We're gonna grab our document and we're gonna grab the body in the document and then we're gonna go
to the style of this body and when to set the background image of the style and what are we gonna set
it to set it equal to our array of background images and that's it.
So let's save and check if this works but come back in here refresh and answer our first question correctly.
So that's a seven foot check the answer then indeed we've set the background image of our body to the
first image in our images folder.
So that works right now.
We don't just have one image right.
We've got six different images.
So what modification could we make to our code to make sure a new image gets added every single time.
The one thing that you might notice is that all the image names actually end in a number which means
that we could actually use our score to grab the next image.
Let's do that instead of using the number one here let's use string interpolation to grab hold of the
score instead I'm going to penned the score to this file name right here.
Let's try this.
Let's save our changes refresh our page and then start answering some of these questions.
So that first one is zero.
The second one is six.
But as you can see nothing happened because our model predicted five because I was writing a very untidy
way.
So let's try again.
So I want to go with one and then two and then six and then eight our garden really seems to be growing
at this point which is really really nice.
But as we get to the end of the number of images that we have.
What do you think will happen.
So far I answer this one right here then I've got my last image and this point I'm going to run out.
So if you look at the error message here what do we see.
We see that it's looking for background seven dot SPG.
And it says four or four file not found.
Why is that.
Well because background seven doesn't exist.
So that's a problem.
Right.
But how do we fix it.
How about we only add a picture if the score is actually less than or equal to six.
If the score is higher than six then let's congratulate the user and restart the quiz.
I think this actually makes a really good challenge.
I'd like you to have a go at writing the code that only adds new pictures.
As long as we have images and if the score gets too high then use a window alert to write a congratulatory
message and then restart the quiz.
I'll give you a few seconds to pause the video before I show you the solution.
All right.
Did you have a go.
Here's a sample solution for how to implement this.
Only adding images if the score is less than or equal to six we can accomplish that with another if
statement someone a nest an if statement and here.
Just read the score smaller or equal to 6 which is the maximum number of images that we have.
And then I want to move these two lines of code into the curly braces of this if statement.
So this is the part of the code that will get executed as long as there are plants that can grow in
our garden.
Now what the garden is already fully grown.
Well in that case we should execute the code in an else clause.
We've reached the end of the quiz.
So let's tell the user that they've won and we should reset to make sure that he can go and have another
go in order to send the congratulations.
Using the alert we're simply going to use a lot open parentheses and then write our message in here.
I'm simply going to write.
Well done your math garden is in full bloom.
Want to start again.
And I'm not going to give them a choice.
They're just gonna have to start again.
But here's the question how do we actually reset the quits in our case.
What are the two things that actually change as the user progresses through the quits.
Well that's gonna be the score and the number of images inside the background images array.
Right.
So a reset simply involves setting the score back to zero and setting background images equal to an
empty array.
Now that the two key variables are reset the only thing that we have to do is make sure we display the
changes to the user.
So that's going to be exactly the same line of code that we're using to grow and add new plants to our
garden.
So if I copy this line pasted in then what should happen is we are going to remove all the images from
our array and we're going to update what's on screen with an empty array.
So meaning we're going to be removing all the images and showing the blank Web site to the user.
So let's try this by going through the quiz zero plus zero is equal to zero three plus zero is equal
to three.
We've had this one before.
Now three plus one is equal to four.
How many more to go.
Not that many.
Right.
So five that's eight that's three and now we've reached the end of the quiz.
Well done.
Want to start again.
OK and here we are back at the beginning of the quiz.
So that works wonderfully right.
The only thing left to implement is the garden wilting and dying.
If an answer is incorrect.
So in my opinion this makes a perfect challenge once again to solve this challenge.
You'll have to figure out a couple of things you'll have to figure out how to remove an element from
the background imagery.
You also have to alert the user that they got an answer wrong.
And as a little bit of an extra challenge I'd like you to remove the image from the screen after a little
bit of a delay so you can use this function right here called set timeout in order for the image to
be removed after a small delay of like a couple of seconds.
I'll give you a bit of time to pause the video before I show you the solution.
Ready.
Here it goes.
So the first thing I'll add is the alert and the alert is gonna read.
Whoops.
Check your calculations and try writing the number neater next time.
Afterwards I'm going to call this such timeout function and the way I'm going to use it is simply by
putting such timeout and then inside the callback.
We're gonna provide no name no parameters but we're gonna write a little bit of code and the first thing
we're gonna do is when to remove an item from our background images array push was the name of the method
to add an item to the array and pop is the name of the method that removes an item.
So background images pop pop and then we simply call this line of code once again.
So we're gonna update the background image of our body with the newly shrunken background images array.
There we go with regards to the delay in order to implement that.
All we need to do is supply a second argument.
You can even see here in the quick help that the second argument is the time out.
How long should it take before the code in the callback is executed.
And I think one or two seconds works really well.
The way you would provide a one second timeout is writing 1000 1000 milliseconds is equal to 1 seconds.
So that's it.
That's the solution to the challenge.
Let's try it out.
Let me answer the first question correctly and then let me answer the second question incorrectly.
I get my feedback message loops check your calculations and then the foliage is removed.
After a good second or so and that's the gaming logic all done.
Now we've written all the code for the entire project.
So what's the next step.
Well in the last lesson for this module we're going to say good bye to our local host and we're going
to publish our Web site and make it live for the world to see.
So for all of that I'll see you in the next lesson.