ICS H21 • UC IRVINE • DAVID G. KAY • FALL 2008

Lab Assignment 1
 

This assignment is due at the end of lab on Friday, October 3.

Choose a partner for this assignment, someone you haven't worked with already, and make sure the TA knows who your partner is.

(a) With your partner, do these exercises from HtDP: 2.1.1; 2.2.1 and 2.2.3 (these may require knowledge about a particular "problem domain;" of course the web is the most convenient source for that information); 2.2.5; 2.3.1, and 2.3.3.

You should be able to place all the definitions and tests into one definitions file. Include your name and your partner's, save the file, and submit it via Checkmate.

(b) With your partner, do exercises 2.4.1 through 2.4.4. There's nothing to turn in for this part, but it's still important that you have the experience of looking at error messages.

(c) For this part, you will use a teachpack called fabric-teachpack.scm. (Copy or download it; save it in a file on your machine; in DrScheme's Language menu, choose Add Teachpack and click Add Teachpack to List; find and select the file you saved; click OK; then click Run.)

This teachpack comes with documentation; skim it to get an idea of what it provides and refer back to it as necessary. (The conventional terms for a teachpack—extra functions for a particular task that aren't part of the programming language to begin with—are library or API (application programming interface) or SDK (software developer's kit).)

(c.1) Familiarize yourself with the images and functions in the teachpack. Enter the names of the images one at a time in the interactions window. Try the functions that create fabric images (create-solid-fabric, add-print, add-horiz-stripe, and add-vertical-stripe) to see what each one does.

(c.2) Write an expression to create blue fabric with red stripes in one direction and purple stripes in the other (you pick the size).

