Programming I
CSC71001 Module 8 - Page 1
Module 8
More about Loops
Introduction
Note that it is assumed that you have completed the work up until this point, and are familiar
with creating objects, adding code, using setImage and other Greenfoot class and object
methods. If you have not completed the work up until now, please go back and make sure you
are familiar with it all, before going further.
This week we will not be using your textbook. We will instead be working on some example files
to concentrate on the mechanics of looping and using loops to produce various results.
Study materials
Materials required:
• The free Greenfoot programming environment;
• Files in "Module08" folder on MySCU site;
• Internet access to access your lecture, and any other material.
CSC71001 Module 8 - Page 2
Objectives
On completion of this topic, you should be able to:
• create and use for loops
• create and use constant values
• create use nested loops (loops within loops)
• build different patterns of objects in the world, using loops and other coding constructs
Concepts
• for loops
• initialisation
• terminating condition
• increment
• decrement
• variable++
• variable--
• constant
• static final
CSC71001 Module 8 - Page 3
Building an army
Before you start
Watch 'Concept Video 8-1 Review of Module 7
Our purpose this week will be to build an “army” of objects in various configurations, using loops.
Along the way, we will use various concepts that you have encountered in the previous modules,
as well as new concepts.
Activity 8-1 A sample scenario
Open the scenario 8-1.gfar from the MySCU site.
Write down the classes in the scenario:
____________________________________________________________________________
Open the Alien class in the editor. Fill out the comment at the top of the class. You will notice that
this class doesn't do anything (yet).
Open the SpaceWorld class. Change the comment at the top of the class to your name and your
version number.
Adding an alien
The first step is to add some aliens into our scenario.
To add objects to our world, we use the addObject method inherited from the World class.
If you check the Greenfoot documentation (Help Menu -> Greenfoot Class Documentation), you
will see the signature of the addObject method:
addObject(Actor object, int x, int y)
We can add a new Alien object at a random location in the world using the following code:
addObject(new Alien(), Greenfoot.getRandomNumber(600),
Greenfoot.getRandomNumber(400));
Activity 8-2 Adding an object
Using the scenario from Activity 8-1, add code in the SpaceWorld constructor to add one object in
a random location in the world.
Test by pressing the reset button several times.
CSC71001 Module 8 - Page 4
Adding more aliens
We could now add more aliens manually, by adding more lines of code (repeating them). There is
a simpler way to do this – a loop. If you remember in the last module we looked at while loops,
which repeat until a particular condition is true.
While loops have an initialisation, a condition that will terminate the loop when it becomes false
and an increment or decrement that will change the loop counter/variable.
A while loop always looks like this:
//declaration of a loop variable
while (condition)
{
// activity of the loop
// incrementing or decrementing the loop variable
}
An example is:
int i = 0;
int sum = 0;
while (i < 6)
{
sum = sum + i;
i = i + 1;
}
Activity 8-3
1. What would the value of sum be at the end of this loop? _____________
2. What would the value of i be at the end of this loop? ______________
3. How many times is the body of the loop executed? _______________
If we wanted to use a while loop to create a number of objects, we could combine the code that
we have used in Activity 8-2, with a while loop.
Activity 8-4 Adding several random aliens using a while loop
Using the scenario from Activity 8-2, alter the SpaceWorld constructor with a while loop to add 8
aliens in random locations in the world.
Test by pressing the reset button several times.
Watch 'Concept Video 8-2 Debugging While Loops
CSC71001 Module 8 - Page 5
Increments and Decrements
Until now, we have been adding one to the current value of a variable using:
i = i + 1;
We have been deleting one from the current value of a variable using:
i = i – 1;
Looking more carefully at this, we can see that we are querying the current value of a particular
variable, adding (or subtracting) one to it, and then storing the result in the same variable,
overwriting the previous value. This activity is so common, that there is a shortcut provided in
Java and many other languages for this operation.
i = i + 1; can be shortened to i++;
i = i – 1; can be shortened to i—-;
Our code in the SpaceWorld constructor can be shortened to:
int alienCount = 0;
while (alienCount < 8)
{
addObject(new Alien(), Greenfoot.getRandomNumber(600),
Greenfoot.getRandomNumber(400));
alienCount++;
}
Activity 8-5 Adding several random aliens using shortened code
Using the scenario from Activity 8-4, alter the SpaceWorld constructor while loop to use the simpler
increment. Test that it is still working correctly by pressing the reset button several times.
We can now refactor this code by creating a new SpaceWorld method called "createAliens".
Create a new method createAliens that does not return anything, and does not have any
parameters. Place the alien creation code in this method, and call it from the SpaceWorld
constructor. Test your code with the reset button several times.
CSC71001 Module 8 - Page 6
Many things can go wrong with While loops. If we forget to initialise the loop variable, or forget
to increment the loop variable, we can easily end up with an infinite loop, or one that does not
execute at all.
Next we are going to look at a different type of loop – a FOR loop. If you understand the
mechanics of the WHILE loop, then you shouldn’t have any trouble with the FOR loop.
FOR loops
Watch 'Concept Video 8-3 For Loops
FOR loops have this structure:
for (initialisation ; condition ; increment/decrement)
{
// body of the loop
}
The three parts that need further explanation are the:
initialisation: This takes the place of the initialisation statement that normally sits outside a while
loop. For example, we could use:
int i=0;
condition: This is the condition that when it becomes false, terminates the loop. An example:
i < 8;
increment/decrement: This is where the loop variable is increased or decreased. It doesn’t have
to be by 1 each time, but it must be included, for the for loop to progress.
An example of a FOR loop:
int myNumber = 10;
for (int i=0; i<6; i++)
{
myNumber = myNumber + i;
}
Activity 8-6 Adding several random aliens using a for loop
Using the scenario from Activity 8-5, alter the createAliens method to use a for loop. Test that it is
still working correctly by pressing the reset button several times. Make sure you comment your
createAliens method.
Non-random placement
Usually our games involving armies of enemies do not have random placement of those enemies.
An army is usually arranged in rows and columns. There is something menacing about a perfect
formation moving towards us relentlessly!
CSC71001 Module 8 - Page 7
Our next task is to alter our for loop to arrange our aliens in a line. To do this, we remove our
random number code, and instead calculate our x and y each time.
Our y value should be fixed. This will mean that our aliens all have the same height across the
screen. Our x value will change for each alien.
If our first alien is sitting at (40, 80), then the second one will be sitting at (40+a, 80) and the third
at (40+2a, 80) and so on.
How do we find the value of “a”? You can see from the diagram above that “a” is the width of the
alien graphic plus a little gap. In this case, our graphic is 60 pixels wide, so if we set our “a” as 70,
then we will place our aliens across the screen.
The first alien will be placed at (40 + 0*70, 80).
The second alien will be placed at (40 + 1*70, 80).
The third alien will be placed at (40 + 2*70, 80).
The fourth alien will be placed at (40 + 3*70, 80) and so on
We can now rewrite our for loop as:
for (int alienCount=0; alienCount < 8; alienCount++)
{
addObject(new Alien(), 40 + (70 * alienCount), 80);
}
Activity 8-7 Adding a line of aliens
Using the scenario from Activity 8-6, alter the for loop in the createAliens method, so that the aliens
are in a line. Are the aliens positioned well? If not, make adjustments until the aliens are positioned
as in the screenshot below.
40 40+a 40+2a 40+3a
CSC71001 Module 8 - Page 8
Reversing the order
We could also reverse the order that we place the alien spaceships. We could start with
alienCount at 8, and make the loop decrement (alienCount--) each time. Think about what the
condition should be within the loop statement, and the starting x value.
Activity 8-8 Adding a line of aliens
Using the scenario from Activity 8-7, alter the for loop in the createAliens method, so that the aliens
are in a line, with the right-most alien positioned first. Are the aliens positioned well? If not, make
adjustments until the aliens are positioned as in the previous screenshot.
Diagonals
We can position our aliens in a diagonal line by changing both our x and y values in each iteration
of the loop.
A first try might look like this:
for (int alienCount=0; alienCount < 8; alienCount++)
{
addObject(new Alien(), 53+(65*alienCount), 20+(65*alienCount));
}
This guesses that the first alien object will sit at (53, 20).
Activity 8-9 Adding a diagonal line of aliens
Using the scenario from Activity 8-8, alter the for loop in the createAliens method, so that the aliens
are in a diagonal line, from top left to bottom right. Make adjustments until the aliens are positioned
as in the screenshot below.
CSC71001 Module 8 - Page 9
Activity 8-10 Adding a diagonal line of aliens
Using the scenario from Activity 8-9, alter the for loop to make a diagonal from the top right to the
bottom left. Hint: you will need to decrement in the for loop.
Creating the army (part 1)
So far we have one line of aliens. We could easily add another two loops, with greater values of y,
to give us another two rows of alien objects.
public void createAliens()
{
// first row of aliens
for (int alienCount=0; alienCount < 8; alienCount++)
{
addObject(new Alien(), 48+(73*alienCount), 70);
}
// second row of aliens
for (int alienCount=0; alienCount < 8; alienCount++)
{
addObject(new Alien(), 48+(73*alienCount), 130);
}
// third row of aliens
for (int alienCount=0; alienCount < 8; alienCount++)
{
addObject(new Alien(), 48+(73*alienCount), 190);
}
}
Activity 8-11 Adding two more rows of aliens
Using the scenario from Activity 8-10, add another two for loops to make three rows of aliens.
CSC71001 Module 8 - Page 10
Repeating the repeat!
You may have noticed that we are repeating some code, with only small changes. When we do
this normally, we use a loop to cut down on code – but we are already using a loop.
We can solve this by putting a loop within a loop. This is also known as using “nested” loops
where one loop is inside another loop.
Let’s trace through an example:
int myNumber = 0;
for (int oCounter=0; oCounter<3; oCounter++) // outer loop
{
myNumber = myNumber + oCounter;
// inner loop
for (int iCounter=10; iCounter<12; iCounter++)
{
myNumber = myNumber + iCounter;
}
}
One way we can trace through this is with a tracing table.
myNumber oCounter myNumber oCounter++ oCounter<3 iCounter myNumber iCounter++ iCounter<12
0 0 0 10 10 11 True
11 21 12 False
1 True
21 1 22 10 32 11 True
11 43 12 False
2 True
43 2 45 10 55 11 True
11 66 12 False
3 False
------- --------- --------- --------- (End of loops)
myNumber would result as 66.
Activity 8-12 Loop within a loop
Using the scenario from Activity 8-10, add another loop that results in three rows of aliens.
What would you need to change to make 4 rows of aliens?
CSC71001 Module 8 - Page 11
Constants
Watch 'Concept Video 8-4 Constants
So far in this unit we have been using numbers wherever we like. For example, our initial code for
the row of aliens was:
public void createAliens()
{
for (int alienCount=0; alienCount < 8; alienCount++)
{
addObject(new Alien(), 48+(73*alienCount), 80);
}
}
If we change the size of our world, we would have to go through all our code and find all the spots
that are dependent on the size of the world. We would also have to change our code if the size of
the aliens was changed – and that would require searching through code to find which numbers
we had used that were dependent on these dimensions.
It is much better practice to use constant values that are set in one place, and then can be used
throughout. You might be thinking that you could store a value in a variable, and then use that
variable throughout your code. This is possible, but it involves the danger that the variable could
accidentally be changed.
Java provides for a static final variable that can be used as a constant. Once set, the value of this
stays the same throughout the program and cannot be changed. We usually give these constants
a name that has all capitals to distinguish these constants from normal variables.
For example, the offset from the top of the world might be called “Y_OFFSET”, and would be
declared like this:
public static final int Y_OFFSET = 80;
The rest is just like a normal variable declaration.
We would then use the constant wherever we use the y offset value:
addObject(new Alien(), 48+(73*alienCount), Y_OFFSET);
If we want to change the y offset, we can change it in one place. Other possible constants may be
X_OFFSET
X_GAP
NUM_COLUMNS
NUM_ROWS
You would declare these constants outside the methods – i.e. make them class constants.
CSC71001 Module 8 - Page 12
Activity 8-13 Using constants
Using the scenario from Activity 8-12, change your code so you are using constants for any values
that make sense.
Summary
During this topic we have built another application completely, using the techniques you have
learned previously and a few new techniques. You have used FOUR new constructs/concepts that
you will use over and over while programming:
• State variables to make decisions based on the state of an application or object at a
particular time;
• Using parameters in constructor methods to set up initial values of the object – including
the image used, and any other information needed that differs between objects;
• While loops that repeat a section of code over and over, until a given condition is false; and
• the concept of array variables that store a number of related values in one array variable.
The workshop activities are to be included in your portfolio under a separate folder “Module 8”.
CSC71001 Module 8 - Page 13
Workshop activities
Activity R8-14 Create a new scenario
Create a new scenario called ActivityR8-14. Choose a background that you like and create a new
Actor with a logical class name, using a small image (smaller than the alien image). Remember
that classes are named with a capital letter as their first letter.
Using a loop within a loop (either a for loop within a for loop, or a while loop within a while loop),
create an army of objects from the new Actor class.
You can, if you wish, offset the objects so they are exactly in a grid formation.
Activity R8-15 Your Initials
Save your scenario from ActivityR8-14 as YourNameR8-15. Using the same Class as previously,
create a frame of objects against the four sides of the World.
Create a constructor in your actor sub-class which takes an integer as a parameter. This
constructor will set an image based on the value passed to this constructor.
For example, instead of using
new Alien()
I might use
new Alien(1) or
new Alien(2)
and use the parameter to decide which image to set.
In your World class, using at least one loop, create a army of objects in the shape of the letter "M".
I can choose any type of object form the letter. If I used stars the letter M may look like this:
(Hopefully your attempt is better than mine with the stars!)
Optional extras:
You may wish to code your objects, so they change state (and spin, move, or turn) on a keypress.
To do this, you could add your objects to an array as they are created, and then loop through the
array, calling that method for each object.
You should try and use nested loops, a loop within another loop, to create the border.
Getting images:
A good place to get sprites to use for your Greenfoot projects is Google images - using the search
"sprites png" or "sprite sheet png". Of course, you need to be careful that you have permission to
use the images, but these are great to use. You can use the free online image editor at
www.pixlr.com to crop them to size.
CSC71001 Module 8 - Page 14
**** Activity R8-1 Portfolio Activity ***
The following activities assume that you have completed the previous initials Scenario
workshop activities. You will use the concepts from those activities in the next few activities.
In this activity, you will update the game you created for Assessment 2 - Practical skills. Each
activity, when it is completed, should be saved as a gfar in your portfolio folder.
Here, you will need to create a different type of food to add to your game (you already have 1 food
type with its own image).
In your Food class:
1. Create two (2) additional instance variables, which will be of Greenfoot image type. These
two variables will be used to hold images for the Food objects. The first variable can hold
the original Food image, and the second can hold the new image for your chosen theme.
2. If you do not have one already, create a default Food constructor that takes no parameters
and does not initialise any variables or properties eg: public Food(){ //no code in here }
3. Create a second Food constructor that has one integer parameter. This Food constructor
will set the image of the food to either the default image or the new food image. Passing the
value 1 as an argument will set the default image. Passing the value 2 will mean that the
second image will be set. You may refer to the concept code videos on setting up a
constructor that uses parameters.
Make sure that you test your game.
Save your scenario to your Portfolio as ActivityR8-1_rmason10.gfar. Replace rmason10 with your
username for MySCU.
**** Activity R8-2 Portfolio Activity ***
In this activity, you will continue to update your existing game created for Assessment 2 - Practical
skills. When this activity is completed, you should save it as a gfar in your portfolio folder.
In your World class;
1. Comment out or remove the while loops from Module 7.
2. Using at least one for-loop, create Food objects to form the shape of one of your initials.
Each new Food object should be created using the default Food constructor.
3. Using two nested for-loops (a loop within another loop), create a border around your scene
of Food objects. You will use one nested for-loop to create the top and the bottom border
and the other nested for-loop to create the left and right borders.
Make sure that you test your game.
Save your scenario to your Portfolio as ActivityR8-2_rmason10.gfar. Replace rmason10 with your
username for MySCU
CSC71001 Module 8 - Page 15
**** Activity R8-3 Portfolio Activity ***
This activity will update your existing game you created for Assessment 2 - Practical skills. When
this activity is completed, you should save it as a gfar in your portfolio folder.
In your World class;
1. you will need to change the default constructor calls in the for-loops to use the second Food
constructor.
2. When you call the second Food constructor, the argument you will pass will be a random
number of either 1 or 2.
Note: for testing purposes, instead of using the default new Food(), you might use new Food(1)
or new Food(2) i.e. not random. You can add random functionality to your code once tested.
Save your program in the Portfolio as ActivityR8-3_rmason10.gfar. Replace rmason10 with your
username for MySCU