Computer Science 120
Introduction to Programming

Spring 2011, Siena College

Lab 1: Sorting Laundry
Due: the start of your next lab session

The Scenario

Many students must wash their own clothes for the first time when they come to college. By the time some figure out how to use laundry machines, their underwear is pink and their white T-shirts are streaked with lots of interesting colors. In the hopes of helping next year's first-year students adjust more easily to college, you are to write a laundry sorting simulator.

You may work alone or with a partner on this lab.

The Approach

It is usually good practice to develop programs incrementally. Start with a simplified version of the full problem. Plan, implement, and test a program for this simplified version. Then, add more functionality until you have solved the full problem.

To encourage this approach, this lab is divided into two parts. For the first, you will implement a laundry sorter with a very simple interface. You should plan, implement, and test a program for this problem first. The second part of the assignment asks you to add additional functionality to your simple version.

You should approach each of the two parts in this step-wise fashion. For example, in the first part you should begin by drawing the objects on the screen. Then, once your program can draw the objects, you can continue to add functionality to the program.

Lab Preparation

To make our limited lab time as productive as possible, please do the following before coming to your lab meeting:

  1. Read the lab description carefully.
  2. Prepare a written design for your program. In order to facilitate this step, a design template is provided for you at the end of the handout. You may use this template to help you organize your ideas for the program. When designing a program, you should think about its behavior in general, the instance variables you will need to store information, and the event-handling methods you will need to implement the program's behavior properly.

    As part of the design, you should also draw the layout for your graphical objects on the screen.

  3. Do not start coding before lab. It is often more productive to design a program away from the computer, and you should get into the habit of working in this way. If you come to lab with a written idea of how to approach the problem, you will be able to make progress much more quickly than you would otherwise.

Laundry Simulator: Part 1

The simulator should begin with three wash baskets on the screen and the item to be sorted, or the "swatch" (a sample piece of fabric). For our purposes, the baskets will simply be squares, and they will be labeled "whites", "darks", and "colors."

A working solution for part 1 will appear below. Click inside the applet to interact with it.



When the program starts, a color swatch will appear on the screen. The user ("laundry trainee") should then click on the basket corresponding to the color of the swatch. If the user clicks on the correct basket, the program should randomly select a new color for the next item and display it on the screen. For this part of the assignment, you should select among the three colors Color.white, Color.red, and Color.black when creating swatches. If the user clicks on an incorrect basket, the original item remains in position for another try.

A Warning!

Because swatch selection is random, it sometimes picks the same color twice in a row. When this happens and you click on the correct basket for the first item, you will get the feeling that the program did not do anything. Even though it has actually displayed a new item, the new item looks identical to the old one, so you may think nothing happened. Don't let this trick you into thinking that your version of the program (or ours) isn't working correctly. The more advanced interface in Part 2 includes counters in the display that make what the program is actually doing clearer.

Creating a BlueJ Project

For this lab, instead of downloading a pre-packaged starter, you will create a project from scratch inside BlueJ. To do so:

  1. From BlueJ's "Project" menu select "New Project...".
  2. First, make sure you are in your "csis120" directory.
  3. In the dialog box, name your project "LaundrySorter", and hit "Create".
  4. You should now see a project with no class files. Press the "New Class..." button. Create a class named "Laundry" that "extends WindowController".
  5. You should now see the "Laundry" class appear in the project. Double click on the "Laundry" class to open up the BlueJ text editor.

Design of Part 1

You will need to design an extension of the WindowController class which will display the wash baskets and the item to be sorted. Begin by laying out where all the items go on paper. The default canvas dimensions - 400x400 - should work well. The picture should look like what you see when you run the demo, but with the coordinates labeling where the baskets, text and swatch will go.

When the program begins, draw all the wash baskets (with labels) on the screen. Then draw the item of clothing that is to be sorted. For simplicity, you may always make the first item have color red. The item should actually consist of two rectangles, a FilledRect which is the appropriate color and a FramedRect which is the same size, but lays on top of the filled rectangle to form a border. (Otherwise it will be awfully difficult to see a white item!)

Think Constants

Use constants (private static final CONSTANT_NAME) for all the relevant location and size information. This makes it easier to change the layout and also makes your program much, much easier to read (presuming you give constants good names). Constant names are by convention written with all capital letters and underscores, e.g. THIS_IS_A_CONSTANT.

      private static final int SWATCH_X = 150;

You may declare Location constants as well by initializing the constant variable with the results of a constructor:

      private static final Location SOME_LOCN = new Location(100,200);

However, you cannot initialize constants whose definition uses canvas (e.g., no FramedRect constants), since Java does not yet know about the canvas when it is initializing the constants.

The widths and heights of wash baskets and the item to be sorted, coordinates of the upper left corner of each of these, etc., are all good candidates for constants.

After writing the code to draw the baskets and item to be sorted, run the program to see if it does what you expect.

Identifying the Correct Basket

Once you have done the layout, you should next figure out how to generate new items. (Generating the random color is discussed below.) Because you will initially be generating the item in one method (begin) and checking to see if the user clicked in the appropriate basket in a different method (the onMouseClick method), you will need to associate some information with an instance variable that will enable onMouseClick to determine which is the correct basket.

