Blue Pelican Java: Graphical Labs Student Manual
Blue Pelican Java: Graphical Labs Student Manual
Graphical Labs
Student Manual
• Beginning Java students ARE able to do the labs early in the course even if they are
using a Java textbook like Blue Pelican Java in which the subject of classes and
objects are deferred until later in the course.
• Students are highly motivated by the graphical results of their programs – even
small programs that might only involve a simple if statement.
(The remainder of this installation chapter might be uncomfortable for some beginning/
inexperienced students, so it is suggested that the instructor do the installation for each student
computer.)
The first step of the installation will be to go to the following College Board web page:
http://www.collegeboard.com/student/testing/ap/compsci_a/case.html
• Code (zip/238kb) …Create a folder called GridWorldDownloads and place this file
there. Unzip and place the resulting code in a folder named C:\GridWorldCode.
o Eclipse 3.1
GS -2
o JCreator 3.5 (Windows only) From the menu select Project | Project
Properties. Click the Required Libraries tab and click New. In the Set Library
dialog box, click the Add button, select Add Archive, then browse to add the
JAR file that resides in the GridWorldCode folder. Give the new library a
name. Finally, click the checkbox for the new library and click OK.
o JJ (Windows only)
rock1.setColor(Color.BLACK);
Place these two source code files (BasicBugRunner.java and BasicBug.java) on your hard
drive in a sub folder of GridWorldProjects named BasicBug. The hierarchal folder structure is
as follows:
C:
GridWorldProjects
BasicBug
BasicBugRunner.java
BasicBug.java
.
.
… other student project folders created as the
… course progresses
.
.
GridWorldDownloads
GridWorldProjects
BasicBug
DG-1
Demonstrating GridWorld
Fig DG-1.
GridWorld,
BasicBugRunner
graphical interface
Experiment:
Click on the Step button a couple of times and observe the bug moving forward.
Now click on any empty cell and get a display similar to the following:
Click on one of the items in the drop-down menu and add another bug, flower, or
rock to the grid at this grid location. Continue experimenting with the controls in
this graphic interface and the following facts will soon become apparent:
• Each time the Step button is clicked, the Bug advances one cell, leaving
behind a flower of the same color as the bug. Each time the bug advances,
each flower in it’s “flower trail” becomes progressively darker, thus
showing their age.
• If the bug encounters an obstacle (the black rock in Fig. DG-1) or the edge
of the grid, instead of moving forward, it turns 45 degrees clockwise. If it
still can’t move, it turns another 45 degrees. This turning continues until it
can move forward.
• Clicking the Run button results in the bug continuing to step with a delay
between steps determined by the Slow/Fast slider.
• The Stop button is only active after Run is clicked. It stops the Run
process.
Making changes:
Clicking on an object such as a bug, rock, or flower results in the following drop-
down menu.
Why did the creators of this class do it that way? Supposedly, it is because this is
conventionally how navigation of ships and aircraft is done (north is 0 degrees
with positive angles rotating clockwise.), and here in GridWorld we are
“navigating” the grid.
Continue to experiment:
Continue to experiment by creating new objects in the grid. Then click on those
objects to change their properties. The student should become aware that this is an
effective learning technique – experimenting.
BL 1 - 1
Create the project with Project | New project, being careful to create this
project within the C:\GridworldProjects folder. Then bring in two classes
mentioned above with Project | Import (Navigate to the
C:\GridWorldProjects\BasicBug folder and then click Import.)
import info.gridworld.actor.Bug;
public class BasicBug extends Bug
{
//Unique code for each lab to be placed here
}
Shortly, we will be replacing the rem with code of our own using a boolean AND
within an if statement.
canMove( )
All we need to know is that this returns a boolean. It will be true if the bug
sees no obstacle in front of it. A false will be returned if the bug can’t
move forward; perhaps another bug or rock is in its path, or it’s at the edge
of the grid.
move( )
This method simply moves the bug forward one cell.
turn( )
The bug faces a new direction by turning 45 degree clockwise.
BL 1 - 2
import info.gridworld.actor.Bug;
public class BasicBug extends Bug
{
public void act( ) // Executes each time the Step button is clicked.
{
if( canMove( ) ) // Is it ok to move?
{
move( ); //canMove( ) is true, so move forward.
}
else
{
turn( ); //Turn 45 deg clockwise if move is blocked.
}
}
private int count = 0; //Use count to determine the number of steps.
}
At this point, do not concern yourself with the peculiarities concerning the
position and syntax of private int count. Just simply think of count as a variable
with which we will count-off three steps before turning.
Our job here is to replace the boolean canMove( ) with the appropriate boolean
expression that will look for an additional reason to turn the bug. What we want
is for the bug to only move forward if both canMove( ) is true and the bug has
moved no more than three spaces since beginning its movement or since the last
turn.
Hint: Use a boolean AND in the parenthesis of the if. Use the ++ operator to
increment count appropriately.
BL 2 - 1
Create the project with Project | New project, being careful to create this
project within the C:\GridworldProjects folder. Then bring in two classes
mentioned above with Project | Import (Navigate to the
C:\GridWorldProjects\BasicBug folder and then click Import.)
import info.gridworld.actor.Bug;
public class BasicBug extends Bug
{
//Unique code for each lab to be placed here
}
Shortly, we will be replacing the rem with code of our own using a boolean and
an if-else statement.
canMove( )
All we need to know is that this returns a boolean. It will be true if the bug
sees no obstacle in front of it. A false will be returned if the bug can’t
move forward; perhaps another bug or rock is in its path, or it’s at the edge
of the grid.
move( )
This method simply moves the bug forward one cell.
turn( )
The bug faces a new direction by turning 45 degree clockwise.
BL 2 - 2
Our job here is to replace the rems in the code below so as to modify the bug’s
behavior as follows:
For each click of the Step button move forward one cell if it’s ok to move;
otherwise turn 135 degrees (using turn( ) several times). Then repeat the
entire process. Thus, it is possible to move forward two cells with a single
click of the Step button. Notice that with this scheme it is also possible for no
move to be made if the bug is sufficiently blocked.
It is important to know that all of the code inside the act method executes
each time the Step button is clicked.
import info.gridworld.actor.Bug;
public class BasicBug extends Bug
{
public void act( ) //Executes each time the Step button is clicked.
{
//Use canMove( ) to decide if it’s ok to move. Use move( )
//to move forward one cell. Use turn( ) to turn. Recall that a
//single execution of turn( ) is just 45 deg clockwise.
}
}
BL 3 - 1
BugLab 3 – Using switch & modulus (Blue Pelican Java Lesson 10)
(Teacher: Although students may not yet be well versed with the meaning of the term
“method”, it is used below. As a result, hopefully, the student will become accustomed to
hearing the term and feel more comfortable when the creation of methods is explored in
future lessons.)
Create the project with Project | New project, being careful to create this
project within the C:\GridworldProjects folder. Then bring in two classes
mentioned above with Project | Import (Navigate to the
C:\GridWorldProjects\BasicBug folder and then click Import.)
import info.gridworld.actor.Bug;
public class BasicBug extends Bug
{
//Unique code for each lab to be placed here
}
Shortly, we will be replacing the rem with code of our own using a switch
structure.
canMove( )
All we need to know is that this returns a boolean. It will be true if the bug
sees no obstacle in front of it. A false will be returned if the bug can’t
move forward; perhaps another bug or rock is in its path, or it’s at the edge
of the grid.
move( )
This method simply moves the bug forward one cell.
turn( )
The bug faces a new direction by turning 45 degree clockwise.
BL 3 - 2
import info.gridworld.actor.Bug;
import java.awt.Color;
public class BasicBug extends Bug
{
public void act( ) // Executes each time the Step button is clicked.
{
if( canMove( ) ) // Is it ok to move?
{
move( ); //canMove( ) is true, so move forward.
}
else
{
turn( ); //Turn 45 deg clockwise if move is blocked.
}
}
private int count = 0; //Use count to determine the number of steps.
}
At this point, do not concern yourself with the peculiarities concerning the
position and syntax of private int count. Just simply think of count as a variable
that counts the number of steps taken.
Our job here is to keep a running count of the number of steps taken by the bug
(by incrementing count appropriately) and to change the color of the bug
(depending on which step it is on) according to the following rules:
After the 1st step, change the bug to a blue color, green after the 2nd step,
yellow after the 3rd step, red after the 4th step, and back to orange (the
bug’s original color) after the 5th step. Continue by repeating this cycle.
Accomplish the color changes with setColor(Color.GREEN), etc.
Create the project with Project | New project, being careful to create this
project within the C:\GridworldProjects folder. Then bring in two classes
mentioned above with Project | Import (Navigate to the
C:\GridWorldProjects\BasicBug folder and then click Import.)
import info.gridworld.actor.Bug;
public class BasicBug extends Bug
{
public void act( ) //Executes each click of the Step button.
{
if( canMove( ) )
{
move( );
}
else
{
turn( );
}
}
}
canMove( )
All we need to know is that this returns a boolean. It will be true if the bug
sees no obstacle in front of it. A false will be returned if the bug can’t
BL 4 - 2
move forward; perhaps another bug or rock is in its path, or it’s at the edge
of the grid.
move( )
This method simply moves the bug forward one cell.
turn( )
The bug faces a new direction by turning 45 degree clockwise.
Our job here is to make the bug turn 45 degree counter clockwise when it
can no longer move in its forward direction. This will be done by
replacing the single turn in the code above with multiple turns. These
multiple 45 degree clockwise turns should bring the bug to the eventual
direction that is equivalent to a single turn of 45 degree counter clockwise.
Instead of replacing the single turn in the code above with multiple turn’s,
create a for loop that executes turn the appropriate number of times.
BL 5 - 1
Create the project with Project | New project, being careful to create this
project within the C:\GridworldProjects folder. Then bring in two classes
mentioned above with Project | Import (Navigate to the
C:\GridWorldProjects\BasicBug folder and then click Import.)
import info.gridworld.actor.Bug;
public class BasicBug extends Bug
{
//Unique code for each lab to be placed here
}
}
}
Our job here is to redo Lab2 in which we “tried” to make the bug move forward
two times with each click of the step button. There we discovered that we were
unable to guarantee two moves since with each attempted move we might have
needed to turn the bug, instead. Now that we have the while loop in our arsenal of
Java weapons, it is possible to guarantee two moves with each Step button click.
BL 5 - 2
Hint: In the act method place a while loop that stays in the loop as long as
canMove is false, and inside the loop place the turn method. When canMove is
true, the loop is exited and it is safe to move the bug. This all ensures that the first
move will definitely be done after any and all necessary turns. Repeat the entire
process to ensure the second move.
BL 6 - 1
Modify BasicBug:
Modify the source code for BasicBug as shown below. This will cause the bug to
exhibit the default behavior (moving forward one cell for each click of the Step
button or turning clockwise 45 degree if a move is not possible):
import info.gridworld.actor.Bug;
public class BasicBug extends Bug
{
public void act()
{
if( canMove( ) )
{
move( );
}
else
{
turn( );
}
}
}
Notice that rows are numbered from top to bottom with 0 being the index of the
top row. Columns are numbered from left to right with 0 being the index of the
far left column.
BL 6 - 2
Fig.BugLab6-1
Initial positions of the three
objects.
The existing code for BasicBugRunner is shown below. Study it to see how the
bug1 and rock1 objects are created and placed in the grid at certain locations.
Then in a similar way modify the code to produce the three colored objects in the
locations specified above.
//This class will not compile until the BasicBug class first compiles.
import info.gridworld.actor.ActorWorld;
import info.gridworld.grid.Location;
import java.awt.Color;
import info.gridworld.actor.Rock;
public class BasicBugRunner
{
public static void main(String args[])
{
ActorWorld world = new ActorWorld( );
BasicBug bug1 = new BasicBug( ); //Create and set color of bug1
bug1.setColor(Color.ORANGE);
(Teacher: Refer to Labs 4 and earlier for a detailed discussion of the various GridWorld
methods used in these labs (act, canMove, move, & turn). If the students have done the
previous labs, then they should already be accustomed to the use of these methods.)
Modify BasicBug:
Modify the source code for BasicBug as shown below. This will cause the bug to
exhibit the default behavior (moving forward one cell for each click of the Step
button or turning clockwise 45 degree if a move is not possible):
import info.gridworld.actor.Bug;
public class BasicBug extends Bug
{
public void act( )
{
if( canMove( ) )
{
move( );
}
else
{
turn( );
}
}
}
Run the main method in BasicBugRunner and the resulting display should be as
follows (notice the green bug turned 45 X 3 = 135 degrees):
(Teacher: Refer to Labs 4 and earlier for a detailed discussion of the various GridWorld
methods used in these labs (act, canMove, move, & turn). If the students have done the
previous labs, then they should already be accustomed to the use of these methods.)
Create BasicBugB:
Modify the source code for BasicBug and rename it BasicBugB as shown below.
This will cause the bug to exhibit the default behavior (moving forward one cell
for each click of the Step button or turning clockwise 45 degree if a move is not
possible). Notice that the constructor allows the bug to have a name (bugName):
import info.gridworld.actor.Bug;
import java.awt.Color;
public class BasicBugB extends Bug
{
public BasicBugB(String nm) //Constructor
{
bugName = nm;
}
Create BasicBugA:
Create another class called BasicBugA as shown below (just copy and paste):
BL 8 - 2
import info.gridworld.actor.Bug;
import info.gridworld.grid.Location;
import info.gridworld.grid.Grid;
import info.gridworld.actor.*;
public class BasicBugA extends Bug
{
public BasicBugA(String nm)
{
name = nm;
}
//Modifications go here
}
else
turn( );
}
else
turn( );
}
}
public String name;
}
Do not be concerned with all the complicated looking code in bold. All it does is
determine if the cell directly in front of our BasicBugA object contains a BasicBugB
object. If so, the name of that BasicBugB object is stored in adjacentBugName.
BL 8 - 3
//This class will not compile until the other two classes first compile.
import info.gridworld.actor.ActorWorld;
import info.gridworld.grid.Location;
import java.awt.Color;
import info.gridworld.actor.Rock;
public class BasicBugRunner
{
public static void main(String args[])
{
ActorWorld world = new ActorWorld( );
BasicBugA bug1 = new BasicBugA("Buster Bug");
bug1.setColor(Color.RED);
Run the main method in BasicBugRunner and the resulting display should be as
follows:
BL 8 - 4
Now click on the red bug (right one) and then select setDirection. Enter 270 in the
resulting dialog box so as to face this BasicBugA bug toward the left. The two
bugs should now be facing each other. Since our red bug’s name is alphabetically
less than the name of the left bug, the code should tell him to turn 180 degrees and
retreat.
What change would you make to the code so as to cause the BasicBugA object to
retreat when its name is alphabetically greater than the other bug’s name?
Continue to experiment by moving the bugs’ locations and directions and see if
all the rules we have established are being followed.
BL 8 - 5
The returned String is of interest to us in this lab and for the particular location
shown in Fig. BugLab9-1 is:
BasicBug[location=(2, 0),direction=270,color=java.awt.Color[r=255,g=200,b=0]]
//This class will not compile until the BasicBug class first compiles.
import info.gridworld.actor.ActorWorld;
import info.gridworld.grid.Location;
import java.awt.Color;
import info.gridworld.actor.Rock;
public class BasicBugRunner
{
public static void main(String args[])
{
ActorWorld world = new ActorWorld( );
BasicBug bug1 = new BasicBug( );
bug1.setColor(Color.ORANGE);
In the area labeled, “Modification go here”, insert code that will manipulate the
returned String mentioned above, and then print to the console screen a summary
of its contents in exactly the following format:
location=(2, 0)
direction=270
color=[r=255,g=200,b=0]
Use Scanner to parse the String into three sections and then further refine those
pieces as shown above. Build an appropriate delimiter for your Scanner object
using regular expressions. For the sake of Scanner, remember to import
java.util.*.
BL 10 - 1
(Teacher: Refer to Labs 4 and earlier for a detailed discussion of the various GridWorld
methods used in these labs (act, canMove, move, & turn). If the students have done the
previous labs, then they should already be accustomed to the use of these methods.)
Modify BasicBug:
The BasicBug class should be changed to include the following:
import info.gridworld.actor.Bug;
import info.gridworld.grid.Location; //Necessary for the Location object below
import java.util.*;
public class BasicBug extends Bug
{
public void act( )
{
if(canMove( ))
{
move( );
Location loc = getLocation( );
int r = loc.getRow( ); //r and c are the row and column to
int c = loc.getCol( ); //which we just moved.
step++;
//<#1>
}
else
{
turn( );
}
}
//<#2>
public int step = 0; //Keeps a running count of the steps.
}
BL 10 - 2
For each move, store into this array the row and column number of the new cell to
which we moved. Each element of the String array is formatted with a parenthesis
surrounding row and column numbers that are, in turn, separated by a comma: for
example, “(12, 3)”. Notice in the code above that the row and column are already
provided in the variables r and c.
As the count variable step advances, use it as the index for storing the formatted
row-column position into the array. Then print the array using Arrays.toString as
follows (place all this code in the <#1> area above):
System.out.println( Arrays.toString(history) );
In Fig BugLab10-1 below we see four printouts of the resulting history array after
each of four executions of move. After the first move the bug is in row 4, column
3 and after the fourth move, it is in row 1, column 4. Notice the first element of
the history array is still null since we are not yet making provisions for entering
data for the starting position.
Modify BasicBugRunner:
Add code to the bottom of the BasicBugRunner class so as to fill the element of
the String array at index 0 with the initial position of the bug.
BL 11 - 1
(Teacher: Refer to Labs 4 and earlier for a detailed discussion of the various GridWorld
methods used in these labs (act, canMove, move, & turn). If the students have done the
previous labs, then they should already be accustomed to the use of these methods.)
Modify BasicBug:
Start with the following default code in the BasicBug class:
public void act()
{
if(canMove( ))
{
move( );
}
else
{
turn( );
}
}
(Teacher: Refer to Labs 4 and earlier for a detailed discussion of the various GridWorld
methods used in these labs (act, canMove, move, & turn). If the students have done the
previous labs, then they should already be accustomed to the use of these methods.)
2, 5
4, 3
To input the file, place the following code in the BasicBugRunner class prior to
where world.add is used to add the two BasicBug objects to the grid.
Notice that by having placed data_Lab13.txt in the same folder as our project,
there is no need to reference it with a path. The use of File makes it necessary
to place throws IOException at the end of the main method signature. It will also
BL 13 - 2
After the execution of this code the contents of the text[] array will be as follows:
Next, create a new Scanner object and set an appropriate delimiter. Parse these
two Strings into the integer variables r1, c1, r2, and c2, and then use these
variables to position bug1 and bug2 in the grid with world.add.
There is no need to modify the BasicBug class. It inherits the needed code from
Bug via extends Bug.
Run main to see the properly positioned bug objects as shown below.
Modify BasicBugRunner:
At the very bottom of the BasicBugRunner class, add the following code that will
create and write to a file on your hard disk:
FileWriter fw = new FileWriter(<#1>); //Student adds code here.
PrintWriter output = new PrintWriter(fw);
<#2> //Student adds code here.
output.close( );
fw.close( );
The presence of FileWriter and PrintWriter will make it necessary to import the
java.io.* package. Also, the possibility of a checked exception make it necessary
to append throws IOException to the main method signature.
There is no need to modify the BasicBug class. It inherits the needed code from
Bug via extends Bug.
In the area of <#2> use the println method of the output object to describe first the
bug1 object and then the rock1 object. The description of each is provided with
their toString methods. Thus the area of <#2> should consist of two lines of code.
Run main and then from within Windows Explorer, check the contents of
outputFile.txt. It should be as follows:
BasicBug[location=(5, 3),direction=0,color=java.awt.Color[r=255,g=200,b=0]]
info.gridworld.actor.Rock[location=(1, 3),direction=0,color=java.awt.Color[r=0,g=0,b=0]]
BL 15 - 1
Modify BasicBug:
Make the following changes to BasicBug. All additional code for this lab will be
done in the area of <#1> below where the bug’s color will be changed when a
move is not possible and a turn is being executed.
import info.gridworld.actor.Bug;
import java.util.*; //Necessary for Scanner
import java.awt.Color; //necessary for the Color class to be used below
public class BasicBug extends Bug
{
public void act( )
{
if(canMove( ))
{
move( );
}
else
{
turn( );
String s = toString( );
//sample,
//"BasicBug[location=(2,3),direction=45,color=java.awt.Color[r=255,g=200,b=0]]"
}
}
}
components of the bug’s color. This can be done in sections as follows in the area
of <#1> in the code above:
int i = s.indexOf("[r="); // The "[" is necessary or it will find "r=" preceeding awt
s = s.substring(????); //Chop off everything prior to "r=".
//sample result , "r=255,g=200,b=0]]"
s = s.substring(?????); //Remove the trailing two square brackets.
//sample result, "r=255,g=200,b=0"
//Red color
String rString = sc.?????;
rString = rString.substring(??); //Remove "r="
int r = ?????; //Convert to int
//Green color
String gString = sc.?????;
gString = gString.substring(??); //Remove "g="
int g = ?????; //Convert to int
//Blue color
String bString = sc.?????;
bString = bString.substring(??); //Remove "b="
int b = ?????; //Convert to int
Bitwise AND the r, g, and b values and then bitwise OR that result with
the decimal equivalent of the binary String, "10101010". The final result then
becomes the new value for int newValue that establishes the new color of the bug
as follows:
Run main, step the bug, and observe the color change as the bug turns.
BL 16 - 1
(Teacher: Refer to Labs 4 and earlier for a detailed discussion of the various GridWorld
methods used in these labs (act, canMove, move, & turn). If the students have done the
previous labs, then they should already be accustomed to the use of these methods.)
Modify BasicBug:
This lab is essentially the same as BugLab15 except the color portion of the String
is to be located with Scanner’s findInLine method. Change the BasicBug class as
follows and note that further changes will be made in the area of <#1>:
import info.gridworld.actor.Bug;
import java.util.*; //Necessary for Scanner
import java.awt.Color; //Necessary for the Color class used below
public class BasicBug extends Bug
{
public void act( )
{
if(canMove( ))
{
move( );
}
else
{
turn( );
String s = toString( );
//sample, "BasicBug[location=(2, 3),direction=45,color=java.awt.Color[r=255,g=200,b=0]]"
sc.useDelimiter(",");
BL 16 - 2
//Red color
String rString = sc.next( );
rString = rString.substring(2); //Remove "r="
int r = Integer.parseInt(rString); //Convert to int
//Green color
String gString = sc.next( );
gString = gString.substring(2); //Remove "g="
int g = Integer.parseInt(gString); //Convert to int
//Blue color
String bString = sc.next( );
bString = bString.substring(2); //Remove "b="
int b = Integer.parseInt(bString); //Convert to int
String s1 = "10101010";
int val_s1 = Integer.parseInt(s1,2); //Covert the binary String to decimal
int newValue = (r & g & b) | val_s1;
Modify BasicBug:
Make the following changes to BasicBug. All additional code for this lab will be
done in the area of <#1> below where the bug’s color and direction will be
randomly changed. Note that this is the area where a turn of 45 degrees was
executed in earlier labs.
import info.gridworld.actor.Bug;
import java.util.*; //Necessary for Random
import java.awt.Color; //Necessary for the Color class to be used below
public class BasicBug extends Bug
{
public void act( )
{
if(canMove( ))
{
move( );
}
else
{
<#1> //Randomly change color and direction here
}
}
}
The new direction of the bug is determined with setDirectin(dir) where dir is a
random integer between 0(inclusive) and 359(inclusive). Recall that as a
navigational angle, north is 0, east is 90, etc.
Run main, step the bug, and observe the color and direction randomly change each time
the bug needs to turn.
BL 18 - 1
(Teacher: Refer to Labs 4 and earlier for a detailed discussion of the various GridWorld
methods used in these labs (act, canMove, move, & turn). If the students have done the
previous labs, then they should already be accustomed to the use of these methods.)
Modify BasicBug:
Make the following changes to BasicBug. Determine the location of the bug and
then determine from its location how many times to turn the bug if a move is
blocked.
import info.gridworld.actor.Bug;
import info.gridworld.grid.Location; //Necessary for Location class below
public class BasicBug extends Bug
{
public void act( )
{
if(canMove( ))
{
move( );
}
else
{
Location loc = getLocation( ); //Get the Location object describing the
int row = loc.getRow( ); //current position of the bug.
int col = loc.getCol( );
<#1>
Run main, step the bug, and observe the bug turning according to these rules.
BL 19 - 1
Modify BasicBug:
In this lab we want the bug to turn only if both canMove is true and the cell to
which we are to move has not been visited by this bug earlier. A two-dimensional
boolean array corresponding cell by cell to the graphical grid will keep a record of
visits to each cell. To prepare for this, make the following changes to BasicBug:
import info.gridworld.actor.Bug;
import info.gridworld.grid.Location; //Necessary for Location class below
public class BasicBug extends Bug
{
public void act( )
{
//Get the row and col of the position to which we will try to move.
int rowIndex = -1;
int colIndex = -1;
Location loc = getLocation();
if(canMove( )) //Test to see if adjacent cell is valid for a move
{
loc = loc.getAdjacentLocation(getDirection());
rowIndex = loc.getRow( );
colIndex = loc.getCol( );
}
//Only move if not blocked and the cell lying ahead has not been visited
if( canMove( ) && <#1>) )
{
move( );
//Store true in the array to indicate current cell has been visited.
<#2>
BL 19 - 2
}
else
{
turn( );
}
}
Fill in code for area <#1> above so as to provide a boolean value of false if the
grid cell corresponding to visitedCell[row][col] has not yet been visited.
Finally, in code area <#2> store a true in the appropriate cell of the visitedCell
array. Thus, a true in any particular cell will indicate that the corresponding grid
cell has been visited by the bug.
Run main, step the bug, and observe the bug moving and turning according to these rules.
BL 20 - 1
Modify BasicBug:
In this lab we will leave the fundamental act method intact; however, we will
override the turn method in the Bug class (inherited here via extends Bug) by
creating a new turn method with code of our own. Notice the skeleton of the turn
method in the code below where we will eventually place new code.
import info.gridworld.actor.Bug;
public class BasicBug extends Bug
{
public void act( )
{
if(canMove( ))
{
move( );
}
else
{
turn( );
}
}
the new direction. Otherwise, subtract 135 degrees and set that as the new
direction.
Hint: The method getDirection returns an integer value in degrees that is the
current direction of the bug. Likewise, the setDirection method receives an int
type parameter and determines a new direction for the bug.
Run main, step the bug, and observe that the old default behavior of turning 45 degrees
clockwise has been replaced with this new behavior.
BL 21 - 1
import info.gridworld.actor.Bug;
import java.awt.Color;
public class BasicBugRed extends Bug
{
Create SuicideBug:
Create a SuicideBug class as shown below. Notice that the default behavior of a
simple 45 degree turn when a move is not possible has now been replaced with
more complicated code. Also notice that the default constructor automatically sets
the color to green:
import info.gridworld.actor.Bug;
import info.gridworld.grid.Location;
import info.gridworld.grid.Grid;
import info.gridworld.actor.*;
import java.awt.Color;
public class SuicideBug extends Bug
{
public SuicideBug( )
{
//Constructor automatically sets color to green
setColor(Color.GREEN);
}
//Modifications go here
}
else
turn( );
}
}
}
BL 21 - 3
Do not be concerned with all the complicated looking code in bold. All it does is get the
object directly in front of us and store it in adjacentNeighbor.
//This class will not compile until the BasicBug class first compiles.
import info.gridworld.actor.ActorWorld;
import info.gridworld.grid.Location;
import java.awt.Color;
import info.gridworld.actor.Rock;
public class BasicBugRunner
{
public static void main(String args[])
{
ActorWorld world = new ActorWorld( );
Continue clicking the Step button until the bug positions are as shown below:
At this point it would seem that the green bug is about to eliminate itself because
it is unable to move and it is an object of type BaiscBugRed that is blocking its
movement. Click Step again, and to our surprise the green bug does not eliminate
itself. Why?
The reason is that when Step is clicked either the red bug’s act method or the
green bug’s act method will execute first. In this case it is the red bug that moves
first; therefore, after it moves the green bug no longer sees an obstacle.
Run the code again and advance the bugs to the state of the last picture above.
Then click on the red bug and set a new direction of 180 degrees. The red bug will
still act first; however, instead of moving, it will now turn. Then when the green
bug finally acts it will see the red bug directly in front of it and will eliminate
itself.
Continue to experiment by clicking on empty cells and creating more red and blue
bugs. Watch them interact with the green SuicideBug bug as the Step button is
clicked, and finally observe the SuicideBug object eliminate itself according to the
rules we have established.
BL 22 - 1
Modify BasicBugRunner:
The new BasicBugRunner class will be exactly the solution to BugLab14 where
the properties of the bug in its initial position are written to a disk file. Recall that
the toString method provides the needed information about the bug.
import info.gridworld.actor.ActorWorld;
import info.gridworld.grid.Location;
import java.awt.Color;
import info.gridworld.actor.Rock;
import java.io.*; //Necessary for FileWriter, PrintWriter, & IOException
public class BasicBugRunner
{
public static void main(String args[]) throws IOException
{
ActorWorld world = new ActorWorld( );
BasicBug bug1 = new BasicBug( );
bug1.setColor(Color.ORANGE);
Rock rock1 = new Rock( );
rock1.setColor(Color.BLACK);
world.add(new Location(5,3), bug1);
world.add(new Location(1, 3), rock1);
world.show( );
Each time we write to the file in the act method, we will need to write in the
append mode; otherwise, each new submission to the file would simply overwrite
whatever was already present in the file. To accomplish all this, place the
following code at the very bottom of the act method in the BasicBug class.
Notice that the FileWriter constructor is sent two arguments. The first is the file
name and the second is true which indicates the append mode.
After placing this code at the bottom of act, it will be discovered that the class
will not compile. Normally we could simply append throws IOException to the
act method signature. Upon doing this we again discover that the class won’t
compile. This is because we are overriding the act method in the inherited Bug
class, and that original method did not use throws IOException.
The only way out of this dilemma is to place the above code in a try block. The
corresponding catch statement should print the following sentence and then stop
execution of the program.
Run main, step the bug several times, and display(using Note Pad or Word Pad) the text
file that is produced. The results should be similar to the following:
BasicBug[location=(5, 3),direction=0,color=java.awt.Color[r=255,g=200,b=0]]
BasicBug[location=(4, 3),direction=0,color=java.awt.Color[r=255,g=200,b=0]]
BasicBug[location=(3, 3),direction=0,color=java.awt.Color[r=255,g=200,b=0]]
BasicBug[location=(2, 3),direction=0,color=java.awt.Color[r=255,g=200,b=0]]
BasicBug[location=(2, 3),direction=45,color=java.awt.Color[r=255,g=200,b=0]]
BasicBug[location=(1, 4),direction=45,color=java.awt.Color[r=255,g=200,b=0]]
BasicBug[location=(0, 5),direction=45,color=java.awt.Color[r=255,g=200,b=0]]
BL 23 - 1
Modify BasicBug:
The following code for BasicBug produces it’s default behavior; the bug moves
when it can and when it can’t, it turns 45 degrees clockwise.
import info.gridworld.actor.Bug;
public class BasicBug extends Bug
{
public void act( )
{
if(canMove( ))
{
move( );
}
else
{
turn( );
}
}
}
While recursion is one of the more sophisticated concepts in computer science, this
particular lab is one of the easiest. Actually, only one line of code needs to be added to
make the bug perform as described.
BL 24 - 1
Modify BasicBugRunner:
The following code for BasicBugRunner creates a rock and three BasicBug
objects. This will give a variety of objects to occupy an ArrayList that will be
created in the BasicBug class.
//This class will not compile until the BasicBug class first compiles.
import info.gridworld.actor.ActorWorld;
import info.gridworld.grid.Location;
import java.awt.Color;
import info.gridworld.actor.Rock;
public class BasicBugRunner
{
public static void main(String args[])
{
ActorWorld world = new ActorWorld( );
BasicBug bug1 = new BasicBug( );
bug1.setColor(Color.ORANGE);
import info.gridworld.actor.Bug;
each Location object using Loaction’s getRow and getCol methods. Then print
these two values
1, 3
1, 7
2, 7
4, 6
5, 3
1, 3
1, 7
2, 7
3, 6
4, 6
5, 3
1, 3
1, 7
2, 7
3, 6
4, 3
4, 6
5, 3
0, 7
1, 3
1, 7
2, 7
3, 6
4, 3
4, 6
5, 3
BL 25 - 1
(Teacher: Refer to Labs 4 and earlier for a detailed discussion of the various GridWorld
methods used in these labs (act, canMove, move, & turn). If the students have done the
previous labs, then they should already be accustomed to the use of these methods.)
Modify BasicBugRunner:
This lab is very similar to BugLab24. Use the exact same BasicBugRunner class
as in that lab. It creates three bugs and one rock.
import info.gridworld.actor.Bug;
//The following imports necessary for bottom block of code
import info.gridworld.grid.*;
import java.util.*;
import info.gridworld.actor.Actor;
public class BasicBug extends Bug
{
public void act( )
{
if(canMove( ))
{
move( );
}
else
{
turn( );
}
//Print the coordinates of all occupied cells.
Grid<Actor> gr = getGrid( ); //Obtain the grid object
//locList is an ArrayList of all the occupied locations.
ArrayList<Location> locList = gr.getOccupiedLocations( );
BL 25 - 2
1, 3
1, 7
2, 7
3, 6
4, 6
5, 3
1, 3
1, 7
2, 7
3, 6
4, 3
4, 6
5, 3
0, 7
1, 3
1, 7
2, 7
3, 6
4, 3
4, 6
5, 3
BL 26 - 1
(Teacher: Refer to Labs 4 and earlier for a detailed discussion of the various GridWorld
methods used in these labs (act, canMove, move, & turn). If the students have done the
previous labs, then they should already be accustomed to the use of these methods.)
Modify BasicBugRunner:
This lab is very similar to BugLab24. Use the exact same BasicBugRunner class
as in that lab. It creates three bugs and one rock.
import info.gridworld.actor.Bug;
//All these imports necessary for bottom block of code
import info.gridworld.grid.*;
import java.util.*;
import info.gridworld.actor.Actor;
public class BasicBug extends Bug
{
public void act( )
{
if(canMove( ))
{
move( );
}
else
{
turn( );
}
String locStr[] = getLocationArray( );
//Modifications go here
}
BL 26 - 2
Notice that the elements of String array locStr typically look something like “3,5”
where the first number is the column and the second is the row of an occupied
cell. The purpose of this lab is to sort by column (the primary sort key) with the
row number as a secondary key.
The reason that String locStr array is not built with the more customary order of
the row-first and column-second, is because the coordinates produced by
getLocationArray already is naturally ordered with respect to rows. Therefore, it
would not be a meaningful exercise to sort an array that is already ordered.
In the “Modification go here” code area above, insert the following code:
Clearly, there is a need to produce two methods here: printStringArray and sort
where each receives the String array, locStr. Create a sort method that orders the
array in ascending order. Use one of the sort methods from Lesson 41 (Bubble
Sort is the simplest) and make use of the compareTo method.
BL 26 - 3
3,1
7,1
7,2
6,4
3,5
3,1
3,5
6,4
7,1
7,2
******************
Observe that the printout occurs in pairs with the first unordered, the second
ordered, and then a row of asterisks serving as a separator between the pairs.
BL 27 - 1
(Teacher: Refer to Labs 4 and earlier for a detailed discussion of the various GridWorld
methods used in these labs (act, canMove, move, & turn). If the students have done the
previous labs, then they should already be accustomed to the use of these methods.)
Modify BasicBugRunner:
This lab is very similar to BugLab26. Use the exact same BasicBugRunner class
as in that lab. It creates three bugs and one rock.
import info.gridworld.actor.Bug;
//All these imports are necessary for the getLocationArray method.
import info.gridworld.grid.*;
import java.util.*;
import info.gridworld.actor.Actor;
public class BasicBug extends Bug
{
public void act( )
{
if(canMove( ))
{
move( );
}
else
{
turn( );
}
String locStr[] = getLocationArray( );
BL 27 - 2
}
}
The purpose of this lab is to reverse the elements of the locStr array just before
printing so as to produce a more standard “row, column” sequence instead of the
BL 27 - 3
present “column, row” sequence. For example, if an element of the locStr array is
“3,7”, we want, instead, to print “7,3”. Use the reverse method of StringBuffer
to accomplish this.
Recall from BugLab26 that the reason that String locStr array was not originally
built with the more customary order of the row-first and column-second, is
because the coordinates produced by getLocationArray already is naturally
ordered with respect to rows. Therefore, it would not be a meaningful exercise to
sort an array that is already ordered.
1,3
1,7
2,7
4,6
5,3
1,3
5,3
4,6
1,7
2,7
******************
Observe that the printout occurs in pairs with the first unordered, the second
ordered, and then a row of asterisks serving as a separator between the pairs.
BL 28 - 1
BugLab 28– Sorting with Comparator (Blue Pelican Java Lesson 45)
(Teacher: Refer to Labs 4 and earlier for a detailed discussion of the various GridWorld
methods used in these labs (act, canMove, move, & turn). If the students have done the
previous labs, then they should already be accustomed to the use of these methods.)
Modify BasicBugRunner:
This lab is very similar to BugLabs 24-27. Use the exact same BasicBugRunner
class as in those labs. It creates three bugs and one rock.
Modify BasicBug:
The BasicBug class will have the following code. Notice the area of
“Modifications go here.” That is where a Comparator object will be used to
sort the locStr array:
import info.gridworld.actor.Bug;
//All these imports are necessary for the getLocationArray method
import info.gridworld.grid.*;
import java.util.*;
import info.gridworld.actor.Actor;
public class BasicBug extends Bug
{
public void act( )
{
if(canMove( ))
{
move( );
}
else
{
turn( );
}
String locStr[] = getLocationArray( );
….Modifications go here….
BL 28 - 2
Use the class thus produced to create a Comparator object and this pass that
object along with the String array, locStr, to the Arrays.sort method. Place this
code in the code area, “Modifications go here.”
several times, and observe the printout on the console screen. It should be
recognized that the act method executes for each bug each time the Step button is
clicked. As the bugs advance they leave behind a trail of Flower objects. Thus,
the number of objects on the grid increases with each click of the Step button.
The following output is produced with a single click of the Step button. Notice the
order is with respect to the product of the row and column numbers.
1,3
1,7
2,7
5,3
4,6
1,3
1,7
2,7
5,3
3,6
4,6
1,3
1,7
4,3
2,7
5,3
3,6
4,6
BL 29 - 1
import info.gridworld.actor.Bug;
public class BasicBug extends Bug
{
//No code
}
Modify BasicBugRunner:
The BasicBugRunner class generates 30 BasicBug objects of random color that
are then randomly placed within the 10 X 10 grid. This fundamental code is
presented below and can be simply copied and pasted into an IDE. Notice the
sections marked with <#1>, <#2>, <#3>, and <#4> are areas where code is to
added.
import info.gridworld.actor.ActorWorld;
import info.gridworld.grid.Location;
import java.awt.Color;
import info.gridworld.actor.Rock;
import java.util.*;
public class BasicBugRunner
{
public static void main(String args[])
{
ActorWorld world = new ActorWorld( );
<#1>
BL 29 - 2
int count = 0 ;
while(count < totalBugs)
{
//Randomlly select row and column indices
int rowIndx = rnd.nextInt(10);
int colIndx = rnd.nextInt(10);
count++;
}
}
world.show( );
<#4>
}
}
BL 29 - 3
This is to be accomplished by storing all red bug objects in Set set1 and all bug
objects residing on the left side of the grid in Set set2. Find the intersection of
these two Sets and then remove from the grid all of the bug objects residing in this
intersection Set.
<#1> In this code area, instantiate two HashSet objects called redSet and leftSet
using BasicBug as a type parameter.
<#2> In this code area, add the current bug object ( bug[count] ) to Set redBug.
<#3> In this code area, add the current bug to Set leftBug only if the bug is in the
left portion of the grid ( colIndx < 5 ).
<#4> In this code area, produce a Set that is the intersection of redSet and leftSet.
Iterate through that Set and remove all its elements from the grid using the
removeSelfFromGrid method.
Modify BasicBugRunner:
The BasicBugRunner class generates 10 BasicBug objects of random color that
are then randomly placed within the 10 X 10 grid. This is the initial state of the
board for a game. This fundamental code is presented below and can be simply
copied and pasted into an IDE.
Take special note of the line of code designated with the rem, “//Create bug”.
Notice that we are sending the BasicBug constructor a String that names the bug
objects with names like “bug1”, “bug2”, etc. Thus, it will be necessary to have an
appropriate constructor in BasicBug to receive this String and then assign that
name to a state variable.
import info.gridworld.actor.ActorWorld;
import info.gridworld.grid.Location;
import java.awt.Color;
import info.gridworld.actor.Rock;
import java.util.*;
public class BasicBugRunner
{
public static void main(String args[])
{
ActorWorld world = new ActorWorld( );
int count = 0 ;
while(count < totalBugs)
{
BL 30 - 2
count++;
}
}
world.show( );
}
}
import info.gridworld.actor.Bug;
import java.util.*;
public class BasicBug extends Bug
{
public BasicBug(String nm)
{
BL 30 - 3
bugName = nm;
<#2>
}
The requirement is to create a static Map object in which the keys are to be the
bug names (name data member) while the values are to be the respective
directions of the bugs.
<#1> In this code area, instantiate a static TreeMap object called dirMap.
Instantiate this object using type parameters. The key will be a String and the
value will be an Integer. Notice that by making this Map object static, this same
object is used by all of the bug objects.)
<#2> In this code area (the constructor), add to dirMap the pair nm and an integer
direction of 0 since the initial direction of the bug is 0 degrees - north. Use the put
method to insert this pair into the Map
<#3> In this code area (just after a turn), update dirMap with the current key-
value pair. Recall that the bug’s name data member is the key and its new
direction is the value. Use the getDirection method of the bug object to obtain its
new direction.
BL 30 - 4
{bug0=0, bug1=0, bug2=0, bug3=0, bug4=0, bug5=45, bug6=0, bug7=0, bug8=0, bug9=0}
{bug0=45, bug1=0, bug2=0, bug3=0, bug4=0, bug5=45, bug6=0, bug7=0, bug8=0, bug9=0}
{bug0=45, bug1=0, bug2=0, bug3=0, bug4=0, bug5=45, bug6=0, bug7=0, bug8=0, bug9=0}
{bug0=45, bug1=0, bug2=0, bug3=0, bug4=0, bug5=45, bug6=0, bug7=0, bug8=0, bug9=0}
{bug0=45, bug1=0, bug2=0, bug3=0, bug4=0, bug5=45, bug6=0, bug7=0, bug8=0, bug9=0}
{bug0=45, bug1=0, bug2=0, bug3=0, bug4=0, bug5=45, bug6=0, bug7=0, bug8=0, bug9=0}
{bug0=45, bug1=0, bug2=0, bug3=0, bug4=0, bug5=45, bug6=0, bug7=0, bug8=0, bug9=0}
{bug0=45, bug1=0, bug2=0, bug3=0, bug4=0, bug5=45, bug6=0, bug7=0, bug8=0, bug9=0}
{bug0=45, bug1=0, bug2=0, bug3=0, bug4=0, bug5=45, bug6=0, bug7=0, bug8=0, bug9=0}
{bug0=45, bug1=0, bug2=0, bug3=0, bug4=0, bug5=45, bug6=0, bug7=0, bug8=0, bug9=0}
Notice that some of the bugs have already had to turn after just a single step. Now
move the println statement to just after turn( ) and observe that the Map is only
printed when a turn is executed.
As more code is added BasicBug to implement the game, the Map could be
printed at any place in the code in order to help analyze errors.