Slippery Rock University Dr. Deborah Whitfield Go Browns!

Chapter 13: Repetition

Terms:

while loop
Also, allows a (compound) statement to be executed some number of times. A while loop is generally used when the exact number of iterations is not know in advance. Iterations occur while something is true. If the condition is not initially true, the "iteration statement" will not execute at all.
boolean expressions
A trivial expression is any single value (as from a variable, a literal or a function). Non-trivial expressions combine other elements in some way to get a resulting value. Boolean expressions work with Boolean (true/false) values. The three operators are: and (&&), or (||) and not (!).
&&
The AND operator combines two boolean values. The result is true only if both of the operands are true, otherwise the result is false. For a string of AND operations, every operand must be true for the result to be true.
||
The OR operator combines two boolean values. The result is false only if both of the operands are false, otherwise the result is true. For a string of OR operations, every operand must be false for the result to be false.
!
The NOT operator works on a single boolean value (unary operator). If the value was true, it becomes false and vice versa.
for loop
Also called a counting loop. Allows a (compound) statement to be executed some number of times. A for loop is generally used when the exact number of iterations is know in advance, perhaps in terms of the current value of some variable (such as maxNumOfStudents). An obvious use is to access each element in an indexed array.
indexed arrays
Indexed arrays are generally meant for use with a for loop. The index is a number from 0 to the length of the array minus 1. The elements in the array are all of the same type. This use of an array matches closely with the array data structure in most programming languages (see note below). Indexed arrays can be thought of as a numbered list of elements, where the numbering starts at zero.
length
Each array object knows its own length. This means we do not have to use a variable to remember it or risk using a literal. Instead we use arrayName.length where ever the value is needed.

WHILE loop syntax
initStmt ;
while  ( testExpr ) { 
   someIterationStmt1 ;
   someIterationStmt2 ; //...
   someIterationStmtN ;
   updateStmt ;
   }

Technically, the initStmt, updateStmt and even the testExpr are all optional. However, you should go through all of these carefully in your planning to avoid an infinite loop. An infinite loop may require an alt-ctrl-delete, task manager kill of the process to stop the loop. The use of an alert() inside the loop can be very useful for debugging.

The most common cause for loop errors, including infinite loops... placing a semicolon after the closing parenthesis of the loop statement. Like an if statement, this results in a null statement. Since the iteration statement is essentially doing nothing, it's going to execute really fast. In a for loop, this means your loop statement will quickly do nothing the number of times you specified and then go on and do what you thought was the loop iteration statement exactly once. A while loop will have no chance to update anything, so once in the loop your stuck forever, doing nothing. Not cool.


FOR loop syntax
for  (  initStmt ; testExpr ; updateStmt ) 
   someIterationStmt ;
for  (  initStmt ; testExpr ; updateStmt ) { 
   someIterationStmt1 ;
   someIterationStmt2 ; //...
   someIterationStmtN ;
   }

The parentheses and the semicolon in the first line are required, even if one of the statements is null.

A for loop can always be written as a while loop following fairly simple rules:

  1. If the for loop did not have a compound iteration statement, add the curly braces ({ }) now.
  2. Whatever comes before the first semicolon inside the for loop parentheses is moved outside and just before the new while loop.
  3. whatever comes after the second semicolon inside the for loop parentheses is moved inside the compound iteration statement as the very last thing to be done.
  4. Make sure the (now) extraneous semicolons are removed from inside the parentheses and change the for to while. The test condition remains as the identical test condition of the while loop.

Simple Loop Examples

These examples tend to use document.write() which creates HTML output that become part of the page displayed. This allows me to show you the output and code that created it on the same web page. They also violate the rule of calling a function (for the same reason), instead just embedding the script to be interpreted in place. Using an onload function means the code and the output would appear on different pages. Sorry for any confusion.

Nested loops means that the iteration statement of one loop contains another loop. This is easiest to understand when the loop calls a function and that function happens to have a loop.


Boolean Expressions

Boolean (true/false) expressions may be used in loops or conditional statements. Generally, the more complex the stopping condition is, the more likely you should use a while loop instead of a counting (for) loop. look at the if statement again.


Array syntax

