CS111, Wellesley College, Fall 2007

Problem Set 3

Due Tuesday, October 2 at the start of class

Reading

About this Problem Set

In this problem set, you will practice reading, writing, and understanding methods. Think carefully about what patterns should be abstracted into methods and which patterns should be named as variables.

To get the code for this assignment, connect to the cs server via Fetch or WinSCP. Use the cs111d account and the password given in class and download the ps03_programs folder.

How to turn in this Problem Set

You must 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, either on an external storage device (like a USB drive), or in your private directory (or, to play it safe, both).

Hardcopy Submission

Your hardcopy packet should consist of:

  1. The cover page;
  2. Your modified KnitWorld.java file from Task 1;
  3. Your modified QuiltWorld.java file from Task 2.

Staple these together, and submit the packet at the start of class on the due date. Don't forget to put one of the instructors' stickers on the cover page!

Softcopy Submission

Save the modified KnitWorld.java and QuiltWorld.java files in the ps03_programs folder. Submit the entire ps03_programs folder to your drop folder on the CS111 server.


PictureWorld Examples

To demonstrate some of the capabilities of PictureWorld, we have included the file MyPictureWorld.java in the ps03_programs folder you downloaded. You can compile the file and run the program if you are interested. This file has lots of examples of Picture manipulations. You are not required to do anything with this file for the assignment. We have included it only because it demonstrates lots of Picture examples. Most of the examples are commented out so that the menu of the applet is not cluttered, but feel free to un-comment whatever examples you are interested in experimenting with. (This file is essentially the same as the SimplePictureWorld.java file we studied in the first PictureWorld lecture.)


Task 0: Meet the Instructors

For the first two problem sets, you met two of the instructors in their office hours. This week, you must meet the third one of us! Go to the third instructor's office hours and secure a sticker (you cannot receive a sticker from an instructor whom you have previously received a sticker from). If you cannot make office hours, you must schedule an appointment. Place the sticker on the problem set cover page. Now you have met all three of us!


Task 1: Knit Picking

Escher's Knitting Patterns

