Chapter 2. Writing Real Code: Going Further

Image

You already know about variables, types, expressions... we could go on. The point is, you already know a few things about JavaScript. In fact, you know enough to write some real code. Some code that does something interesting, some code that someone would want to use. What you’re lacking is the real experience of writing code, and we’re going to remedy that right here and now. How? By jumping in head first and coding up a casual game, all written in JavaScript. Our goal is ambitious but we’re going to take it one step at a time. Come on, let’s get this started, and if you want to launch the next startup, we won’t stand in your way; the code is yours.

Let’s build a Battleship game

It’s you against the browser: the browser hides ships and your job is to seek them out and destroy them. Of course, unlike the real Battleship game, in this one you don’t place any ships of your own. Instead, your job is to sink the computer’s ships in the fewest number of guesses.

Goal: Sink the browser’s ships in the fewest number of guesses. You’re given a rating, based on how well you perform.

Setup: When the game program is launched, the computer places ships on a virtual grid. When that’s done, the game asks for your first guess.

How you play: The browser will prompt you to enter a guess and you’ll type in a grid location. In response to your guess, you’ll see a result of “Hit”, “Miss”, or “You sank my battleship!” When you sink all the ships, the game ends by displaying your rating.

Our first attempt...

... a simplified Battleship

For our first attempt we’re going to start simpler than the full-blown 7x7 graphical version with three ships. Instead we’re going to start with a nice 1-D grid with seven locations and one ship to find. It will be crude, but our focus is on designing the basic code for the game, not the look and feel (at least for now).

Don’t worry; by starting with a simplified version of the game, you get a big head start on building the full game later. This also gives us a nice chunk to bite off for your first real JavaScript program (not counting the Serious Business Application from Chapter 1, of course). So, we’ll build the simple version of the game in this chapter, and get to the deluxe version later in the book after you’ve learned a bit more about JavaScript.

Image
Image

First, a high-level design

We know we’ll need variables, and some numbers and strings, and if statements, and conditional tests, and loops... but where and how many? And how do we put it all together? To answer these questions, we need more information about what the game should do.

First, we need to figure out the general flow of the game. Here’s the basic idea:

Image

Now we have a high-level idea of the kinds of things the program needs to do. Next we’ll figure out a few more details for the steps.

Image

A few more details...

We have a pretty good idea about how this game is going to work from the high-level design and professional looking flowchart, but let’s nail down just a few more of the details before we begin writing the code.

Representing the ships

For one thing, we can start by figuring out how to represent a ship in our grid. Keep in mind that the virtual grid is... well, virtual. In other words, it doesn’t exist anywhere in the program. As long as both the game and the user know that the battleship is hidden in three consecutive cells out of a possible seven (starting at zero), the row itself doesn’t have to be represented in code. You might be tempted to build something that holds all seven locations and then to try to place the ship in those locations. But, we don’t need to. We just need to know the cells where the ship is located, say, at cells 1, 2 and 3.

Image

Getting user input

What about getting user input? We can do that with the prompt function. Whenever we need to get a new location from the user, we’ll use prompt to display a message and get the input, which is just a number between 0 and 6, from the user.

Displaying the results

What about output? For now, we’ll continue to use alert to show the output of the game. It’s a bit clunky, but it’ll work. (For the real game, later in the book, we’ll be updating the web page instead, but we’ve got a way to go before we get there.)

Working through the Pseudocode

We need an approach to planning and writing our code. We’re going to start by writing pseudocode. Pseudocode is halfway between real JavaScript code and a plain English description of the program, and as you’ll see, it will help us think through how the program is going to work without fully having to develop the real code.

In this pseudocode for Simple Battleship, we’ve included a section that describes the variables we’ll need, and a section describing the logic of the program. The variables will tell us what we need to keep track of in our code, and the logic describes what the code has to faithfully implement to create the game.

Image

Oh, before we go any further, don’t forget the HTML!

You’re not going to get very far without some HTML to link to your code. Go ahead and type the markup below into a new file named “battleship.html”. After you’ve done that we’ll get back to writing code.

Image
Image

Writing the Simple Battleship code

We’re going to use the pseudocode as a blueprint for our real JavaScript code. First, let’s tackle all the variables we need. Take another look at our pseudocode to check out the variables we need:

Image

Let’s get these variables into a JavaScript file. Create a new file named “battleship.js” and type in your variable declarations like this:

Image

Now let’s write the game logic

