[an error occurred while processing this directive] [an error occurred while processing this directive]
Except where otherwise noted, the contents of this document are Copyright 2013 Stuart Reges and Marty Stepp.
lab document created by Marty Stepp, Stuart Reges and Whitaker Brand
Goals for today:
To work on the critters assignment, you must first download the classes that are used by the simulator. To begin:
CritterMain.java
from the (unzipped) Critters folder.
CritterMain.java
. You should see a world that
has 30 "Food" critters and 30 "FlyTrap" critters. You can click on
"start", although nothing will happen with just these two
critters in the world.
public class LabTA extends Critter { }
CritterMain
to include this line of code:
frame.add(30, LabTA.class);
CritterMain
. You should see 30 new
critters that are displayed as black question marks.
LabTA
critters are turning in a counterclockwise direction because their default behavior is Action.LEFT
.
public Action getMove(CritterInfo info) { return Action.HOP; } public Color getColor() { return Color.MAGENTA; } public String toString() { return ":-)"; }
import java.awt.*;
LabTA
class and correct any
errors. Switch to the CritterMain
window and give the run
command. Now you should see 30 magenta colored critters that are
displayed with the smiley emoticon.
FlyTrap
. Click on the debug button to watch in detail
and try running it several times.
Our LabTA critters have very simple behaviors that don't change. They always hop forward and they always display as magenta emoticons.
For this exercise, we want to alter the behavior of the LabTA critter so that it changes color over time. In particular, we want them to alternate between the colors magenta and white. Initially they should be magenta, but after they make a first move, they should change their color to white. Then after another move they should change back to magenta. Then after another move they should change back to white.
Developing this kind of behavior is a central part of the critters
homework. Think about how you can implement this. In particular, think
about what kind of state information you could add to
the LabTA
critter that would allow it to do this. Remember
that in defining critters, you get to decide what fields to introduce. A
field allows an object to remember information about its state.
The next slide tells you how to do it, but it would be good to try to come up with your own ideas first.
To allow your LabTA critters to change colors on alternate moves, they need
to keep track of where they are in the cycle. For example, you could
introduce a boolean
field that keeps track of whether it
should be displaying itself as magenta or as white. You can then switch
the boolean
value each time that getMove
is
called.
We can solve this in an even more general way by introducing a move counter:
count
to keep track of
how many moves the critter has made. Remember that fields should be
declared to be private
.
getMove
method to increment this counter each
time it is called.
getColor
method to return
magenta when the move counter is even and to return white when it is
odd.
LabTA
class and
running CritterMain
.
public class LabTA extends Critter { private int count; public LabTA() { this.count = 0; } public Action getMove(CritterInfo info) { count++; return Action.HOP; } public Color getColor() { if (count % 2 == 0) { return Color.MAGENTA; } else { return Color.WHITE; } } ...
Now we're going to work on the moves that the LabTA
critters
make.
FlyTrap
class to see how it is
written. Notice its getMove
method:
public Action getMove(CritterInfo info) { if (info.getFront() == Neighbor.OTHER) { return Action.INFECT; } else { return Action.LEFT; } }
getMove
in the LabTA
class. Then
modify it so that it always infects when a different creature is in front
of it, otherwise hops if it can (if nothing is in front of it), and
then otherwise turns left. This involves adding a new
branch in the if/else. Remember that the
constant Neighbor.EMPTY
can be used to see if a position
is empty and that you move forward with the Action.HOP
move. Also be sure to still increase your count
field by 1 as in
the last exercise
CritterMain
and observing
the LabTA
critters.
public class LabTA extends Critter { ... public Action getMove(CritterInfo info) { count++; if (info.getFront() == Neighbor.OTHER) { return Action.INFECT; } else if (info.getFront() == Neighbor.EMPTY) { return Action.HOP; } else { return Action.LEFT; } } ...
Now we're going to include a bit of randomness. The current version of
the LabTA
class always turns left when it can't infect or
hop. We are going to change it so that it instead randomly chooses between
turning left and turning right.
To solve this problem, we will need access to a Random
object. We don't want to construct one every time we
call getMove
, so we will instead store it as a field.
Take your time to complete each of the following steps because the practice will be very valuable. Ask a TA or your neighbor for help if you don't know how to accomplish any of the tasks:
r
of type Random
.
Random
object.
getMove
method so that it uses
the Random
object to randomly pick between turning left
and turning right if it can't infect or hop.
CritterMain
and observing
the LabTA
critters.
import java.util.*; public class LabTA extends Critter { private Random r; ... public Action getMove(CritterInfo info) { count++; if (info.getFront() == Neighbor.OTHER) { return Action.INFECT; } else if (info.getFront() == Neighbor.EMPTY) { return Action.HOP; } else { int choice = r.nextInt(2); if (choice == 0) { return Action.LEFT; } else { return Action.RIGHT; } } } ...
Nice job making it this far--labs are tough! Feel free to work with the person next to you for the remaining slides. Labs are a unique opportunity (unlike homework) to collaborate directly on ideas, and practice peer programming.
These next problems get a little more challenging as we explore earlier concepts further.
We put a lot of problems in here so that you have plenty to refer back to later when working on homework. Don't feel bad if you don't finish all of them--Brett can't finish them all in a 50 minute lab, either! :)
Forest the cat says good job!
Fish
Define a Critter class called Fish
:
Fish
should be White in color
Fish
should appear as "<><" on even numbered moves, and as "><>" on odd numbered moves.
Fish
should always infect if a different critter is in front of them, then should otherwise hop if able, and should otherwise turn right.
Solve this program in jGRASP with CritterMain
, and be sure to add your Fish
to the critter world in the same way you added your LabTA
class. Your Fish should end up "swimming" around the outside edge of the world.
Eagle
Define a Critter class called Eagle
:
Eagle
should alternate in Color between Red, White, and Blue (in that order)
Eagle
should appear as an "E"
Eagle
should always infect if a different critter is in front of them, then should otherwise move in a circular pattern. An Eagle should hop three times, then turn left, then hop three times, then turn left, and so on so forth.
Solve this program in jGRASP with CritterMain
, and be sure to add your Eagle
to the Critter world in the same way you added your LabTA
class. You should see your Eagles moving in small circles, occasianally infecting other critters, and changing between red, white, and blue.
If you finish all the exercises, try out our Practice-It web tool. It lets you solve Java problems from our Building Java Programs textbook.
You can view an exercise, type a solution, and submit it to see if you have solved it correctly.
Choose some problems from the book and try to solve them!