![]() |
Problem Set 2 Optional Challenge Due: Tuesday September 18 at the start of class |
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 problems of the first two problem sets, 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
byheight
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 bewidth + 1
cells in front of its original position, its final color should becol
, 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:
n
|
n/2
|
n/3
|
n/4
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The following equations are also always true (both in Java arithmetic and traditional arithmetic):
1 + (n/2) = (n + 2)/2
1 + ((n - 1)/2) = (n + 1)/2
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 are 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!):
n = 1 + ((n - 1)/2) + (n/2)
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":
Invoking thepublic void CUP() { C(Color.blue, 3, 5); U(Color.green, 8, 3); P(Color.red, 4, 12); }
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:
C()
,
d()
, G()
, H()
,
I()
, P()
, and U()
.
valentine()
method that draws Fontaine's
Valentine card design in a 51 x 51 grid, as depicted at the beginning of
this problem.
The ps02_programs
folder you downloaded from
the CS111 server contains a folder called HuggleWorld
.
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
files for testing your methods:
C()
,
U()
, and
P()
methods, run the CupWorld.html
applet. This should yield the fourCUPs
figure
depicted above.
FontTestWorld.html
applet. This should
yield the FontTest figure depicted above.
valentine()
method, run the
HuggleWorld.html
applet. This should yield
Fontaine's Valentine card design.
Hints/Notes:
FontBuggle
method, you should assume
that the brush state of the buggle is down when the method is called and
when the method returns.
1 + ((width - 1)/2)
cells wide, the buggle should only go forward
((width - 1)/2)
steps to draw half the base of the
'I' before turning left to draw the stem of the 'I'. The reason
that no "1 +" is needed is that the initial cell occupied by the
buggle should not be included in the number of forward
steps. This is why all the "half" distances in the letter
specifications have a "1 + " at the beginning: so it will be
easy for you to subtract off the 1 in your code.
public void paintCell (Color c)
c
regardless of the buggle's
color. Invoking this method does not change the color of the
buggle.
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).