![]() |
Problem Set 4 Due Friday, October 12 at the start of class |
On this assignment, getting the buggles to behave correctly is not enough to receive a perfect score. You must also write your programs so that they are beautiful. Good programming style produces programs that are easy for others to read and understand.
Unlike previous problem sets, notes, hints, and suggestions for each homework problem are given on a separate page. We want you to have freedom to think about the problem in your own way. Reading the hints page is not required. Its main purpose is to help students to think about the problem if they don't know how to get started. On the other hand, we do also include some notes on what we think are good ways of going about programming. It is not required that you follow those guidelines exactly. However, your programming style should result in a program that is at least as easy to read and understand as the program would be if you followed our suggestions.
There are two problems in this problem set. We have included working
examples of the solutions to the problems in the test
folder that
you download with the ps04_programs
folder. It is a good idea to
run these programs to get a feel for what we are asking you to do. Your
solution should provide the exact same results as our solution (exceptions
noted below).
The code is available in the
ps04_programs
folder in the cs111 download directory on
the cs
server.
This assignment is more challenging than the previous assignments. Based on student time estimates from previous semesters, most of you will need between 5 and 10 hours to complete this assignment. Please start early and plan your time accordingly.
Follower.java
file from Task 1;
DeadEndWorld.java
file from Task 2.
Save the final
Follower.java
and DeadEndWorld.java
files
in the ps04_programs
folder. Submit the entire
ps04_programs
folder to your drop folder on the cs111
server.
In the FollowWorld problem, a buggle named Folla at coordinate (1,1) has before her a tantalizing trail of bagels. The exact length and shape of the trail is not specified. However, it is known that (1) the bagel trail has at least one bagel; (2) it starts at coordinate (1,1); and (3) it forms a continuous line that may bend in many different directions but may never branch out. Here is a sample bagel trail: | Your goal is to program members of the Follower
class (such as Folla) to follow the trail of bagels. At every position,
a Follower should eat (i.e., pick up) the bagel at that position, and then
move in the direction of the next bagel. This process should continue until
there are no more bagels. A Follower should also leave behind a colored
mark in every grid cell that formerly contained a bagel except for the
cell of the very last bagel. The Follower should stop and rest in that
cell. For example, here is the state of the world after Folla has eaten
all the bagels in the previous picture: |
![]() |
![]() |
To begin this problem, open the test
subfolder of the
ps04_programs
folder that you downloaded for this
assignment and run the FollowWorldSoln
program. You
can do this in two ways:
FollowWorldSoln.java
in Dr. Java, compile it,
and run the FollowWorldSoln
program.
FollowWorldSoln.html
in a web browser.
When you start the FollowWorldSoln
program, you should see a
bagel trail. Every time you click on the Reset button, a new
bagel trail will be randomly generated. When you click on the
Run button, a buggle follows the trail of Bagels, picking them
up as it goes.
We recommended that you slow down the pace of the buggle so that you can see what actions it takes at every step. You can do this by pressing the Step button many times, or by using the setDelay button to have the buggle wait a certain amount of time between every pair of steps. (Experiment to find a nonzero time that works best for you.)
Your goal is to develop a buggle that will correctly
follow all such trails as in the test
example.
We have supplied you with the following FollowWorld
class
in the file FollowWorld.java
:
public class FollowWorld extends BagelTrailWorld { public void setup() { setDimensions(15,15); } public void run () { Follower folla = new Follower(); folla.tick128(); // Would be nicer to stop when find last bagel, // but assume a predetermined number of steps for now. } public static void main (String[] args) { runAsApplication(new FollowWorld(), "FollowWorld"); } }
The run()
method of the FollowWorld
class creates a Follower
(a special kind of buggle)
named folla
and tells her to execute her tick()
method 128 times. (We use a predetermined number of steps, but it would
be much more elegant to have folla
move until she has eaten all the bagels
in the trail. We will show how to accomplish this via recursion in Lecture #10.)
You do not need to modify the FollowWorld
class in this problem.
Your task is to create a Follower
class from scratch
in a new file named Follower.java
. Your
Follower
class should be a subclass of TickBuggle
and it should define a tick()
method and any helper methods used
by your tick()
method.
(Because Follower
is a subclass of TickBuggle
,
Follower
buggles already understand messages
like tick2()
, tick4()
, tick8()
,
and so on, so you do not need to define these.)
Your tick()
method should implement your
bagel-following strategy. Remember that the tick()
method will be sent to folla
exactly 128 times for every bagel trail,
regardless of its length and shape. So tick()
must
appropriately do nothing after all the bagels have been consumed.
In particular, once the buggle has determined that there are no more bagels,
it should not repeatedly "dance" or "wiggle" in its final position.
Your Follower
buggle should behave exactly like the one we have
given you in the test
folder. Use Reset and Run/Step
to test your program on a variety of trails.
In addition to creating your new Follower
class in Dr. Java,
you will also need to open and compile the FollowWorld
class from FollowWorld.java
. Note that FollowWorld
class will not compile until you have defined your new Follower
class.
To test your program, run the FollowWorld
class using
java FollowWorld
in the Interaction Pane.
Deanna explores only connected acyclic mazes. A connected acyclic maze is a maze in which there is a unique non-backtracking path from any point in the maze to any other. This means that it is always possible for Deanna to find all the dead ends in a particular maze! Here is an example of a connected acyclic maze:
It is possible to visit all the cells of a connected acyclic maze by using the "right-hand-on-the-wall" strategy. That is, if you always keep your right hand on a wall as you walk through such a maze, you will eventually visit all the cells and end up where you started. Along the way, you will visit some cells more than once (i.e., backtrack), but that's OK.
Your goal is to program members of the DeadEndBuggle
class (such as
Deanna) to drop bagels in all the dead ends of a particular maze by using
the "right-hand-on-the-wall" strategy to visit cells in the maze until
the buggle has explored the entire maze. Once the buggle has explored the
entire maze and returned to its starting location, the buggle should not go through
the maze again, but should just rest there. The buggle should color every
visited cell with its color and leave a bagel in every dead end of the maze.
Here is a snapshot of the above maze after Deanna is done exploring it:
To begin this problem, open the test
subfolder of the
ps04_programs
folder that you downloaded for this
assignment and run the DeadEndWorldSoln
program.
You can do this in two ways:
DeadEndWorldSoln.java
in Dr. Java, compile it,
and run the DeadEndWorldSoln
program.
DeadEndWorldSoln.html
in a web browser.
The DeadEndWorldSoln
program is a working
solution of the maze-navigating, bagel-dropping buggle. When you
start this program, you should see a maze like the one shown in the
first picture above. Every time you click on the Reset
button, a new maze will be randomly generated. When you click Run,
the buggle uses the right-hand-on-the-wall strategy to explore the maze
and uses conditionals to figure out where to drop bagels.
As in Task 1, you are encouraged to use Step or setDelay
to slow down the pace of the buggle to study its behavior.
Your goal is to flesh out a definition of the DeadEndBuggle
class so that instances of this class behave like the test buggle.
That is, an instance of DeadEndBuggle
should explore every cell of a connected acyclic maze and drop a bagel
in every dead end. We have provide you with the following skeleton
of the DeadEndBuggle
class in the file DeadEndBuggle.java
:
public class DeadEndBuggle extends TickBuggle { // This location is helpful for stopping the buggle // when it returns to its starting position. Location start = new Location(1,1); public void tick() { // Override the default tick method of the TickBuggle class. // Keep "right finger" of buggle on right wall to explore maze. // Drop bagels in dead ends. } // Add your auxiliary methods below: }
You will need to "teach" members of the DeadEndBuggle
class how to follow the "right-hand-on-the-wall" strategy by filling in
the details of the tick()
method skeleton in that class.
You should also define any auxiliary methods you find helpful.
We have also provided you with the following working definition
of the DeadEndWorld
class in the file DeadEndWorld.java
:
public class DeadEndWorld extends MazeWorld { public void setup() { setDimensions(15,15); } public void run () { DeadEndBuggle deanna = new DeadEndBuggle(); deanna.tick1024(); } public static void main (String[] args) { runAsApplication(new DeadEndWorld(), "DeadEndWorld"); } }
The DeadEndWorld
class is a subclass of the
MazeWorld
class, whose responsibility is to draw a
connected acyclic maze. The run()
method of the
DeadEndWorld
class creates a DeadEndBuggle
named deanna
and tells her to execute
her tick()
method 1024 times. (A predetermined
number of steps is inelegant. We will see how to get rid of this inelegance
later in the course via recursion and iteration.) You do not
need to modify the DeadEndWorld
class in this problem.
You can test your solution by compiling the DeadEndWorld
class and running the DeadEndWorld
program.
You make sure that your solution works properly on at least the first 3 mazes
generated by Reset.
These first three mazes include all the possible starting configurations
that your buggle needs to handle.
Your solution should behave exactly like the solution provided except
that your buggle may end at the start position in any
orientation (heading) when she finishes exploring the maze.