Download the hw7Buggles folder from my download directory on panther. It should contain
BuggleWorld.java
ExampleTickBuggleWorld.html
ExampleTickBuggleWorld.java
ExampleTickBuggleWorld.mcp
FindWorld.html
FindWorld.java
FindWorld.mcp
HurdleWorld.html
HurdleWorld.java
HurdleWorld.mcp
MazeWorld.java
Randomizer.java
TickBuggle.java
TickBuggleWorld.java
ExampleTickBuggleWorld
. It should look just
like the BuggleWorlds you've seen until now, except that there's an extra
button labelled "tick()
", which sends a tick()
message
to the current Buggle. How that Buggle responds to the tick()
message is up to you.
ExampleTickBuggleWorld.java
. It should
contain two classes: ExampleTickBuggleWorld
, with a run()
method that creates an ExampleTickBuggle, and ExampleTickBuggle
,
with a tick()
method that does nothing. Fill in the body
of tick()
with a forward();
statement. Compile
and run the program again, and it should now respond to the "tick()
"
button by moving forward.
Next,
let's replace the "
forward();
" with two statements: "forward(2);
left();
" Compile, run, hit the "run" button, then the "tick"
button, and you should see the buggle move forward 2 and turn left.
Hit the "tick" button a few more times and see what happens!
Try some other experiments.
tick()
method just as before. Fill
it in with a forward();
statement, compile and run. You'll
probably find that your Buggle is facing a wall, and therefore can't move.
But if you move it (by hand) away from the wall, the "tick" button should
work just as before until the Buggle hits another wall. (By the way,
you can create and remove walls yourself by clicking on the green lines
between squares in the BuggleWorld. This will be useful for testing
your Buggles.)
jumpHurdle()
", in the Hurdler
class, to do this.
Replace the forward();
statement in the tick()
method
with a call to jumpHurdle();
. Now compile, run, hit the
"run" button, and hit "tick" a few times.
public void tick() { if (isFacingWall ()) { jumpHurdle (); } else { forward (); } }
But
there's still a problem: if you keep ticking along, the Buggle will get
to the right-hand wall and start climbing it. The Buggle thinks the
right-hand wall is a hurdle, so it tries to jump it: turn left, move forward
(i.e. north), turn right, move forward (i.e. east), and we can't do this
so the Buggle stops in its tracks. The next time, it tries again:
move north, head east, and stop. To remedy this, we need to teach
the Buggle to detect the "finish line" and stop running. This calls
for a method named "
atFinishLine()
", which returns a boolean that
can be used by another "if" statement to do nothing if we're already at
the finish line. For purposes of this assignment, any wall two units
high or higher constitutes a "finish line", so if we're looking at a wall,
we take a step to the left (i.e. north) and we're still looking
at a wall, we know we're at the finish line. It's important to make
sure that atFinishLine()
has no side effects: it doesn't draw
anything on the screen, it doesn't have the net effect of moving the buggle,
etc. and all it does is answer a yes-or-no question.
public boolean atFinishLine() { // Return true if buggle is facing wall (as opposed to hurdle) and false otherwise. // Should leave buggle in same position and heading as when it starts. // Should not leave any marks behind. if (isFacingWall ()) { brushUp (); stepLeft (); if (isFacingWall ()) { stepRight (); brushDown (); return true; } else { stepRight (); brushDown (); return false; } } else return false; } private void stepLeft () { left (); forward (); right (); } private void stepRight () { right (); forward (); left (); }Note the use of auxiliary methods
stepLeft()
and stepRight()
to make it clearer what's really going on in the body of atFinishLine()
.
There's still a certain amount of duplication in the code, which can be cleaned up by introducing a boolean variable:
public boolean atFinishLine() { // Return true if buggle is facing wall (as opposed to hurdle) and false otherwise. // Should leave buggle in same position and heading as when it starts. // Should not leave any marks behind. if (isFacingWall ()) { brushUp (); stepLeft (); boolean answer = isFacingWall (); stepRight (); brushDown (); return answer; } else return false; }In addition, of course, we have to use the
atFinishLine()
method in the body of tick()
:
public void tick() { if (atFinishLine ()) { // do nothing } else if (isFacingWall ()) { jumpHurdle (); } else { forward (); } }Note that we've also used an "extended" form of the "if...else" statement:
if (first condition) {
what to do if first condition is true
}
else if (second condition) {
what to do if first is false, but second
is true }
else if (third condition) {
what to do if first and second are false,
but third is true }
.
.
.
else {
what to do if none of the conditions hold
}
HurdleWorld.java
, which you've been working on for a
while now, there's also a class named TiredHurdler
. It's
intended to model a Hurdler who gets tired after jumping a fixed number
of hurdles. The instance variable hurdlesLeft
keeps track
of how much energy the Hurdler has. Your mission is to write a TiredHurdler
class that works correctly: if initialized with the number 3, it'll jump
3 hurdles and keep going, but once it reaches the fourth hurdle, it will
stop rather than jumping it.
TiredHurdler
class, you'll
need to change the run()
method in the HurdleWorld
class:
comment out the line that creates a Hurdler, and uncomment the lines that
create a (green) TiredHurdler
. Note that since TiredHurdler
extends Hurdler, all the methods you wrote for Hurdlers are still available
for free. You only need to rewrite the method(s) that behave differently.
HurdleWorld.java
.
tick()
method in the Finder class so that Fiona, and
any other Finder, can search through a maze, always keeping her right hand
on the wall, until she finds a bagel (you can detect this with the boolean-valued
isOverBagel()
method), at which point she refuses to go any farther.
Be sure to test your program on several different mazes (remember, each
time you hit the "reset" button, a new maze is generated randomly for you).
You'll probably need to write some auxiliary methods: for example, it might
be useful to have boolean-valued methods named canGoRight
, canGoStraight
,
and canGoLeft
. (That's a hint!) Turn in your
modified copy of FindWorld.java.