CS111, Wellesley College, Fall 2006

Problem Set 8

Due on Tuesday 5 December at the start of class

About this Problem Set

The purpose of this problem set is to give you hands-on experience with:

All parts of the assignment involve a pared-down version of BuggleWorld called TuggleWorld, which is described below. Working on this assignment will give you insight into the implementation of micro-worlds like BuggleWorld, TurtleWorld, and PictureWorld.

The problem set has three tasks, all of which are parts of one large problem. To pace yourself, you should try to finish Tasks 1 and 2 (or at least make a lot of progress on them) by Friday, Dec. 1, and then complete Task 3 by Tuesday, Dec. 5.

Working In Pairs

On this problem set, you are encouraged (but not required) to work with a partner as part of a two-person team. If you work on a team, your team will submit a single softcopy and hardcopy of the problem set and the same grade will be given to both team members.

All work by a team must be a true collaboration in which members actively work together on all parts of the assignment. It is not acceptable for team members to split up the problems and work on them independently. All programming should be done with both team members working at the same computer console. It is strongly recommended that both team members share the responsibility of "driving" (typing at the keyboard), swapping every so often. The only work that you may do alone is debugging code that you have written together and talking with the instructors and drop-in tutors.

There are many advantages to programming in pairs. People who program in pairs often claim to take less time than those who program alone. By continuously reviewing the code they find bugs sooner. Catching more bugs also leads to higher-quality code. When it comes to problem solving, two heads are better than one, and less time is spent exploring blind alleys. It can be a better learning experience, since team members both learn from and teach each other. And pair programmers often report that the experience is more enjoyable than programming alone. Many empirical studies have confirmed these and other benefits of pair programming. For example, see The Costs and Benefits of Pair Programming and other publications by Laurie Williams.

It's only fair to note that there are drawbacks to programming in pairs as well. Some pairs take longer to complete a program than they would individually. A mismatch in the skill level or working style of pair members can lead to friction between the individuals and disrupt the work. At Wellesley, the most common problem in pair programming is finding enough time in common to work together. You should not choose a partner to program with on this assignment unless you can schedule at least 10 hours to work together. To find a partner with a schedule similar to yours, feel free to post a message on CS111-F06 Q&A.

Although you clearly can share Java code with your team partner on this assignment, other aspects of the course collaboration policy still hold. In particular, while you can talk with other individuals and teams about high-level problem-solving strategies, you cannot share any Java code with them.

How to turn in this Problem Set

You are required to turn in both a hardcopy and a softcopy. For general guidelines on problem set submission, including how to submit a softcopy and how to check if you softcopy submission was successful, click here. Please make sure to keep a copy of your work.

Hardcopy Submission

Your hardcopy packet should consist of:
  1. The cover page.
  2. The object diagram from Task 1.
  3. The final version of your Tuggle.java file.
  4. The final version of your TuggleWorld.java file.
  5. Transcripts of test cases showing that your TuggleWorld main method works correctly in the following cases:

Staple these together, and submit them at the start of class on the due date.

A two-member team need only submit one hardcopy. Make sure that the names of both team members are on the hardcopy.

Softcopy Submission

You should submit your final version of your ps08_programs folder. This should include the final version of your Tuggle.java and TuggleWorld.java files and any TuggleScript (.tgl) files you have written.

A two-member team need only submit one softcopy. Please indicate whose drop directory the softcopy is in.


Background: TuggleWorld

Overview

Once considered clunky and old-fashioned, textual (in contrast with graphical) representations are becoming popular again in the context of text-based environments like text messaging and chat rooms. One branch of the Buggle line has seized the opportunity to propagate to text-based applications by evolving to live in a textual environment. These Textual Buggles, who call themselves Tuggles, share much of the behavior of the Buggles from which they evolved. They live in a rectangular grid of cells called TuggleWorld in which they can move forward and backward, turn left and right, leave colored trails, drop and pick up bagels, and so on.

The details of the Tuggle's behavior and their world, which are described in the Tuggle contract and TuggleWorld contract (both of which you should study closely), should look very familiar. There are some differences from the Buggle and BuggleWorld contracts that are worth noting:

An Example

