Aquarium Lab Series    

Mini-Lab: More Fish!

Using Arrays

Alyce Brady
Kalamazoo College


This set of Mini-Lab Exercises is the fourth in a series in which students build a small program with several fish moving around in an aquarium. The set includes the following exercises:

Each section contains an Introduction to a problem or task, (usually) abridged versions of one or more Patterns that will be useful in solving the problem or completing the task, and an Exercise.

In the exercises that precede this one, students will have created three fish that move randomly back and forth in an aquarium, being careful not to hit the sides. Students should be familiar with constructing objects, invoking methods, simple selection statements, basic for loops, and the Random class.

Students should read over the patterns that appear in this document before the lab.



Becoming a Collector

Introduction

A more realistic simulation of an aquarium would have more than two or three fish. We could modify the simulation so that it supports four fish, five fish, or twelve fish in that many variables, but if we "hard-code" the number of fish into the program in this way, then we must modify and re-compile the program to change the number of fish in the aquarium. We must also repeat statements, such as the code to display and move fish, four, five, or twelve times.

A better alternative would be to ask the user how many fish to place in the aquarium and then store them in a collection object. We can use a Linear Indexed Data Structure to store the collection of fish.

Exercise

  • Modify your program to ask the graphical user interface to prompt the user for the number of fish as well as the number of simulation steps. Store the result in a local variable with an Intention Revealing Name.


    Stop and Think

    Where does it make sense to ask for the number of fish?

  • Replace the three fish you constructed earlier with a Fixed-Size Linear Indexed Data Structure of the right size to store the number of fish the user wants. What does this data structure represent? Choose an Intention Revealing Name for it.


    It is always difficult to test modified code part-way through the change. At this point, you have constructed a collection that can contain fish but doesn't yet. The rest of your program, however, still expects three named fish. In order to test that you have not introduced any syntax errors into your program, "comment out" the code that displays and moves the three fish (who no longer exist). Do this by placing the specified code in comments. For example,

      /*
              d.showFish(fish1);
              .
              .    more code to display and move fish
              .
              d.showFish(fish3);
      */
    Now compile your program just to make sure that you have created your fixed-size collection correctly. (Don't be surprised when your program no longer moves or displays fish!)



Bringing Home the Catch

Introduction

Of course, we don't see any fish, because we haven't created any.  But we do have a container to hold them.  When we create fish, we can put them directly into the Linear Indexed Data Structure.

How do we do this? And once we've put them there, how do we display one of them, or ask one for its color? We can no longer refer to each fish by name, but we can use the Indexed Random Access pattern to refer to any individual object in a Linear Indexed Data Structure. Rather than trying to create and display all the fish in the aquarium right away, though, we will start by concentrating on the first and last fish in the collection.

Exercise

  • Modify your program to put two newly constructed fish in the first and last slots in your Fixed-Size Linear Indexed Data Structure. Construct them as you did before, but instead of putting them in named local variables, insert them in your array using the Indexed Random Access pattern.


    Stop and Think

    What is the index of the last fish in the collection?

  • Next, remove the comments around the initial display of the aquarium and fish. Replace the statements displaying the three named fish with statements displaying the first and last fish in the collection. You may leave the code for moving the fish commented out for now.

  • Test your program to make sure that your program is correctly constructing and displaying two fish.



Loopy Fish

Introduction

One of the reasons we switched to using a collection object was to avoid having to duplicate code for each fish, but we currently have two lines to display the two fish.  This will not scale up well if we want to put 25 fish in the aquarium!  We can access all of the fish sequentially using the Linear Indexed Traversal pattern.

Exercise

  • Step through your Linear Indexed Data Structure using a Linear Indexed Traversal to put newly constructed fish in each slot. Even though the aquarium can now handle more fish than before, your code should be getting considerably shorter!

  • In the initial display of the aquarium and fish, replace the statements displaying the first and last fish in the collection with a Linear Indexed Traversal to display all fish. You may leave the code for moving the fish commented out for now.

  • Test your program to make sure that it correctly constructs and displays the number of fish specified by the user.



A School In Motion

Introduction

Now let's think about how to move and display all the fish for as many time steps as the user wants. 

It seems clear that we will want to loop through the steps in the simulation, as we are already doing. It also seems clear that we will want to loop through all the fish. The question is:

Processing all the fish and all the steps in the simulation are not independent of one another. That is, we can't process all the fish and then process all the simulation steps, or vice versa. Either processing all the fish is part of what we do in one step of the simulation, or running all the steps of the simulation is part of what we do for each fish. Thus, we will need to nest one of the loops inside the other.

To decide which loop gets nested inside of which, consider the following algorithmic structures in which we assume that we have 25 fish in the aquarium and we want to run the simulation 100 times.

For each fish in the collection:
        Move 100 times and display the aquarium.
For each step in the simulation:
        Move the 25 fish once and display the aquarium.

We do not want the first fish to move 100 times, followed by the second fish moving 100 times, followed by the third fish moving 100 times. Instead, we want all 25 fish to move once, then all 25 fish to move again. This corresponds to the second solution above.

Another question we have to consider is where the display of the aquarium should be relative to the fish movement. Do we want to display the fish and aquarium in the outer loop (as part of each simulation step), or in the inner loop (as part of processing each fish)? The following table illustrates these two options.

For each step in the simulation:
        For each fish in the collection:
                Move, possibly changing direction.
        Display aquarium & fish.
For each step in the simulation:
        For each fish in the collection:
                Move, possibly changing direction.
                Display aquarium & fish.

Which behavior do you wish to implement?

Exercise

  • Remove the remaining comments around the code that runs through the steps of the simulation, moving and displaying the fish in the aquarium.

  • Inside the simulation loop, replace the code that moves the three named fish with a loop that will move all the fish in your collection. (Each will still change direction when it has to or when it randomly chooses to.) Use a Linear Indexed Traversal through your Linear Indexed Data Structure of fish. You may wish to create a temporary variable in the loop to refer to the fish being processed in this iteration rather than repeatedly retrieve the same fish from the Java array.

  • Display all the fish in the aquarium with a single statement.  Research the abbreviated AquaSimGUI specification to discover how to display an indexed collection of fish. Note that this method will also display the aquarium, so you no longer need to do that separately (although you still need to "repaint" the interface and pause for the user to see the fish movement).


    Stop and Think

    Where does this statement belong? Should it be part of the inner or outer loop?

  • Update the initial display of fish in the aquarium also to display all the fish at once.

  • Test your modifications.

  • Make sure that you have updated the program documentation at the top of the file to reflect your changes.




Copyright Alyce Faulstich Brady, 2001-2002.