An appropriate way to do this is to use an instance variable of type FramedRect that stores the basket in which the user should click. When you generate a new item (either initially in begin or thereafter in onMouseClick), you will associate the instance variable with the rectangle/basket in which an item of the swatch's should be placed. That way, to determine if the user clicks on the correct basket, onMouseClick can simply check to see if the rectangle currently associated with the instance variable contains the point where the mouse was clicked. Then, onMouseClick will either select a new color for the item (if the user was correct) or wait until the user clicks again (if incorrect).

Picking a random color

To pick a random color, use the RandomIntGenerator class as described in the textbook. Since there are three colors to select from, you should create your random number generator to return random numbers in the range of 1 to 3. Then, pick the color based on the number generated (ie., make the laundry be Color.white if the number is 1, Color.black if the number is 2, and Color.red if the number is 3).

Recycling

Because your program only uses one laundry item at a time, you can (and should!) reuse the same rectangle for each new laundry item by simply changing its color rather than creating a new rectangle. In general, it is a good strategy to reuse objects when possible rather than creating new ones because it uses less memory and makes the code more clear.

Once you have completed Part 1, make sure it works correctly and then move on to Part 2.

Laundry Simulator: Part 2

Once you get the basic version working, it's time to jazz it up a bit. Here are the extensions you should make:

  1. Add counters (Text items) at the bottom of the picture showing the number of correct and incorrect placements. This makes it clearer when the student succeeds in placing the item correctly. They should read something like "Correct = nn", "Incorrect = mm". The value in the first Text item will be formed by concatenating the string "Correct = " with an integer instance variable which keeps track of the number of correct answers. The other Text item is similar. (You can also have both counters interspersed in the text of one text string.) If the user presses the mouse button down outside the laundry item, it should not increase the correct or the incorrect counter.
  2. Users should drag the items to the correct laundry basket rather than just clicking on the basket. Recall from the example in class that you will need an instance variable to label the last mouse position before the drag so you can determine how far to drag the item. If the user drops their laundry outside of all baskets, it will count as an incorrect sorting.
  3. Assign the item a randomly generated color by randomly choosing integers redNum, greenNum, and blueNum between 0 and 255 for each of the red, blue, and green components of the color. Colors are created from those components by writing new Color(redNum,greenNum,blueNum)).

    Now define criteria for determining where each color should go. The simplest criterion is based on the sum of the three color components. If the sum of the component numbers is less than 230, then it goes in the darks basket, if it is greater than 675, then it goes in the whites basket. Otherwise it goes in the colors basket.

The details of how to add these features are left mostly to you, but you should not hesitate to ask for help if you get stuck. Note that to drag the item, you should drop the onMouseClick method in favor of using the three methods:

A working solution for part 2 will appear below. Click inside the applet to interact with it.



Optional Extensions

You should always focus first on getting the lab working, writing good comments, and using good style in your programming. But if you have done all that and would like to do more, here is an extra credit opportunity.

As described in the second feature of Part 2 above, if the user drops their laundry outside of all baskets, it will count as an incorrect sorting. For extra credit, you can be nicer to the user. If the user misses all the baskets, let the user try again without increasing either the correct or incorrect counters.

You should also feel free to extend or embellish your programs, but always be sure to have the basic assignment working properly beforehand.

Submitting Your Work

Before the start of your next lab session, submit your Java program for grading. There are three things you need to do to complete the submission: (i) place a copy of your Java program into your csis120/hw folder under hw2, (ii) print a copy of your program and hand it to your lab instructor, and (iii) demonstrate the execution of your program for your instructor.

A Sample Design

To give you an idea about the expectations for the pre-lab design document, here is a design that could have been used for the SunAndMoon example from class (plus it uses some constants that did not exist in the class examples). It would also include a simple drawing showing the initial placement of the objects in the scene, labelled with key coordinates.

public class SunAndMoon extends WindowController {

    private FilledRect field;        // lower 1/3rd of window
    private FilledRect sky;          // top 2/3rds of window
    private FilledOval heavenlyBody; // the sun or the moon

    // constants to use in scene layout
    private static final int HORIZON_Y = 260;
    private static final int ORB_DIAMETER = 80;
    private static final double RISE_OR_SET_SPEED = 1.5

    /* Create the sky, field and orb and set their colors */
    public void begin() {
        // create sky (FilledRect), field (FilledRect),
        //  heavenlyBody (FilledOval)
        // set colors to "daytime colors"
    }

    /* Make it look like night by using black, white and gray */
    public void onMousePress(Location point) {
       // set sky, field, heavenlyBody colors to "nighttime colors"
    }

    /* Make it look like a bright sunny day */
    public void onMouseRelease(Location point) {
       // set sky, field, heavenlyBody colors to "daytime colors"
    }

    /* Move the sun-like circle down a little bit */
    public void onMouseMove(Location point) {
       // move heavenlyBody down by one unit
    }

    /* Move the moon-like circle up a bit */
    public void onMouseDrag(Location point) {
       // move heavenlyBody up by one unit
    }
}