FSEM 142: The Algorithmic Life
Lab 3: Loops and Choices

The third lab for FSEM 142 is Friday, October 18. On that day, the class meets in the computer lab, room Gulick 208. As usual, you should log onto your Linux account.

You will need copies of all of the files from the folder /classes/cs424/lab3. You should copy all the files from that folder into your www.folder. You will work on the HTML files lab3a.html and lab3b.html. The other files, heads.png, tails.png, and no-coin.png. are images that are used in lab3b.html.

This lab, Lab 3, will be due in two weeks, on Friday, November 1.

Lab 2 is due today. Please make sure that your completed files lab2a.html and lab2b.html are in your www folder and available for grading.

About if and while

Computer algorithms use just a few basic techniques. Two of the most essential are making choices and looping. When making a choice, the computer tests some condition that might be either true or false. If the condition is true, the computer does one thing; if it is false, the computer does something else. In JavaScript, and in many other computer languages, this type of choice is programmed using an if statement that has the form

if ( condition ) {
    some-commands
}
else {
    other-commands
}

When you write an if statement, replace condition with a test such as guess < number or count == 500. You can compare values using the operators ==, !=, <, >, <=, and >. The operator == tests whether two things are equal, and != tests whether they are not equal. Where some-commands appears above, you should type the commands that you want the computer to execute when the condition is true. Where other-commands appears, you should type the commands that you want to execute when the condition is false. For example, here is an if statement that simulates flipping a coin. The function Math.random() returns a randomly selected real number in the range 0.0 to 1.0, so there is a 50/50 chance that the value is less than 0.5:

if ( Math.random() < 0.5) {
    alert("Heads");
}
else {
    alert("Tails");
}

This command has just one command in each part of the if statement, but you can have as many as you want. You can even have loops and other if statements inside an if statement.

You can leave out the second part of an if statement, starting with "else". When you do that, the if stament has the form:

if ( condition ) {
    some-commands
}

In this case, the if statement does nothing at all when the condition is false


A loop is used to repeat a sequence of commands. One way of doing this is with a while statement. To avoid repeating the commands forever — a situation called an "infinite loop" — there has to be some way to break out of the loop. That is done with a break statement. When a break statement is executed in a loop, the computer leaves the loop and jumps to whatever command follows the end of the loop. Usually, a break statement will be used inside an if statement, so the loop will only be broken if the condition in the if statement is satisfied. Here is the form of the while loop that we will use:

while (true) {

    some-commands

    if ( condition ) {
        break;
    }
    
    some-commands
    
}

Note that the commands that are to be repeated are enclosed between { and }. This doesn't show all the options. For example, you can have more than one if statement, with more than one break, and a break could come inside the else part of an if statement. And the if statement with the break might come at the beginning or at the end of the while loop, instead of in the middle.

As an example, suppose that we want to simulate tossing a coin 1000 times, and we want to count the number of times that the simulated coin comes up heads. We can use a variable to count the number of coin tosses, and the condition for breaking the loop is that that counter reaches 1000. We will need another counter variable to count the number of heads.

var numberOfTosses = 0;
var numberOfHeads = 0;

while (true) {
    if ( Math.random() < 0.5) { call it a head
        numberOfHeads = numberOfHeads + 1; // goes up by 1 sometimes
    }
    numberOfTosses = numberOfTosses + 1; // always goes up by 1
    if (numberOFTosses == 1000) {
        break;
    }
}

alert("The number of heads was " + numberOfHeads);

Exercise 1: Random Art

For exercise 1, you should edit the file lab3a.html. Before you start, the page has one button, and clicking that button will call the function lines(). The function clears the canvas to a white background, draws 500 random lines, and draws a black border around the edges of the canvas. There is a graphics context named graphics for use in drawing on the canvas, with all the functions that were documented in Lab 2. There are also several new functions for this lab. These are stand-alone functions, not part of graphics:

You can find examples of using all three functions in the definition of lines().

To begin the lab, you should try making some changes to lines() to see their result. Here are some things that you can try:

For the first part of this exercise, you should modify the definition of lines() using some combination of these ideas to define your own customized line art.


To complete the exercise, you should add three more buttons to the page, and add three new functions to be called by the new buttons. Each function should draw a different kind of random art. You can use different shapes, including rectangles, squares, circles or ovals that are filled or stroked or both. You might use more complicated shapes, such as a filled circle with a smaller filled circle of a different color inside it. You might use some text instead of shapes. You might use some transparency. And of course, you should use randomness in various places. Try to make pictures that look nice! (One example: Draw stroked squares, all of the same size and color, with a wide stroke, using transparency, on a dark or randomly colored background.)

Furthermore, the last button should draw a mixture of two different kinds of shapes. Use an if statement inside the while loop to decide, at random, which kind of shape to draw for that particular execution of the loop.

Note on drawing squares and rectangles: You will get better, more symmetrical results if you select the center at random rather than select the upper left corner at random. To draw a filled rectangle with center at the point (centerX,centerY), with width width, and with height height, use the command:

graphics.fillRect( centerX - width/2, centerY - height/2, width, height);

Exercise 2: Coin Flip

For exercise 2, you should edit the file lab3b.html. The page has a button and an image of a question mark, given by the image file no-coin.png You will program the button to simulate flipping a coin, getting either heads or tails. After the coin is flipped, one of the images heads.png or tails.png should appear where the question mark image is now.

You need to write a function to be called by the button. As a first step, that function should simply replace the current image on the page with either the heads or the tails image, selected at random. Do that much and try it out!

A problem with this is that half the time, the new image will be the same as the old image, and it will look to the user as if nothing has changed. To finish the exercise, you should fix this problem: Instead of showing heads or tails as soon as the user clicks the button, you should show the question mark image for a short time; at the end of that time, the question mark image should be replaced by either the heads image or the tails image. There is no way to do this in one function. You need two functions. The first function, which is called by the button, should put the question mark image on the page and start a timer. When the timer expires, it will call another function. That function should replace the image with either the heads image or the tails image. (Remember that you already used a timeout in the second exercise of Lab 2, and you saw how to change the src of an image in the first exercise of that lab.)

Furthermore, the user should not be able to click the button again while all this is happening. For that, you should disable the button in the first function and enable it in the second function. To disable the button, which has id="flipper", use the command

document.getElementById("flipper").disabled = true;

and to enable it again, use the command

document.getElementById("flipper").disabled = false;

(If you can figure out how to do it, you might want to make the image rapidly change many times before it finally settles to heads or tails. Use a global variable as a counter. When the user clicks the button, set the counter to zero, change the image, and set a timeout. When the timeout expires, the counter goes up by one. When it reaches a certain value, you want to put in the final image and stop the process; otherwise, you want to start a new timeout. Don't forget to disable/enable the button at the start/end of the process.)