![]() |
Problem Set 2 Due: Tuesday, February 18 by 11 pm |
To get the code for this assignment, connect to cs111 download directory via Fetch and download the folder ps2_programs from the directory /cs111d.
Save the modified RugWorld.java
and
FontBuggle.java
files in the ps2_programs
folder. Submit the entire ps2_programs
folder to your
drop folder on the cs111 server. Turn in a hardcopy of the JEM
diagram from task 1 and your modified Writing2.java
, RugWorld.java
,
FontBuggle.java
, and HuggleWorld.java
When submitting your hardcopies, we ask that you turn in only one package of materials. Please staple your files together with a cover page, and submit your hardcopy package by sliding it under the door of Elena's office (E127, in minifocus).
IMPORTANT NOTES:
In this part of the homework, you will use the Java Execution
Model to draw an Execution Diagram that summarizes the execution of a
simple Buggle program. It is important to become familiar with the
conventions for drawing Execution Diagrams, since they are an
important tool for explaining the behavior of Java programs. In
particular, Execution Diagrams explain the meaning of method
invocation, parameter passing, local variable declarations, and the
this
variable. You will be expected to draw an Execution
Diagram on Exam 1.
Before continuing with this problem, please study the conventions for drawing execution diagrams (i.e. your notes from lecture and the reading for this problem set).
Below are the declarations for two classes: a SwapWorld class that is a subclass of BuggleWorld and a SwapBuggle class that is a subclass of Buggle.
public class SwapWorld extends BuggleWorld { public void run () { SwapBuggle bg1 = new SwapBuggle(); SwapBuggle bg2 = new SwapBuggle(); SwapBuggle bg3 = new SwapBuggle(); Point pt1 = new Point(6,3); Point pt2 = new Point(4,5); bg1.setPosition(pt1); bg2.setPosition(pt2); bg3.setPosition(new Point(pt1.x-pt2.x, pt1.y+pt2.y)); bg2.setColor(Color.blue); bg1.setColor(Color.green); bg2.left(); bg3.right(); bg2.swap(bg3); bg3.swap(bg1); } } class SwapBuggle extends Buggle { public void swap (Buggle bg1) { Point pt1 = this.getPosition(); Point pt2 = bg1.getPosition(); Color c1 = this.getColor(); Color c2 = bg1.getColor(); this.setPosition(pt2); bg1.setPosition(pt1); this.setColor(c2); bg1.setColor(c1); } }
Suppose that Object Land contains an instance of the
SwapWorld
class that has the reference label SW1.
Your assignment is to draw an Execution Diagram for the execution of
the statement
SW1.run()
Please be careful. This code is specifically designed to be tricky in a number of places. Be sure to pay attention to the following:
run()
and one
for each of the two invocations of swap()
. Each
execution frame should have two parts: (1) a variables section and
(2) a statement section. Each variable section should include: (1)
a this
variable; (2) any parameters declared by the
invoked method; and (3) any local variables declared within the
body of the invoked method. The statement section should show the
result of evaluating all expressions. Each expression should be
replaced by a representation of its value.
SwapWorld
class, three instances of
the SwapBuggle
class, three instances of the
Point
class, and three instances of the
Color
class. Label each of your objects in Object
Land with a unique reference label (e.g. B1, B2, B3 for the
buggles; P1, P2 for the points, etc). It is a bad idea to
use reference labels which are the same as any variable names in
your code. Use these labels in place of pointers. You need not
show any Direction
instances in Object Land; use the
convention of representing such instances by special reference
labels like WEST
. Your diagram should show the
state of each object after the completion of the execution of the
run
method.
Your assignment:
Using methods, create the above grid. The file Writing2.java contains Java code which creates a larger grid and defines a LetterBuggle, a new class of objects which extends the Buggle class. A new LetterBuggle named ellie has also been created for you, along with two LetterBuggle methods; writeName, and writeJ, as shown below:
Perform the following steps to solve the problem://write the word "JAVA" around the perimeter of the grid public void run () { LetterBuggle ellie = new LetterBuggle(); ellie.writeName(Color.red, Color.blue, Color.yellow); // statements which will write the word in various colors around the perimeter of the grid } class LetterBuggle extends Buggle { //write the word "JAVA", in the appropriately colored letters, //by invoking methods with appropriate color parameters for writing the individual letters //Note that the J and the V are always the same color, and each A can be a different color from the // color of the J and V. public void writeName (Color c1, Color c2, Color c3) { //fill in with statements which will position this Buggle correctly to start writing this.writeJ(c1);//write the "J" in color c1 // fill in with statements which will write the "A V A" in the correct colors } //write the letter "J" public void writeJ(Color jcolor) { // set the buggle's color to jcolor this.left(); // face NORTH this.forward(); // draw hook in lower left of "J" //the rest of the statements for writing a "J" } //methods for writing the other letters in the word JAVA }
Alternatively, to be on the safe side (i.e. to make sure that you are not running the code from the previous task instead of the new one), you might want to quit CodeWarrior entirely and reopen it for the new project. To do this
Here is an example of a rug they created:
The buggles are great designers, but, unfortunately, they don't know much about manufacturing. It takes so long to hand-drop the bagels individually that it's impossible to make any money. Luckily for them, there is a way to automate the production of the rugs. As it turns out, the design shown above can be produced using just 4 different 3x3 grids of bagel patterns:
![]() pattern 1 |
![]() pattern 2 |
![]() pattern 3 |
![]() pattern 4 |
The rug pattern includes a lot of repetitive patterns. This means that there are many opportunities for using methods to generate the pattern efficiently. Your task is to write the code which will create the rug pattern shown above in the most efficient manner you can think of. The code for this problem is contained in the RugWorld folder. The file RugWorld.java contains the initial set-up for creating the rug shown above. becky, bobby, bertie, benny and billy have hired a RugBuggle (another new class of objects which extends the Buggle class) named weaver to produce the rugs. You should add your code to this file, but you should not remove any existing code.
You must observe the following constraints:
public void pattern1 (Color c1, Color c2) { // add code here }
This method should take two Color parameters named c1
and c2. c1 will represent the areas colored in black above
and c2 will represent the areas colored in yellow above. Note that
the actual rug uses the colors cyan and pink in one instantiation of the
pattern and green and orange in the other instantiation of the pattern.
The Story
Fontaine Buggle is very impressed by the creative work of her cousins at the Buggle Bagel Ruggle Company. But she thinks that buggles can use their considerable talents to do more than just drop bagels in interesting patterns.
Inspired by the buggle writing problem of Problem Set 1 (remember "Java"?), Fontaine wants buggles to be able to write words using letters of any color drawn in rectangles of arbitrary size and orientation. As a simple example of what can be done with this capability, Fontaine designs the following Valentine card:
The card uses the seven letters 'C', 'd', 'G', 'H', 'I', 'P', and 'U'. Note that the 'U' appearing in "CUPId" and "HUG" has the same basic shape even though it is written in rectangles of different sizes (a 5x5 rectangle in the case of the 'U' in "CUPId" and a 7x17 rectangle int the case of the 'U' in "HUG").
Letter Methods and their Contracts
Fontaine recognizes that methods can be used to capture the similarity in shape while abstracting over the color and rectangle size. She defines a new FontBuggle class that is a subclass of Buggle extended with methods that draw the seven letters of the Valentine card. For example, the FontBuggle class has a method for drawing the letter 'U' according to the following contract:
public void U (Color col, int width, int height);
Assume the initial brush state of this buggle is down. Consider the width by height rectangle such that this buggle is in the lower left hand corner facing along the width edge. Executing this method causes this buggle to draw the letter 'U' inscribed in the rectangle, as shown below. The heading of the buggle should not change, but its final position should be width + 1 cells in front of its original position, its final color should be col, and its final brush state should be down.
Fontaine defines similar methods for the other six letters, whose contracts are the same as that for U() except for the shape inscribed in the rectangle. The shapes drawn by the C(), d(), G(), H(), I(), and P() methods are depicted below:
Java Arithmetic
The dimensions in the above pictures are given in terms of Java integer arithmetic. Java integer arithmetic is pretty much what you would expect except that division of two integers always yields the integer that results by truncating (not rounding) the decimal portion of the exact result. For example:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The following equations are also always true (both in Java arithmetic and traditional arithmetic):
The reason that we prefer the left-hand side versions to the right-hand side versions in the above diagram is that the left-hand side versions turn out to be more useful when drawing the letters with buggles. (See the note on fencepost errors in the tasks section, below.)
You should also convince yourself that in Java integer arithmetic, the following equation is always true (this equation is not true for traditional arithmetic!):
Stringing Letters Together
The final position and heading of a FontBuggle after drawing a letter is designed to facilitate stringing letters together to form words. If the FontBuggle is asked to draw a new letter, both letters will be on the same "baseline", and there will be one cell of space between the previous letter and the new one. For example, consider the following method for drawing the word "CUP":
public void CUP () { C(Color.blue, 3, 5); U(Color.green, 8, 3); P(Color.red, 4, 12); }
Invoking the CUP() method on a FontBuggle causes it to draw the following letters:
Buggle Jumping
Since letters do not always directly follow one another, it is useful to have the following jump() method, which changes the relative position of a FontBuggle by fwd units in the forward direction and lft units to its left. (Either number may be 0 or negative.)
public void jump (int fwd, int lft) { brushUp(); forward(fwd); left(); forward(lft); right(); brushDown(); }
Because the parameters to jump() are relative to the buggle's current position and heading, the method works regardless of the buggle's initial state. After jumping, it is often desirable to turn the buggle; the following three methods abstract over the three possible ways of turning:
public void jumpAndTurnLeft (int fwd, int lft) { jump(fwd,lft); left(); } public void jumpAndTurnRight (int fwd, int lft) { jump(fwd,lft); right(); } public void jumpAndTurn180 (int fwd, int lft) { jumpAndTurnLeft(fwd,lft); left(); }
As an example of buggle jumping, consider the following method:
public void fourCUPs () { CUP(); jumpAndTurnLeft(4, 0); CUP(); jumpAndTurnLeft(4, 0); CUP(); jumpAndTurnLeft(4, 0); CUP(); jumpAndTurnLeft(4, 0); }
Invoking fourCups() on a FontBuggle at position (3,3) facing eastward yields the following picture:
As another example of buggle jumping, consider the following testFont() method that draws the C(), d(), G(), H(), I(), P(), and U() shapes for 5x5, 4x4, 3x5, 4x4, and 4x3 rectangles for both the east and north buggle orientations:
public void testFont() { testSizes(); jumpAndTurnLeft(27,0); testSizes(); } public void testSizes() { testLetters(5,5); jump(-42,6); testLetters(4,5); jump(-35,6); testLetters(3,5); jump(-28,6); testLetters(5,4); jump(-42,5); testLetters(5,3); jump(-42,4); } public void testLetters(int w, int h) { C(Color.red, w, h); d(Color.green, w, h); G(Color.black, w, h); H(Color.blue, w, h); I(Color.yellow, w, h); P(Color.magenta, w, h); U(Color.cyan, w, h); }
Executing testFont() should yield the following result:
Your tasks in the problem are to define the following eight FontBuggle methods:
You should begin the problem by downloading the HuggleWorld folder from the CS111 download folder. This folder has a file FontBuggle.java that contains skeletons of the eight methods you should define, as well as the jump(), jumpAndTurnLeft(), jumpAndTurnRight(), and jumpAndTurn180() methods described above.
The HuggleWorld folder also contains three .html for testing your methods:
Hints/Notes:
One advantage of methods is that they can be
used to significantly shrink the size of a program, as measured by
the number of lines of Java code. For the HuggleWorld program, we are
having a contest to see how small you can make your FontBuggle class and still
have it work correctly. The name of the winner(s) will be announced in the online conference
and posted on the class web page! And the lucky winner(s) will receive gift certificates to Bruegger's Bagels ($10 for first prize and $5 for second). Buggles eat bagels!!
Traditionally, program size is measured by the
number of lines in the program. Because this metric is very sensitive
to the way you format your program (commenting, use of whitespace,
placement of squiggly brackets, etc.), we will use a way of measuring
the size of a Java program that is insensitive to formatting factors.
In particular, we define the following two notions: For instance, the size of the jump() method described
above is 7, while the three methods jumpAndTurnRight(),
jumpAndTurnLeft(), and jumpAndTurn180() each have
size 3. So these four methods contribue 16 to the size of the
FontBuggle
class. To enter the contest, all you need do is
calculate the size of your FontBuggle class and write
it on your problem set cover sheet. We would like to point out that, while making your program shorter is fun
and may be a helpful exercise, in general it should not be your goal to make a program shorter. Shorter programs often lack clarity, and since programs are written not only for machines to execute, but also for humans to read, clarity is a far more important goal!
Some rules/hints: To learn much more about measuring the time
and space resources required to run a program, you should take
CS230 (Data Structures) and CS231 (Algorithms).