Chapter 18
The while loop will continue to perform its loop as long as its conditions are met. The while loop will do the job until it’s done — no questions asked!
In this chapter, we use a while loop to write a game that will keep buying you sandwiches until you run out of money. The object of the game is to make your lunch money last all week.
Compared to for loops, while loops are pretty simple. They only have one part — a Boolean expression — that determines whether the loop will run and continue to run.
Here’s an example of a while loop:
while (money > 0) {
buyThings();
saveMoney();
payTaxes();
}
This loop executes the three functions — buyThings(), saveMoney(), and payTaxes() — as long as the value of the money variable is greater than 0.
The for loop has a final expression that changes the value of the counter. The while loop requires you to have an expression or expressions inside the loop that can change the result of its condition.
The three function calls we created inside the while loop are just made up names. If we were to actually write these functions, they would need to update the value of the money variable so that the loop stops at some point (but, of course, this is one loop we hope doesn’t stop!).
If you don’t modify the value of the variable in a while loop’s condition, you may create what’s called an infinite loop. An infinite loop won’t damage your computer, but it will likely cause your web browser to freeze up and cause you to have to force it to quit — risking losing any unsaved changes. So, make sure to check your while loops carefully to make sure they’re not infinite!
A while loop can do everything that a for loop can do, but the coding is just a bit different. Let’s take a look at the three uses for for loops that we talk about in Chapter 17 and show how to do them with while.
Listing 18-1 shows how you can use a while loop to log Hello, JavaScript! to the console window 500 times.
Listing 18-1 Logging Hello, JavaScript
var i = 0;
while (i < 500) {
console.log(i + ": Hello, JavaScript!");
i++;
}
Notice that the program in Listing 18-1 contains all the same three parts that are in a for loop (initialization, condition, and final expression), but only the condition is inside the parentheses. The initialization (var i = 0;) is before the while loop, and the final expression (i++) is inside the while loop.
To create a loop that counts, you can just modify a variable inside every pass through the loop and use that variable inside other statements in the loop.
Listing 18-2 shows a countdown like the one from Chapter 17, but using a while loop.
Listing 18-2 Count Down with while
var count = 10;
while (count > 0) {
alert(count);
count--;
}
alert("Blast Off!");
Looping through arrays with while is easier than it is with for. To loop through an array with while, change the condition in the loop to test whether an array element has been declared.
To test whether an element has been declared, just put the name of the array with a counter variable inside the parentheses after the while keyword.
For example, Listing 18-3 shows an example that loops through a list of people’s names.
Listing 18-3 Looping through a List of Names
var people = ["Deborah","Carla","Mary","Suzen"];
var i = 0;
while (people[i]) {
alert(people[i]);
i++;
}
The condition between the parentheses in a for loop or a while loop is a Boolean expression, which means it evaluates to either true or false. When you use an array element, such as people[5] as a Boolean expression, it will be true as long as there is an element in the array at that array position.
The Lunch Game is a unique combination of a game of chance and a game of math. The object of the game is to try to budget so that you have sandwiches for every day of the week.
But, here’s the catch: You go to the strangest school in the world, and you don’t know how much sandwiches will cost until the sandwiches are made — but you have to buy all your sandwiches for the week before the week starts!
You do know that sandwiches will always cost between $1 and $5. So, depending on your luck, you’ll be able to buy somewhere between 4 and 20 sandwiches.
How much risk are you willing to take? Will someone come to your aid and give you part of their sandwich if you run out before the week ends? How many sandwiches can you eat?
All these questions, and more, will be answered in the Lunch Game.
To get started with writing the Lunch Game, follow these steps:
Go to our JSFiddle Public Dashboard at http://jsfiddle.net/user/forkids/fiddles
.
You see the list of all our public programs.
Find the program named “Chapter 18 – Lunch Game – Start,” and click the title to open it.
The starter program opens, as shown in Figure 18-1.
We’ve written the HTML, CSS, and most of the JavaScript for you. The only thing left for you to do is to write the buyLunches() function.
In the next section, we show you how to do it!
Listing 18-4 shows the starter code and comments for the buyLunches() function.
Listing 18-4 The Starting Point for buyLunches()
/*
buys specified number of sandwiches per day at current prices
*/
function buyLunches() {
/*
todo:
* reset the form
* start a loop
* get daily sandwich order
* calculate total price
* figure out if there's enough money
* if so: subtract money, increment number of lunches, and start loop over
* if not: display 'out of money' message
* display total lunches after loop exits
*/
}
Follow these steps to write the body of the function to match these instructions:
resetForm();
var day = 0;
Create a loop that will buy sandwiches until you’re out of money.
while (money > 0) {
Get the current price of sandwiches by making a call to the getSandwichPrice() function and assigning the return value to a variable.
var priceToday = getSandwichPrice();
At this point, take a look at the getSandwichPrice function. Its purpose is to randomly generate a number between 1 and 5 and return that value.
Get the number of sandwiches that the user entered into the form field.
var numberOfSandwiches = document.getElementById("numSandwiches").value;
Calculate the total price by multiplying the number of sandwiches that you want by the current sandwich price.
var totalPrice = priceToday * numberOfSandwiches;
Find out whether there’s enough money to buy the sandwiches.
if(money >= totalPrice) {
If there is enough, subtract the total price from the current money balance.
money = money - totalPrice;
Congratulations! You’ve successfully purchased a lunch!
Increment the lunches variable, which keeps track of how many lunches were purchased.
lunches++;
Output a message to tell the user the price of the sandwiches he just bought and how much money he has left.
document.getElementById("receipt").innerHTML += "<p>On day " + day + ", sandwiches are: $" + priceToday + ". You have $" + money.toFixed(2) + " left.</p>";
Notice that we’ve attached the toFixed() method to the money variable. The toFixed() method converts a number to a string, while keeping the number of decimals specified within the parentheses. In this case, because we’re printing out a currency value, we use two decimal places.
Next, start the else clause of the if…else to handle cases where the amount of money left isn’t enough to buy the specified number of sandwiches.
} else {
When the else clause runs, output a message that’s special for when the user doesn’t have enough money for another lunch.
document.getElementById("receipt").innerHTML += "<p>Today, sandwiches are: $" + priceToday + ". You don't have enough money. Maybe your sister will give you some of her sandwich.</p>";
Still within the else clause, set the value of money equal to 0 in order to prevent the loop from running again.
money = 0;
Finish the if…else statement and the while loop with curly brackets.
}
}
When the loop completes, output the total number of lunches that the user was able to buy.
document.getElementById("reciept").innerHTML += "<p>You bought " + lunches + " lunches this week.</p>";
Close the function with a curly bracket.
}
The finished Lunch Game is shown in Figure 18-2.
If you enter a number into the text field and press the Place Order button, the program calculates how many lunches you can buy, using random sandwich prices. Remember: A lunch consists of one or more sandwiches, according to your input.
Try out the program several times by entering new numbers into the text input field and pressing the Place Order button. You see that the random numbers and the number of lunches you can buy per week vary quite a bit.
Figure 18-3 shows one possible outcome of running the program.
When you have a game that you’re proud of and you want to share with the world on your own website, you need to move beyond the walls of JSFiddle. In this section, we show you how to do that!
Every website has a unique address that people can use to visit it. In order to get your own address on the Internet, you need to sign up with some sort of web hosting company. JSFiddle is a web hosting company that provides a free testing area for people to make programs with JavaScript, HTML, and CSS.
JSFiddle is great, but it has its limits, such as the fact that it lets anyone copy and modify your code, and it doesn’t give you the option of having your own domain name (such as www.mywebsite.com
).
Most web hosting companies charge a monthly fee for uploading your web pages to the Internet. However, there are some that give out free trial accounts. In this section, we show you how to set up and use a free trial account with x10Hosting (www.x10hosting.com
).
Follow these steps to create an account and a website at x10Hosting:
Open your web browser and go to www.x10hosting.com
.
You see the home page, featuring a button labeled Sign Up Now, as shown in Figure 18-4.
Click the Create My Account button.
A form where you can enter a name for your custom web address appears.
Click to agree to the terms of service, and click Submit to finish signing up.
An email confirmation is sent to you.
Click the link in the email to confirm your account.
If you don’t get the email within a few minutes, check your spam folder.
When your account is confirmed, click Continue to log in.
It may take minute for your account to be ready. If you see a message telling you to wait, take a break and then come back and click the Continue button when it becomes available.
Click the link that says Open cPanel.
Your control panel opens.
Click Add Website.
Your new site is created and you see the unique website address.
Make a note of this website address. You’ll be using it later!
In the control panel for your website, click the File Manager link.
A window opens, showing you the files and directories in your web hosting account (see Figure 18-7).
If this is your first time using the code editor, a window opens asking you to choose an “encoding”; click the Disable Encoding Check link.
A blank page opens in the code editor.
Copy the first lines from the JavaScript pane, up to the function declaration for the buyLunches() function, and paste it in the function body for the init() function in the lunchgame.html file, as shown in Listing 18-6.
Check your code carefully after you paste, to make sure that it matches Listing 18-6 exactly.
The init() function runs as soon as the web page is loaded.
Click Close, just to the left of the Save button.
If you get a message regarding the character encoding, you can just close it by clicking OK and you’re returned to the File Manager.
Go to your website address in a new browser tab.
You see a list of the files in your website. Currently, you should only have a folder called cgi-bin and your lunchgame.html file.
If you don’t want to see this list of web pages, you can create a new HTML file called index.html, and it will appear when you visit your website instead.
Click lunchgame.html to open the Lunch Game.
The Lunch Game appears in your browser window, as shown in Figure 18-8.
Listing 18-5 A Standard HTML Template
<!doctype html>
<html>
<head>
<title>Lunch Game</title>
<style>
</style>
<script>
function init() {
}
</script>
</head>
<body onload="init();">
</body>
</html>
Listing 18-6 Finishing the init() Function
function init() {
// declare globals
var money = 20;
var lunches = 0;
//display lunch budget
document.getElementById("money").innerHTML = money;
//listen for order
document.getElementById("placeOrder").addEventListener("click", buyLunches);
}