Graphic by Keith Ohlfs |
|
The purpose of this problem set is to give you experience with conditionals. You must demonstrate an understanding of how to use conditionals to complete this problem set. You will need to follow the style guidelines outlined in the reading as well as demonstrate that you understand the principle of when/how to use invariants. However, getting the problems to work is not enough to receive a perfect score on this assignment. 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 do want for you to have freedom to think about the problem in your own way. Reading the hints page is not required. It's 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 including working examples of the solutions to the problems in the Test folder that you download with the ps4_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).
Softcopy submission: Save the modified FollowWorld.java
and
DeadEndWorld.java
files in the ps4_programs folder. Upload
the entire folder (including all the other .java
and
.class
files -- everything) to your ps4 drop folder.
Hardcopy submission: New Location!
Turn in only one package of hardcopy materials. Staple your files together
and submit your hardcopy package by placing it in the box outside of Lyn's
office (121B, behind the mini-focus consultant's desk).
Your package should include printouts of
FollowWorld.java
from Homework Problem 1
DeadEndWorld.java
from Homework Problem 2
Reminders
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 and length 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. For example, 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, use the AppletViewer to run FollowWorld.html in the Test subfolder of the ps4_programs folder. When you start this applet, you should see the bagel trail shown in the first picture above. 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. Your goal is to develop a buggle that will correctly follow all such trails as in the Test example. You will use Reset and Run to test your program on a variety of trails. Your solution should behave exactly like the solution we have given you in the Test folder.
Open the project file ps4.proj. This contains many files, but the only one you need to look at is FollowWorld.java. This file contains two classes, as shown below:
public class FollowWorld extends BagelTrailWorld { public void setup() { // setDimensions(11,19); } public void run () { Follower folla = new Follower(); folla.tick64(); // Would be nicer to stop when find last bagel, // but assume a predetermined number of steps for now. } } class Follower extends TickBuggle { public void tick () { // Override default tick method of TickBuggle class. // Follow the trail of bagels until they have all been picked up. } }
The FollowWorld class is a subclass of the BagelTrailWorld class, whose responsibility is to draw bagel trails subject to the constraints mentioned above. The run() method of the FollowWorld class creates Folla and tells her to execute her tick() method 64 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.) You do not need to modify the FollowWorld class in this problem.
In this problem, you should develop a bagel-following strategy for the Follower class and implement it in terms of the tick() method in that class. You should first develop a set of motion rules in the same style as those discussed for the IfBuggle class in lecture. Then you should implement your rules in the tick() method of the Follower class. (Note: you can download the code for IfWorldAnswers.java from the lec9_programs folder inside the CS111 download directory.) Remember that the tick() method will be sent to Folla exactly 64 times for every bagel trail, regardless of its length and shape. So tick() must appropriately "do nothing" after all the bagels have been consumed.
Notes/Hints/SuggestionsIn the DeadEndWorld problem, an eccentric buggle named Deanna loves to wander around in mazes finding all the dead ends. She loves it so much that she tries to get all her friends to find the dead ends in mazes, too. She does this by carrying around a bag of bagels as she explores mazes. Every time she finds a dead end, she leaves a bagel there so that her friends can be rewarded if they find the dead end, too. Deanna explores 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 arrives at the start again, the buggle should not go through the maze again, but should just rest there. The buggle should leave a mark behind in every visited cell and 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, use the Applet Viewer to run the DeadEndWorld.html applet within the Test subfolder of the ps4_programs folder that you downloaded for this assignment. This applet contains a working solution of the maze-navigating, bagel-dropping buggle. When you start this applet, you should see the maze 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. You should test your solution to make sure that it works properly on at least the first 3 mazes. The first three mazes include all the possible unique starting configurations. Your solution should behave exactly like the solution provided except that your buggle isn't required to "twitch" once she is finished with the maze and may end at the start in any orientation (heading).
Your goal is to develop a program that instructs the buggle to correctly explore entire mazes and drop bagels in all the dead ends. You will use Reset and Run to test your program on a variety of mazes.
You will implement your code in the file DeadEndWorld.java. This file contains two classes, as shown below:
public class DeadEndWorld extends MazeWorld { public void setup() { // setDimensions(11,19); } public void run () { DeadEndBuggle deanna = new DeadEndBuggle(); deanna.tick256(); } } class DeadEndBuggle extends TickBuggle { Point start = new Point(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 auxiliary methods here. }
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 Deanna and tells her to
execute her tick()
method 256 times. (As
usual, a predetermined number of steps is icky; we will see how to
get rid of this ickiness later in the course via recursion and
iteration.) You do not need to modify the DeadEndWorld
class in this problem.
Note that we have defined a Point start for you which you may use to figure out if your buggle is in the starting cell. As an example, the expression
this.getPosition().equals(start)
returns a boolean value of true or false indicating whether or not that buggle is
in the starting cell. You may also want to be able to check if your buggle is
headed in a particular direction. The expression to determine if your buggle is facing the Direction defined as EAST follows:
this.getHeading().equals(Direction.EAST)
In this problem, you should "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.
Notes/Hints/Suggestions