(Here are some more detailed steps, if you'd like them: First, write an expression to create a blue fabric of some size. Click Run to test it. Then create a blue fabric with red stripes, let's say horizontally; do this by calling add-horiz-stripe with your blue-fabric expression as its third argument. That is, copy your blue-fabric expression as the third argument at the end of your add-horiz-stripe expression. This last part is key: We can use the result of one expression as an argument to another expression, as we saw with (+ 1 (* 3 5)), and that's how we create more complex, interesting results. Click Run to see this red-stripe fabric. Finally, to add the purple stripes, let's say vertically, call add-vertical-stripe with your whole red-stripe-fabric expression as its third argument. "Nesting" the calls to functions in this way will be basic to everything we do this term. You'll find that if you hit the Return key before each new function call, DrScheme will indent your program to make it more readable.) Keep this expression in the definitions (top) window and add the subsequent expressions to the same window; you can save them to turn in.

(c.3) Write an expression to create a small green stripe fabric with a chili print on it (you pick the size).

(c.4) Invent two fabrics of your own using the teachpack functions. You can create your own print images by importing them using Insert Image from the Special menu or by using the circle and rectangle operators from the image teachpack (which is included in this teachpack); you can see the image teachpack documentation in DrScheme's Help Desk. Each fabric should involve at least two calls to functions that create fabrics. Be creative!

(c.5) If you overlay a fabric on top of a clothing image (like tshirt or hat), you can see what the fabric might look like on the clothing. The overlay function from the image teachpack does this. The fabric and the clothing image should be the same size; you can find out the size of an image using the image-width and image-height functions, also described in the image teachpack documentation. Write a function create-from-fabric that consumes an image for a white clothing item (like the tshirt or hat) and a fabric image sized to fit that item, and produces an image of the clothing item in the given fabric.

(c.6) Write a function add-center-logo that consumes an image for a logo and an image for a clothing item and produces an image of the clothing item with the logo centered on it. The given clothing item may already be printed in fabric.

(c.7) Write a function stack-logos that consumes images of two logos and returns an image with the first logo just above the second logo. You do not need to center the logos, but you may if you wish. (Hint: Check the image teachpack documentation for overlay/xy and image-height.)

(c.8) Write a function side-by-side-logos that consumes images of two logos and returns an image with the first logo to the left of the second logo. You do not need to center the logos, but you may if you wish.

(c.9) Define three pieces of clothing using a combination of the teachpack functions and your definitions. You should use each of the functions you defined at least once. Again, be creative!

(d) The world.ss teachpack provides some functions that let you animate images. Clear the fabric teachpack, then add the world.ss teachpack and click Run.

When we use this teachpack, we create a world that might change at every tick of the clock. We can (re)display the (changed) world at every tick; that gives us the animation. To set this up, the world.ss teachpack provides us the functions big-bang (to start the animation off), on-redraw (to say what function to call to redraw the world each time), and on-tick-event (to say what function to call every time the clock ticks). We might call them with these lines:

(big-bang 200 200 0.1 (make-world 1 1)) ; Start the whole thing going 
(on-redraw world-draw)     ; Tell it how to draw the world at each step 
(on-tick-event world-tick) ; Tell it to call world-tick at each tick of the clock

Now we just have to define the world structure so make-world works, define the function world-draw, and define the function world-tick.

Let's imagine a very simple world, one that has a falling rock and a flying bird. To make it even simpler, the rock will be a 10-pixel brown circle and the bird will be a 10-pixel yellow square. Not only that, but the rock will fall straight down, 5 pixels at every clock tick, and the bird flies straight from left to right at the same rate.

In terms of our animation, what needs to change in this world? Really, just two things: the horizontal position of the bird and the vertical position of the rock. The scene, the bird's image and its height, and the rock's image and its horizontal position, all stay constant. We need to draw them, but when we define a world to use with this teachpack, we only need the world to represent the aspects that might change from time to time. In this case, that's just two numbers: the x-coordinate (horizontal position) of the bird and the y-coordinate (vertical position) of the rock. So let's define a structure to represent our world:

(define-struct world (birds-x rocks-y))
  ;; A world is (make-world Number Number)
  ;; where the first number is the x-coordinate of the bird
  ;; and the second number is the y-coordinate of the rock.

Remember that as with any structure, you will use make-world to create a world, world-birds-x to get the bird's position from a world, and world-rocks-y to get the rock's position.

(There's one other little detail to note. In computer graphics—not just in Scheme—the convention for x-y coordinates is that the origin is in the upper left corner, the x axis extends positively to the right, and the y axis extends positively downwards. So (5,20) would be five pixels from the left side, 20 pixels down from the top.)

(d.1) Develop the function world-draw that takes a world as input and returns a scene created using empty-scene and place-image (as described in the world.ss documentation). You should create an empty scene of 200 by 200 pixels; into that scene you should place the image of the bird (at a constant height of 120 pixels above the ground) and place the image of the rock (at a constant 80 pixels from the left edge). Test this out by calling it with (world-draw (make-world 1 1)).

(d.2) Develop the function world-next that takes a world and returns a new world that represents how the input world should be at the next clock tick. Hints: What is the world? How does it change at each tick? How do you create a (new) world?

(d.3) With the structure definition and your two definitions above, you just need to add these few lines to run your animation:

;; world-tick: world -> world
;; Action to perform at each clock tick
(define world-tick
  (lambda (w)
    (cond
      ((>= (world-rocks-y w) 190) (end-of-time "Done!"))  ; quit when rock nears bottom
      (else (world-next w))))))   ; otherwise, return world at next tick

(big-bang 200 200 0.1 (make-world 1 1)) ; Start the whole thing going
(on-redraw world-draw)     ; Tell it how to draw the world at each step
(on-tick-event world-tick) ; Tell it to call world-tick at each tick of the clock

(d.4) Make the bird fly twice as fast as the rock falls.

(d.5) There's a strong wind blowing. Make the rock fall at a 45-degree angle to the right. You can do this without changing how the world is defined.

Submit your definitions via Checkmate.

(e) (extra credit) Extra credit problems in ICS H21 follow different rules. The first rule is that you must finish the main part of the assignment before starting on the extra credit. The second rule is that you may work with whomever you like on the extra credit problems—your partner on the main part, one or more other students, or yourself alone; group work must clearly indicate who contributed and how much. The third rule is that extra credit must be turned in on paper to the TA (clearly marked with the contributors' names and including, where appropriate, printouts of the relevant definitions and interactions). The fourth rule is that extra credit is mainly for the fun and the glory; it also gives a little bit of credit, but not so much as to make up for low performance on the required work and exams.

(e.1) Do exercise 2.2.4.

(e.2) What's the longest number you can generate in DrScheme, without running out of memory and taking no more than 60 seconds of elapsed time? Generating the big numbers is one part of the question; counting the digits is another.

Try to count digits using (string-length (number->string your-big-number)). How do you get your-big-number into that expression without copying and pasting it (or typing the entire number)?

Try to count the digits using some tool(s) other than Scheme (or any programming language).

Using your wristwatch (or slow, measured counting), time how long it takes for Scheme to calculate and display your big number. Now, time how long it takes to calculate the big number and then its length (by nesting the expression to generate the big number inside the length-calculating expression above). You'd expect the second, combined task to take longer, but on some Scheme systems it doesn't. Does it on your system? Why might the generate-and-calculate-length task take less time than generating the number without calculating its length?

(f) (extra credit—the same rules apply) Think of some other, clever ways to enhance the bird-and-rock animation (e.g., have the bird fly more creatively) or create another (e.g., draw a simple face whose eye winks). Just keep to the same basic organization: A world to represent what changes, a function to draw the world, and a function to create the next world from the previous one. Show your results to your classmates and the TA.

(g) Remember that each partner must complete a partner evaluation form and submit it individually at eee.uci.edu by Saturday morning at the latest.


Based in part on ICS H21 assignments by David G. Kay from Fall 2001. Modified for image.ss and world.ss teachpacks by Angelo Pioli and David G. Kay, Fall 2005. Modified by David G. Kay in Fall 2007. The rock-and-bird example was adapted from CS 211 at Northeastern University, taught by Matthias Felleisen and John Clements in Fall 2004. The fabric exercise was written by Kathi Fisler at Worcester Polytechnic Institute and modified slightly by David G. Kay.


David G. Kay, kay@uci.edu

Friday, October 7, 2005 -- 6:25 PM