Dutch artist M. C. Escher is renowned for creating artwork based on interlocking patterns and visual playfulness. Here we will experiment with "knitting patterns" that Escher himself experimented with in 1943. (For more details on Escher's artwork, see M.C. Escher: Visions of Symmetry by Doris Schattschneider, W.H. Freeman and Company, 1990).

Escher's knitting patterns were based on the following two primitive patterns that he designed:


Pattern A


Pattern B

We will call these patterns A and B. We can make many variants of A an B by rotating them, flipping them, and painting their stripes different colors. These variants of A and B can be combined to form an amazing number of patterns that resemble the weave patterns of knitted yarn. For example, study the following four knitting patterns, all of whose basic squares are versions of A and B that have been rotated, flipped, and colored in various ways.

Playing with Knitting Patterns in PictureWorld

PictureWorld is a perfect tool for experimenting with Escher's knitting patterns. The file KnitWorld.java in the ps03_programs folder contains several methods that aid in this experimentation. Colored versions of the A and B patterns are created by the following two black-box methods in KnitWorld.

	public Picture A(Color c1, Color c2, Color c3, Color c4, Color c5)
	public Picture B(Color c1, Color c2, Color c3, Color c4, Color c5)

The five color arguments of A and B paint the patterns in the way indicated by the following examples:


A(Color.red, Color.blue,
Color.green, Color.yellow, Color.magenta);


B(Color.red, Color.blue,
Color.green, Color.yellow, Color.magenta);

The tileKnit method is useful for constructing many simple knitting patterns:

public Picture tileKnit (Picture p1, Picture p2, Picture p3, Picture p4) 
{
     return fourSame(fourSame(fourPics(p1, p2, p3, p4)));
}

The fourSame and fourPics methods are similar to those presented in lecture and lab:

public Picture fourSame (Picture p) 
{
     return fourPics(p, p, p, p);
}

public Picture fourPics (Picture p1, Picture p2, Picture p3, Picture p4) 
{
     return above(beside(p1,p2), beside(p3,p4));
} 

Using the above methods, plus the usual picture combinators of PictureWorld, it is possible to make pictures for all four knitting patterns shown above. Here is a knit1() method, parameterized over two colors, that generates the knit1 pattern shown above:

public Picture knit1(Color c1, Color c2) 
{
     Picture A1 = A(c1, c2, c1, c1, c2);
     Picture B1 = B(c2, c1, c2 ,c2, c1);

     return tileKnit(A1, B1, A1, B1);
} 

The knit2() method is similiar in structure to knit1(), but uses different colorings, flips, and rotations:

public Picture knit2(Color c1, Color c2) 
{
     Picture A1 = A(c1, c2, c1, c2, c1);
     Picture B1 = B(c2, c1, c2 ,c1, c2);
     return tileKnit(flipVertically(B1),
                     flipVertically(A1),
		     clockwise180(B1),
		     clockwise180(A1));
} 

The knit3() method is parameterized over three colors rather than two:

public Picture knit3(Color c1, Color c2, Color c3) 
{
     return tileKnit(B(c1, c2, c1, c3, c1),
                     clockwise90(B(c1, c3, c2, c2, c1)),
                     flipHorizontally(B(c1, c3, c1, c2, c1)),
                     flipHorizontally(clockwise90(A(c1, c2, c3, c3, c1))));
} 

The knit4 pattern has a more complex repetition pattern than can be described by tileKnit(). Two alternative knit4() methods are shown below. Both methods produce identical pictures. The first uses 12 local variables to refer to the various intermediary pictures that are generated while constructing the final picture pattern. The second uses only 2 local variables to refer to intermediary pictures, instead preferring to nest expressions by having fruitful method invocations, which return Picture objects, serve as arguments to other methods with Picture parameters. The two alternative methods for capturing the knit4 pattern represent two different problem solving approaches that achieve the same result.

public Picture knit4(Color c1, Color c2)
{
    Picture A1 = A(c1, c2, c1, c1, c2);
    Picture B1 = B(c1, c2, c1, c2, c1);
    Picture A2 = A(c2, c1, c2, c1, c2);
    Picture B2 = B(c2, c1, c2, c2, c1);
    Picture A1_clockwise270 = clockwise270(A1);
    Picture B1_flipHorizontally = flipHorizontally(B1);
    Picture B2_flipDiagonally = flipDiagonally(B2);
    Picture B2_clockwise270 = clockwise270(B2);
    Picture A2_flipHorizontally = flipHorizontally(A2);
    Picture A1_flipDiagonally = flipDiagonally(A1);
    
    Picture tile1 = fourPics(B1, A1_clockwise270, B1_flipHorizontally, B2_flipDiagonally);
    Picture tile2 = fourPics(A2, B2_clockwise270, A2_flipHorizontally, A1_flipDiagonally);
    return fourSame(fourPics(tile1, tile2, tile1, tile2));
}
public Picture knit4_alternative(Color c1, Color c2) 
{
     Picture tile1 = fourPics(B(c1, c2, c1, c2, c1),
                              clockwise270(A(c1, c2, c1, c1, c2)),
                              flipHorizontally(B(c1, c2, c1, c2, c1)),
                              flipDiagonally(B(c2, c1, c2, c2, c1)));
     Picture tile2 = fourPics(A(c2, c1, c2, c1, c2),
                              clockwise270(B(c2, c1, c2, c2, c1)),
                              flipHorizontally(A(c2, c1, c2, c1, c2)),
                              flipDiagonally(A(c1, c2, c1, c1, c2)));
     return fourSame(fourPics(tile1, tile2, tile1, tile2));
}

Your Task

In this problem, you will define methods that draw the following two knitting patterns: knit5 (shown in the LEFT column) and knit6 (shown in the RIGHT column). knit5() is parameterized over four colors, while knit6() is parameterized over two colors. The particular knit5 patterns shown below are created by the invocation that you can read in the top of the KnitWorld picture (in the yellow bar at the top of the image). For example, the top left knit5 pattern in created by this invocation: knit5(Color.red, Color.magenta, Color.blue, Color.green).

The file KnitWorld.java contains the skeletons of two methods that you should flesh out :

public Picture knit5(Color c1, Color c2, Color c3, Color c4) 
{
     // Put your definition here.

}

public Picture knit6(Color c1, Color c2) 
{
     // Put your definition here.

}

To begin this problem, first study the knit1() through knit4() methods above and convince yourself that they do in fact draw the four knitting patterns shown in the previous section. Your solutions to knit5() and knit6() will be similar to the knit1() through knit4(). Next, you should carefully study the knit5 and knit6 patterns to determine which rotations, flips, and colorings of the basic patterns A and B are employed. The final step is to encode your findings in Java code in the method bodies of knit5() and knit6(). You may find it helpful to define your own auxiliary methods in addition to defining knit5() and knit6().

Testing your program

To make testing a little easier, we have included a folder Test which contains working examples of the patterns you need to make so that you can compare your work with the examples (but, alas, no Java code!). There are two different ways to see the examples. (1) You can start Dr. Java and open the file CS111.txt in the Test folder that you downloaded with ps03_programs, click on the "Interactions" tab at the bottom of the Dr. Java window and type "java KnitWorldSoln" in the "Interactions" pane. (2) Alternatively, using a web browser (e.g., Mozilla Firefox, Apple Safari, Internet Explorer), open the file KnitWorldSoln.html in the Test folder that you downloaded with ps03_programs. You can choose knit5 and knit6 from the menu to compare these examples with your own work.


Task 2: QuiltWorld

Blithe Buggle, co-founder of the Buggle Bagel Ruggle Company, has been looking for new ways to expand her company's product line. Although the bagel rugs marketed by the company are popular, they are difficult to manufacture because of the labor costs (each rug is hand-drawn by a Buggle) and and raw material costs (bagels cost more than you think!). Blithe thinks the company should diversify to produce other products with interesting designs, such as quilts,wallpaper, and sweaters. Blithe is currently experimenting with the picture drawing software presented in CS111 to design quilts. Here is an example of one of Blithe's quilt designs, which we will call quilt1.


quilt1()

You and several other CS111 students have been hired as interns at the Buggle Bagel Ruggle Company to help Blithe design quilts. Your project is to use PictureWorld to generate the quilt design shown above. The quilt above is just one sample of the quilt design. Your code will contain methods that take color parameters, and therefore your code will be able to generate lots of different quilts, in the same pattern as above, but with color variation. This description of the assignment will use the quilt above as an example, but keep in mind that your code must be generic and able to handle different color variations of the above pattern. There is a file called QuiltWorld.java in the ps03_programs folder. All the methods that you will define for this problem will be in the QuiltWorld class. Your goal is to flesh out the skeleton of the quilt1() method so that it returns a picture corresponding to the quilt shown above. This picture is ultimately generated by combining primitive pictures generated by the following two black-box methods:

public Picture patch (Color c)
Returns a rectangular patch of color c with a black border that fills a given picture frame.

public Picture triangles(Color c1, Color c2)
Returns a picture that consists of two triangles filling the given picture frame: a black-bordered triangle of color c1 in the lower left corner of the frame; and a black-bordered triangle of color c2 in the upper right corner of the frame.

For example, below are the pictures generated by some sample invocations of these methods:


patch(Color.red);


triangles(Color.red, Color.blue);

Divide, Conquer, and Glue

The key to solving the problem of defining quilt1() is to note that the picture can be decomposed into smaller pictures that are used more than once in the larger picture. For example, the upper right quadrant is a picture that we'll call corner:


corner(Color.red, Color.blue, Color.green, Color.darkGray, Color.cyan, Color.magenta)

The whole picture can be decomposed into four copies of corner that have different rotations. Once we figure out how to define the corner picture, we can combine four rotated copies of the picture to form the desired quilt picture. This is an excellent illustration of the divide, conquer, and glue problem solving strategy we will use throughout this course:

  1. Divide the problem into subproblems. Here there is one subproblem: defining corner().
  2. Conquer the subproblems by solving them. In this case, the solution to the subproblem is a picture named corner.
  3. Glue the solutions to the subproblems together to form the solution to the whole problem. Here, we combine four rotated versions of corner to construct our quilt.

But how do we solve the problem of defining the corner picture? By applying the divide, conquer, and glue strategy again! In this case, corner naturally decomposes into four quadrants:


quadrant2(Color.blue,Color.green,Color.darkGray,Color.cyan,Color.magenta)


quadrant3(Color.magenta,Color.darkGray)


quadrant1(Color.red,Color.blue,Color.green,Color.darkGray,Color.cyan)


quadrant2(Color.blue,Color.green,Color.darkGray,Color.cyan,Color.magenta)

We give the names quadrant1, quadrant2, and quadrant3 to each distinct pattern. We notice that quadrant2 is used twice in the corner! We can continue to use divide, conquer, and glue to decompose each quadrant above into smaller and smaller pictures. When does the process stop? When we get to pictures so small that they are trivial to solve. In this case the trivial pictures are those generated by the patch() and triangles() methods.

Auxiliary Methods

A general principle of computer science is “never write any piece of code more than once.” If you find yourself writing the same or similar code more than once in your program, you should write methods that capture the patterns of the repeated code and invoke the methods instead.

The divide, conquer, and glue process of defining quilt1() naturally exposes the need for numerous auxiliary methods. As part of working on this assignment, you should define and use the following methods. Skeletons for all of these methods can be found in QuiltWorld.java.

public Picture patch_2x2 (Color c)
Returns a picture consisting of four rectangular patches of color c with black lines between the patches. (Remember that patch(c) returns a picture with a black border.)

public Picture triangles_2x2 (Color c1, Color c2)
Returns a picture similar to triangles(c1, c2) except that each large triangle is composed out of three smaller fragments (two triangles and a rectangle).

public Picture LL (Picture p)
Returns a picture which divides the picture space into four quadrants and places the given picture in the lower left corner.

public Picture LLNest (Picture p1, Picture p2)
Returns a picture which places picture p2 over the lower left corner of picture p1.

Here are example invocations of the four methods above:


patch_2x2(Color.red);


triangles_2x2(Color.red, Color.blue);


LL(triangles(Color.red, Color.blue));


LLNest(patch(Color.red), triangles(Color.red, Color.blue));

Completing the Assignment

All of the methods in the PictureWorld and QuiltWorld contracts are available to you. At a minimum, you should have methods that correspond to each pattern described above. The QuiltWorld.java file has skeletons for all the methods that you must define. In addition to that, you should define additional methods which capture patterns that are used over and over again. It is also helpful to define local variables within your methods to give names to pictures that you generate as part of your solution.

The quadrant3 pattern is made up of invocations of LLNest() and triangles(). You do not need anything else.

Testing your program

To make testing a little easier, we have included a folder Test that contains working examples of the patterns you need to make so that you can compare your work with the examples (but, alas, no Java code!). There are two different ways to see the examples. (1) You can start Dr. Java and open the file CS111.txt in the Test folder that you downloaded with ps03_programs, click on the "Interactions" tab at the bottom of the Dr. Java window and type "java QuiltWorldSoln" in the "Interactions" pane. (2) Alternatively, using a web browser (e.g., Mozilla Firefox, Apple Safari, Internet Explorer), open the file QuiltWorldSoln.html in the Test folder that you downloaded with ps03_programs. You can choose components of your design, such as LL or LLNest to compare them to your work.

Your final Task.

Oh no! Blithe has just designed this new quilt shown below, using the same pattern as above, but with different colors. She forgot how she actually created this one. She hires you to figure out which Color parameters were used in what order to create the pattern below. To solve this problem, write a new method called quilt2() that produces the quilt shown below.

quilt2()