We’ve got the variables out of the way, so let’s dig into the actual pseudocode that implements the game. We’ll break this into a few pieces. The first thing you’re going to want to do is implement the loop: it needs to keep looping while the ship isn’t sunk. From there we’ll take care of getting the guess from the user and validating it—you know, making sure it really is a number between 0 and 6— and then we’ll write the logic to check for a hit on a ship and to see if the ship is sunk. Last, we’ll create a little report for the user with the number of guesses it took to sink the ship.

Image
Image
Image

Step One: setting up the loop, getting some input

Now we’re going to begin to translate the logic of our game into actual JavaScript code. There isn’t a perfect mapping from pseudocode to JavaScript, so you’ll see a few adjustments here and there. The pseudocode gives us a good idea of what the code needs to do, and now we have to write the JavaScript code that can do the how.

Image

Let’s start with all the code we have so far and then we’ll zero in on just the parts we’re adding (to save a few trees here and there, or electrons if you’re reading the digital version of the book):

Image

How prompt works

The browser provides a built-in function you can use to get input from the user, named prompt. The prompt function is a lot like the alert function you’ve already used—prompt causes a dialog to be displayed with a string that you provide, just like alert—but it also provides the user with a place to type a response. That response, in the form of a string, is then returned as a result of calling the function. Now, if the user cancels the dialog or doesn’t enter anything, then null is returned instead.

Image

Checking the user’s guess

If you look at the pseudocode, to check the user’s guess we need to first make sure the user has entered a valid input. If so, then we also check to see if the guess was a hit or miss. We’ll also want to make sure we appropriately update the guesses and hits variables. Let’s get started by checking the validity of the user’s input, and if the input is valid, we’ll increment the guesses variable. After that we’ll write the code to see if the user has a hit or miss.

Image
Image

Let’s look a little more closely at the validity test. You know we’re checking to see that the guess is between zero and six, but how exactly does this conditional test that? Let’s break it down:

Image

So, do we have a hit?

This is where things get interesting—the user’s taken a guess at the ship’s location and we need to write the code to determine if that guess has hit the ship. More specifically, we need to see if the guess matches one of the locations of the ship. If it does, then we’ll increment the hits variable.

Image

Here’s a first stab at writing the code for the hit detection; let’s step through it:

Image

Adding the hit detection code

Let’s put everything together from the previous couple of pages:

Image
Image

Hey, you sank my battleship!

Image

We’re almost there; we’ve almost got this game logic nailed down. Looking at the pseudocode again, what we need to do now is test to see if we have three hits. If we do, then we’ve sunk a battleship. And, if we’ve sunk a battleship then we need to set isSunk to true and also tell the user they’ve destroyed a ship. Let’s sketch out the code again before adding it in:

Image

Provide some post-game analysis

After isSunk is set to true, the while loop is going to stop looping. That’s right, this program we’ve come to know so well is going to stop executing the body of the while loop, and before you know it the game’s going to be over. But, we still owe the user some stats on how they did. Here’s some code that does that:

Image
Image

Now let’s add this and the sunk ship detection into the rest of the code:

Image

And that completes the logic!

Alright! We’ve now fully translated the pseudocode to actual JavaScript code. We even discovered something we left out of the pseudocode and we’ve got that accounted for too. Below you’ll find the code in its entirety. Make sure you have this typed in and saved in “battleship.js”:

Image
let location1 = 3;
let location2 = 4;
let location3 = 5;
let guess;
let hits = 0;
let guesses = 0;
let isSunk = false;

while (isSunk == false) { guess = prompt("Ready, aim, fire! (enter a number from 0-6):"); if (guess < 0 || guess > 6) { alert("Please enter a valid cell number!"); } else { guesses = guesses + 1;
if (guess == location1 || guess == location2 || guess == location3) { alert("HIT!"); hits = hits + 1; if (hits == 3) { isSunk = true; alert("You sank my battleship!"); } } else { alert("MISS"); } } } let stats = "You took " + guesses + " guesses to sink the battleship, " + "which means your shooting accuracy was " + (3/guesses); alert(stats);

Doing a little Qualit y Assurance

QA, or quality assurance, is the process of testing software to find defects. So we’re going to do a little QA on this code. When you’re ready, load “battleship.html” in your browser and start playing. Try some different things. Is it working perfectly? Or did you find some issues? If so list them here. You can see our test run on this page too.

Image
Image
Image

Boolean operators allow you to write more complex statements of logic.

You’ve seen enough conditionals to know how to test, say, if the temperature is greater than 32 degrees. Or, that a variable that represents whether an item is inStock is true. But sometimes we need to test more. Sometimes we need to know not only if a value is greater than 32, but also if it’s less than 100. Or, if an item is inStock, and also onSale. Or that an item is on sale only on Tuesdays when the user is a VIP member. So, you see, these conditionals can get complex.

Let’s step through a few to get a better idea of how they work.