var arrayName = new Array ( numItems );
var arrayName2 = [  value1 , value2 , /* ... */ valueN ] ;

var idx = parseInt(" 3 ");
arrayName[0] = "first element";
arrayName2[idx] = 1;
alert(arrayName2[1]);
arrayName[arrayName2[idx]] = "second element";

All of the parts shown in the first version are required, except for numItems. In most languages, you not only have to specify the number of items ahead of time, but also the type of the elements in the array. JS is "friendlier", allowing you to put anything in the array and to increase the size simply by accessing an element that is not already there.

In the second version, JS knows it is a new array because you list the initial values inside square brackets. JS figures out the number of items by counting them.

Images Array


Mandango Examples

For all of these, use view the source code in a separate window while running the example.

It is important that names be selected properly for these examples to work. For example, the image for the first seat must have an id of "seat0", the next "seat1", etc. This allows the code to use a loop counter to reference all of the seats by id as: "seat" + cntr

An array of nine items is created with various true and false values. (You can change these to see if the code still works.) True means the associated seat is still available, false means it is not.

The images in the page are only given ids in the HTML code. The JS initialization function assigns the src and the alt attributes once the page is loaded.

Mandango v1









The findSeat() function is called when you click the button. It traverses the array of T/F values from beginning to end. If the seat is available, it changes the image to green and asks the user if it is accepted. If so, it leaves that seat green, otherwise it changes it back to red.

Unfortunately, the loop continues checking all seats. Of course that lets the user change his/her selection.

This is "fixed" in Mandango v2, where a break is used to exit the loop as soon as the user selects a seat.

The real goal in Mandango is to let the user select any three seats together. So, in Mandango v3, we traverse the array looking for three seats in a row that are all available.

This is accomplished by making sure seats[i] && seats[i+1] && seats[i+2] are all true.

Mandango v4 uses a while loop instead of a for loop with a break; To get the same behavior, this version sets a flag used in the loop condition and use a conditional to control execution of statements after the user "accepts" a set of seats.

The final version uses two-dimensional arrays. We will skip that topic, at least for now.


New Array Syntax

As you may have gathered, the keyword new declares something to be an array and gives it a size. It doesn't put anything into the array though. Most of the examples we have seen provide a list of initial values. Here we will use this other method and then assign a value to each location in the array.

<script>
var NUM = 5;
// declare an array with NUM elements
var myArray = new Array(NUM);

for(i=0; i<NUM; i++)
   myArray[i] = i * 2;

for(i=0; i<NUM; i++)
   alert("myArray[" + i + "] = " + myArray[i]);
</script>

The example above, may seem silly since you could have listed the values when you created the array. But it is obviously better when there are a hundred or a thousand elements! In the next example, we will put images into the array one at a time. A key step is to first tell each element that it will be an image...

  anArray[someElem] = new Image();
<body>
<img src="" alt="seat image 1" name="seatImg1" id="seatImg1" border="0">
<img src="" alt="seat image 2" name="seatImg2" id="seatImg2" border="0">
<img src="" alt="seat image 3" name="seatImg3" id="seatImg3" border="0">
<script>
var myArray = new Array(3);

for (i=0; i<3; i++)
    myArray[i] = new Image();
    
myArray[0] = "mandango/seat_avail.png";
myArray[1] = "mandango/seat_select.png";
myArray[2] = "mandango/seat_unavail.png";

alert("images are loaded");

document.getElementById("seatImg1").src = myArray[0];
document.getElementById("seatImg2").src = myArray[1];
document.getElementById("seatImg3").src = myArray[2];
</script>
</body>

Using this idea, we can rewrite the Stick Figure Adventure to use preloaded images. The advantage here is that all of the images will be requested when the page is first loaded (onLoad). That way delays in sending image across the Internet will not interfere with our scene changes. Use "view source" to see the code. note that the initial image is displayed as before (except that it is in a subdirectory).

It might be useful to look at a stripped down version of SFA. This is the kind of small test program you might create before trying a more complicated version. It includes lots of debugging alerts.

Clicking buttons seems silly in the test program, since the decision isn't used anyway. So, why not use an interval timer to change images for me.