Here is a simple example illustrating various features of tuggles and TuggleWorld:
TuggleWorld tw = new TuggleWorld(3, 4, 4);
System.out.println(tw);
Tuggle t1 = tw.getTuggle(1); 
Tuggle t2 = tw.getTuggle(2); 
Tuggle t3 = tw.getTuggle(3); 
Tuggle t4 = tw.getTuggle(4); 
t1.forward(3); 
System.out.println(tw);
t1.dropBagel();
t1.left(); 
t1.forward(2);
t1.dropBagel();
System.out.println(tw);
t2.setPosition(1, 2);
t2.setColor(Color.blue);
t2.dropBagel(); 
t2.forward();
System.out.println(tw);
t2.brushUp();
t2.dropBagel(); 
t2.forward();
System.out.println(tw);
t2.dropBagel(); 
t2.forward();
System.out.println(tw);
t2.dropBagel(); 
t3.setPosition(1, 3);
t3.setColor(Color.green);
t3.forward();
System.out.println(tw);
t3.dropBagel(); 
t3.right();
t3.forward(2);
t4.setHeading(Direction.WEST);
System.out.println(tw);

Below, we show each chunk of code ending in System.out.println() and the result displayed by this System.out.println():

TuggleWorld tw = new TuggleWorld(3, 4, 4);
System.out.println(tw);
+-+-+-+-+
| | | | |
+-+-+-+-+
| | | | |
+-+-+-+-+
|>| | | |
+-+-+-+-+