Say we need to test that an item is inStock AND onSale. We could do that like this:

Image

We can simplify this code by combining these two conditionals together. Unlike in Simple Battleship, where we tested if guess < 0 OR guess > 6, here we want to know if inStock is true AND onSale is true. Let’s see how to do that...

Image

We don’t have to stop there; we can use multiple boolean operators to combine conditionals in a variety of ways:

Image
Image

Can we talk about your verbosit y...

We don’t know how to bring this up, but you’ve been a little verbose in specifying your conditionals. What do we mean? Take this condition for instance:

Image

As it turns out, that’s a bit of overkill. The whole point of a conditional is that it evaluates to either true or false, but our boolean variable inStock already is one of those values. So, we don’t need to compare the variable to anything; it can just stand on its own. That is, we can just write this instead:

Image

Now, while some might claim our original, verbose version was clearer in its intent, it’s more common to see the more succinct version in practice. And, you’ll find the less verbose version easier to read as well.

Finishing the Simple Battleship game

Yes, we still have one little matter to take care of because right now you’ve hard coded the location of the ship—no matter how many times you play the game, the ship is always at locations 3, 4 and 5. That actually works out well for testing, but we really need to randomly place the ship to make it a little more interesting to the user.

Let’s step back and think about the right way to place a ship on the 1-D grid of seven cells. We need a starting location that allows us to place three consecutive positions on the grid. That means we need a starting location from zero to four.

Image

How to assign random locations

Now, once we have a starting location (between zero and four), we simply use it and the following two locations to hold the ship.

Note

Take the random location along with the next two consecutive locations.

let location1 = randomLoc;
let location2 = location1 + 1;
let location3 = location2 + 1;

Okay, but how do we generate a random number? That’s where we turn to JavaScript and its built-in functions. More specifically, JavaScript comes with a bunch of built-in math-related functions, including a couple that can be used to generate random numbers. Now we’re going to get deeper into built-in functions, and functions in general, a little later in the book. For now, we’re just going to make use of these functions to get our job done.

The recipe for generating a random number

We’re going to start with the Math.random function. By calling this function we’ll get back a random decimal number:

Image

What we need is an integer between 0 and 4—that is, 0, 1, 2, 3 or 4—not a decimal number, like 0.34. To start, we could multiply the number returned by Math.random by 5 to get a little closer; here’s what we mean...

Image

That’s closer! Now all we need to do is clip off the end of the number to give us an integer number. To do that we can use another built-in Math function, Math.floor:

Image

Back to do a little more QA

That’s all we need. Let’s put this code together (we’ve already done that below) and replace your existing location code with it. When you’re finished, give it a few test runs to see how fast you can sink the enemy.

Image

Here’s one of our test sessions. The game’s a little more interesting now that we’ve got random locations for the ship. But we still managed to get a pretty good score...

Image

Congrats on your first true JavaScript program, and a short word about reusing code

You’ve probably noticed that we made use of a few built-in functions like alert, prompt, console.log and Math.random. With very little effort, these functions have given you the ability to pop up dialog boxes, log output to the console and generate random numbers, almost like magic. But, these built-in functions are just packaged up code that’s already been written for you, and as you can see their power is that you can use and reuse them just by making a call to them when you need them.

Now there’s a lot to learn about functions, how to call them, what kinds of values you can pass them, and so on, and we’re going to start getting into all that in the next chapter where you learn to create your own functions.

But before you get there you’ve got the bullet points to review, a crossword puzzle to complete... oh, and a good night’s sleep to let everything sink in.

JavaScript cross

Image

How does a crossword puzzle help you learn JavaScript? The mental twists and turns burn the JavaScript right into your brain!

Image

ACROSS

1. This helps you think about how a program is going to work.

7. Both while and if statements use __________ tests.

8. Boolean operators always result in true or _________.

9. To get a true value from an AND operator (&&), both parts of the conditional must be ___________.

10. JavaScript has many built-in __________ like alert and prompt.

11. To randomly choose a position for a ship, use Math._________.

DOWN

1. To get input from a user, you can use the _________ function.

2. == is a _____________ operator you can use to test to see if two values are the same.

3. OR (||) and AND (&&) are ___________ operators.

4. If you’re good at testing programs, you might want to become a ________ Assurance specialist.

5. If you don’t initialize a variable, the value is __________.

6. We keep track of whether a ship is sunk or not with a ________ variable.

8. To get a false value from an OR operator (||), both parts of the conditional must be __________.

JavaScript cross Solution

Image

How does a crossword puzzle help you learn JavaScript? The mental twists and turns burn the JavaScript right into your brain! Here’s our solution.

Image