Notes: The 3x4 grid is empty except for 4 tuggles at (1,1). The cell (1,1) shows the heading ">" of the highest-numbered tuggle (#4) at (1,1).

Tuggle t1 = tw.getTuggle(1); 
Tuggle t2 = tw.getTuggle(2); 
Tuggle t3 = tw.getTuggle(3); 
Tuggle t4 = tw.getTuggle(4); 
t1.forward(3); 
System.out.println(tw);
+-+-+-+-+
| | | | |
+-+-+-+-+
| | | | |
+-+-+-+-+
|>|r|r|>|
+-+-+-+-+

Notes: Although cells (1,1), (2,1), and (3,1) are all red, only (2,1) and (3,1) show an "r" for "red". Cell (1,1) still shows the heading ">" of the highest-numbered tuggle (#4) at (1,1). Cell (4,1) shows the heading ">" of tuggle #1.

t1.dropBagel();
t1.left(); 
t1.forward(2);
t1.dropBagel();
System.out.println(tw);
+-+-+-+-+
| | | |^|
+-+-+-+-+
| | | |r|
+-+-+-+-+
|>|r|r|R|
+-+-+-+-+

Notes: Cell (4,1) is painted red and has a bagel, so it shows an uppercase letter "R". Cell (4,2) is painted red but has no bagel, so it shows a lowercase letter "r". Cell (4,3) shows the heading "^" of tuggle #1.

t2.setPosition(1,2);
t2.setColor(Color.blue);
t2.dropBagel(); 
t2.forward();
System.out.println(tw);
+-+-+-+-+
| | | |^|
+-+-+-+-+
|B|>| |r|
+-+-+-+-+
|>|r|r|R|
+-+-+-+-+

Notes: Cell (1,2) is painted blue and has a bagel, so it shows "B". Cell (2,2) shows the heading ">" of tuggle #2. Cell (2,2) is not blue, because, just as buggles do, tuggles paint a cell when they leave it (if their brush is down).

t2.brushUp();
t2.dropBagel(); 
t2.forward();
t2.dropBagel(); 
t2.forward();
t2.dropBagel(); 
System.out.println(tw);
+-+-+-+-+
| | | |^|
+-+-+-+-+
|B|O|O|>|
+-+-+-+-+
|>|r|r|R|
+-+-+-+-+

Notes: Cells (2,2) and (3,2) are unpainted with a bagel, so they show "O". Cell (4,2) is painted red with a bagel, but it only shows the heading of ">" of tuggle #2.

t3.setPosition(1, 3);
t3.setColor(Color.green);
t3.forward();
System.out.println(tw);
+-+-+-+-+
|g|>| |^|
+-+-+-+-+
|B|O|O|>|
+-+-+-+-+
|>|r|r|R|
+-+-+-+-+

Notes: Cell (1,3) is painted green with no bagel so it shows "g". Cell (2,3) shows the heading of ">" of tuggle #2. Cell (1,1) still shows the heading of ">" of tuggle #4.

t3.dropBagel(); 
t3.right();
t3.forward(2);
t4.setHeading(Direction.WEST);
System.out.println(tw);
+-+-+-+-+
|g|G| |^|
+-+-+-+-+
|B|G|O|>|
+-+-+-+-+
|<|V|r|R|
+-+-+-+-+

Notes: Cells (2,3) and (2,2) are painted green and have bagels so they show "G". Cell (2,1) is painted red with no bagel but only shows the heading of "V" of tuggle #3. Cell (1,1) shows the heading of "<" of tuggle #4.

Concrete Representations

There are many different concrete representations that could be used to implement the Tuggle and TuggleWorld classes. In this assignment, we require you to use the following concrete representations:

Your classes should contain no other instance variables other than the ones specified above.

Note that the concrete instance variables specified for TuggleWorld differ from the abstract state variables specified in the TuggleWorld contract. This highlights the power of data abstraction.


Task 1: Object Diagram

Draw an object diagram that represents the state of the TuggleWorld instance and all four Tuggle instances after executing the code from the above Example section. You should use the concrete representations defined in the Concrete Representations section for displaying TuggleWorld and Tuggle instances. You may use our standard abbreviated notations for references to Direction and Color instances, but should explicitly show all Point instances. (You need only show the Points that are still "alive" at the end of the code; you do not have to show intermediate Points that were created during the execution of the code but can no longer be referenced.)

Task 2: Implementing the Tuggle and TuggleWorld classes

Download the ps08_programs folder from the CS111 download directory. This contains an implementation of the Direction class you have used in BuggleWorld.

In the ps08_programs folder, create new files Tuggle.java and TuggleWorld.java that implement all the methods defined by the Tuggle contract and TuggleWorld contract. You must use the concrete representations specified in the above Concrete Representations section.

Your TuggleWorld.java class should also contain a main() method that, when called on the argument example1 (via the DrJava command line java TuggleWorld example) executes the example shown in the above Example section.

Notes:


Task 3: A TuggleScript Interpreter

Overview of TuggleScript

It is possible to test other TuggleWorld programs by adding them to the main() method of TuggleWorld.java. However, this is cumbersome, since it requires editing the main() method and recompiling TuggleWorld.java.

In this Task, you will implement an interpreter for a mini-language we'll call TuggleScript that makes it possible to test TuggleWorld programs without editing the main() method or recompiling TuggleWorld.java. Instead, you can write TuggleScript programs in a file and ask the TuggleScript interpreter to execute these files.

TuggleScript programs have the following format:

For example, below is the contents of the file example.tgl (our convention is to use the .tgl extension for TuggleScript programs). This corresponds to the TuggleWorld program from the Example section above (except that it does not include the System.out.println() statements):

3 4 4
1 forward 3
1 dropBagel
1 left
1 forward 2
1 dropBagel
2 setPosition 1 2
2 setColor blue
2 dropBagel
2 forward
2 brushUp
2 dropBagel
2 forward
2 dropBagel
2 forward
2 dropBagel
3 setPosition 1 3
3 setColor green
3 forward
3 dropBagel
3 right
3 forward 2
4 setHeading west
When a TuggleScript program finishes executing, it displays a textual representation of the TuggleWorld state at the end of the program. So the execution of example.tgl ends by displaying:
+-+-+-+-+
|g|G| |^|
+-+-+-+-+
|B|G|O|>|
+-+-+-+-+
|<|V|r|R|
+-+-+-+-+

Your Task

In this task, you will implement a TuggleScript interpreter by defining two new methods in the TuggleWorld class:

public void execCommand (String cmd)
Executes the TuggleScript command cmd in this world.

public static void execFile (String filename, boolean traceOn)
Executes the TuggleScript program in the file named filename by creating an instance of TuggleWorld as described by the first line of the file and executing all the commands in the remaining lines of the file relative to this world. Displays the state of the world after executing all the commands in the file. If traceOn is true, then for every command in the file it additionally displays (1) the state of the world before executing the command and (2) the command itself. If traceOn is false, only the final state of the world is displayed.

An an illustration of execCommand, the effect of the TuggleScript program example.tgl can be achieved by executing the following:

TuggleWorld tw = new TuggleWorld(3,4,4);
tw.execCommand("1 forward 3");
tw.execCommand("1 dropBagel");
tw.execCommand("1 left");
tw.execCommand("1 forward 2");
tw.execCommand("1 dropBagel");
tw.execCommand("2 setPosition 1 2");
tw.execCommand("2 setColor blue");
tw.execCommand("2 dropBagel");
tw.execCommand("2 forward");
tw.execCommand("2 brushUp");
tw.execCommand("2 dropBagel");
tw.execCommand("2 forward");
tw.execCommand("2 dropBagel");
tw.execCommand("2 forward");
tw.execCommand("2 dropBagel");
tw.execCommand("3 setPosition 1 3");
tw.execCommand("3 setColor green");
tw.execCommand("3 forward");
tw.execCommand("3 dropBagel");
tw.execCommand("3 right");
tw.execCommand("3 forward 2");
tw.execCommand("4 setHeading west");
System.out.println(tw);

An an illustration of execFile, TuggleWorld.execFile("example.tgl", false) displays

+-+-+-+-+
|g|G| |^|
+-+-+-+-+
|B|G|O|>|
+-+-+-+-+
|<|V|r|R|
+-+-+-+-+

but TuggleWorld.execFile("example.tgl", true) displays

+-+-+-+-+
| | | | |
+-+-+-+-+
| | | | |
+-+-+-+-+
|>| | | |
+-+-+-+-+

1 forward 3

+-+-+-+-+
| | | | |
+-+-+-+-+
| | | | |
+-+-+-+-+
|>|r|r|>|
+-+-+-+-+

1 dropBagel

+-+-+-+-+
| | | | |
+-+-+-+-+
| | | | |
+-+-+-+-+
|>|r|r|>|
+-+-+-+-+

1 left

+-+-+-+-+
| | | | |
+-+-+-+-+
| | | | |
+-+-+-+-+
|>|r|r|^|
+-+-+-+-+

1 forward 2

+-+-+-+-+
| | | |^|
+-+-+-+-+
| | | |r|
+-+-+-+-+
|>|r|r|R|
+-+-+-+-+

1 dropBagel

+-+-+-+-+
| | | |^|
+-+-+-+-+
| | | |r|
+-+-+-+-+
|>|r|r|R|
+-+-+-+-+

2 setPosition 1 2

+-+-+-+-+
| | | |^|
+-+-+-+-+
|>| | |r|
+-+-+-+-+
|>|r|r|R|
+-+-+-+-+

2 setColor blue

+-+-+-+-+
| | | |^|
+-+-+-+-+
|>| | |r|
+-+-+-+-+
|>|r|r|R|
+-+-+-+-+

2 dropBagel

+-+-+-+-+
| | | |^|
+-+-+-+-+
|>| | |r|
+-+-+-+-+
|>|r|r|R|
+-+-+-+-+

2 forward

+-+-+-+-+
| | | |^|
+-+-+-+-+
|B|>| |r|
+-+-+-+-+
|>|r|r|R|
+-+-+-+-+

2 brushUp

+-+-+-+-+
| | | |^|
+-+-+-+-+
|B|>| |r|
+-+-+-+-+
|>|r|r|R|
+-+-+-+-+

2 dropBagel

+-+-+-+-+
| | | |^|
+-+-+-+-+
|B|>| |r|
+-+-+-+-+
|>|r|r|R|
+-+-+-+-+

2 forward

+-+-+-+-+
| | | |^|
+-+-+-+-+
|B|O|>|r|
+-+-+-+-+
|>|r|r|R|
+-+-+-+-+

2 dropBagel

+-+-+-+-+
| | | |^|
+-+-+-+-+
|B|O|>|r|
+-+-+-+-+
|>|r|r|R|
+-+-+-+-+

2 forward

+-+-+-+-+
| | | |^|
+-+-+-+-+
|B|O|O|>|
+-+-+-+-+
|>|r|r|R|
+-+-+-+-+

2 dropBagel

+-+-+-+-+
| | | |^|
+-+-+-+-+
|B|O|O|>|
+-+-+-+-+
|>|r|r|R|
+-+-+-+-+

3 setPosition 1 3

+-+-+-+-+
|>| | |^|
+-+-+-+-+
|B|O|O|>|
+-+-+-+-+
|>|r|r|R|
+-+-+-+-+

3 setColor green

+-+-+-+-+
|>| | |^|
+-+-+-+-+
|B|O|O|>|
+-+-+-+-+
|>|r|r|R|
+-+-+-+-+

3 forward

+-+-+-+-+
|g|>| |^|
+-+-+-+-+
|B|O|O|>|
+-+-+-+-+
|>|r|r|R|
+-+-+-+-+

3 dropBagel

+-+-+-+-+
|g|>| |^|
+-+-+-+-+
|B|O|O|>|
+-+-+-+-+
|>|r|r|R|
+-+-+-+-+

3 right

+-+-+-+-+
|g|V| |^|
+-+-+-+-+
|B|O|O|>|
+-+-+-+-+
|>|r|r|R|
+-+-+-+-+

3 forward 2

+-+-+-+-+
|g|G| |^|
+-+-+-+-+
|B|G|O|>|
+-+-+-+-+
|>|V|r|R|
+-+-+-+-+

4 setHeading west

+-+-+-+-+
|g|G| |^|
+-+-+-+-+
|B|G|O|>|
+-+-+-+-+
|<|V|r|R|
+-+-+-+-+

Notes: