CS 5010: Problem Set 04

Out: Monday, 6 February 2017
Due: Monday, 13 February 2017 at 6pm
Corrected: Wednesday, 8 February, to correct the return type for make-skillet

This is an individual assignment. You are not allowed to discuss this problem set with any other person. You are also not allowed to search for or to view any solutions to similar problems that may be available on the World-Wide Web or in other resources that might otherwise have been available to you.

The main purpose of this problem set is to give you some practice programming with lists. It will also give you a little more practice with data design and the Iterative Design Recipe.

You must use the HtDP Intermediate Student Language for this problem set.

For these problems, download a copy of extras.rkt and put it in the folder with your solutions. Then import this library by including the line

      (require "extras.rkt")
    

at the top of your file with the other require declarations. Then, for each problem, put in lines that say

      (provide function)
    

for each deliverable function, as you have done on previous problem sets. This will allow our testing framework to import your file and do automated testing on it. You can use check-location to double-check that your solutions are in the right place.

Remember that you must follow the design recipe, which is a process, not a list of deliverables. Your deliverables include the artifacts produced by the various steps of the design recipe: data definitions (including interpretation and templates, contracts, purpose statements, definitions, and tests). Be sure to follow our coding conventions. Doing so will make codewalks easier for everyone.

Be sure to fill out a work session report at the end of each work session. Tell git to add it to the files you will commit, and then commit and push (sync) that report in addition to committing and pushing your entire set04 directory. Do this at the end of every work session.

Remember to include a copy of extras.rkt racket in your set04 directory along with your q1.rkt and q2.rkt files.


  1. You will build upon the simple animation of Problem Set 03 by preserving all of its features and by adding these new features that allow doodads to be created and destroyed dynamically:
    • Pressing the "t" key will create a gold star-like doodad with its center at position (125,120) and add that doodad to the world. The star-like doodad created by the first press of the "t" key will have velocity components vx = −12 and vy = 10. The star-like doodad created by the second press of the "t" key will have velocity components vx = −10 and vy = −12. The star-like doodad created by the third press of the "t" key will have velocity components vx = 12 and vy = −10. The star-like doodad created by the fourth press of the "t" key will have velocity components vx = 10 and vy = 12. And so on: Each newly created star-like doodad has an initial velocity vector that's rotated 90 degrees clockwise from the initial velocity of the previously created star-like doodad.
    • Pressing the "q" key will create a gray square doodad with its center at position (460,350) and add that doodad to the world. The square doodad created by the first press of the "q" key will have velocity components vx = 9 and vy = −13. The square doodad created by the second press of the "q" key will have velocity components vx = 13 and vy = 9. And so on: Each newly created square doodad has an initial velocity vector that's rotated 90 degrees clockwise from the initial velocity of the previously created square doodad.
    • Doodads that are created by key events behave the same as the two doodads that are present in the initial world. In particular, they go through the same sequence of colors in response to Core Bounces, and can be selected and dragged jerklessly.
    • The age of a doodad is the number of ticks that have elapsed since the doodad was added to the world. The age of a newly created doodad is zero, and the age of the two doodads that are present in the initial world is also zero until the first tick. Doodads grow older even if the world is paused.
    • Pressing the "." key will remove the oldest star-like doodad and the oldest square doodad from the world. If there are several oldest star-like doodads, all of those oldest star-like doodads will be removed. If there are several oldest square doodads, all of those oldest square doodads will be removed. If there are no star-like doodads at all, then no star-like doodads will be removed. If there are no square doodads at all, then no square doodads will be removed.
    • The "t", "q", and "." key events behave as specified above even if the world is paused.

    You are to deliver a file named q1.rkt that defines appropriate data types Doodad and World. That file must provide all of the following functions. Note that the list of the functions to be provided is the same as for question 2 of Problem Set 03 except the world-doodad-star and world-doodad-square functions have been replaced by the world-doodads-star and world-doodads-square functions, the doodad-after-mouse-event function has been dropped, and the doodad-age function has been added.

              ;;; animation : PosReal -> World
              ;;; GIVEN: the speed of the animation, in seconds per tick
              ;;;     (so larger numbers run slower)
              ;;; EFFECT: runs the animation, starting with the initial world as
              ;;;     specified in the problem set
              ;;; RETURNS: the final state of the world
              ;;; EXAMPLES:
              ;;;     (animation 1) runs the animation at normal speed
              ;;;     (animation 1/4) runs at a faster than normal speed
              
              ;;; initial-world : Any -> World
              ;;; GIVEN: any value (ignored)
              ;;; RETURNS: the initial world specified for the animation
              ;;; EXAMPLE: (initial-world -174)
              
              ;;; world-after-tick : World -> World
              ;;; GIVEN: any World that's possible for the animation
              ;;; RETURNS: the World that should follow the given World
              ;;;     after a tick
              
              ;;; world-after-key-event : World KeyEvent -> World
              ;;; GIVEN: a World and a KeyEvent
              ;;; RETURNS: the World that should follow the given World
              ;;;     after the given KeyEvent
              
              ;;; world-after-mouse-event
              ;;;     : World Integer Integer MouseEvent -> World
              ;;; GIVEN: A world, the x- and y-coordinates of a mouse event, and the
              ;;;     mouse event
              ;;; RETURNS: the world that should follow the given world after the
              ;;;     given mouse event
              
              ;;; world-paused? : World -> Boolean
              ;;; GIVEN: a World
              ;;; RETURNS: true iff the World is paused
              
              ;;; world-doodads-star : World -> ListOfDoodad
              ;;; GIVEN: a world
              ;;; RETURNS: a list of the star-like doodads of the world
              
              ;;; world-doodads-square : World -> ListOfDoodad
              ;;; GIVEN: a world
              ;;; RETURNS: a list of the square doodads of the world
              
              ;;; doodad-x : Doodad -> Integer
              ;;; doodad-y : Doodad -> Integer
              ;;; GIVEN: a Doodad
              ;;; RETURNS: the x or y coordinate of the Doodad
              
              ;;; doodad-vx : Doodad -> Integer
              ;;; doodad-vy : Doodad -> Integer
              ;;; GIVEN: a Doodad
              ;;; RETURNS: the vx or vy velocity component of the Doodad
              
              ;;; doodad-color : Doodad -> Color
              ;;; GIVEN: a Doodad
              ;;; RETURNS: the color of the Doodad, in one of the forms recognized
              ;;;     as a color by DrRacket's image-color? predicate
              
              ;;; doodad-selected? : Doodad -> Boolean
              ;;; RETURNS: true iff the given doodad is selected
              
              ;;; doodad-age : Doodad -> Integer
              ;;; RETURNS: the age of the given doodad
            

    Remember that we will be doing automated testing of your solution, so be sure your solution is in the right place (set04/q1.rkt in your private cs5010sp16/pdp-YOURUSERNAME repository), and that it provides all the functions listed above. To see if your file is in the right place, insert the following line somewhere near the top of your file:

              (check-location "04" "q1.rkt")
            
  2. For this second part of Problem Set 04, you will continue to use graphics coordinates but will not be drawing any pictures or animations. Since the coordinates do not correspond to pixels, they can be arbitrary real numbers.

    You will design an idealized Flapjack data type whose values represent perfectly circular pancakes, and an idealized Skillet data type whose values represent perfectly circular frying pans.

    You are to deliver a file named q2.rkt that defines the data types Flapjack and Skillet. That file must provide all of the following functions:

              ;;; make-flapjack : Real Real PosReal -> Flapjack
              ;;; GIVEN: x and y coordinates and a radius r
              ;;; RETURNS: a flapjack whose center is at the given x and y
              ;;;     coordinates, with the given radius
              
              ;;; flapjack-x      : Flapjack -> Real
              ;;; flapjack-y      : Flapjack -> Real
              ;;; flapjack-radius : Flapjack -> PosReal
              ;;; GIVEN: a flapjack
              ;;; RETURNS: its x or y coordinate or radius
              
              ;;; make-skillet : Real Real PosReal -> Skillet
              ;;; GIVEN: x and y coordinates and a radius r
              ;;; RETURNS: a skillet whose center is at the given x and y
              ;;;     coordinates, with the given radius
              
              ;;; skillet-x      : Skillet -> Real
              ;;; skillet-y      : Skillet -> Real
              ;;; skillet-radius : Skillet -> PosReal
              ;;; GIVEN: a skillet
              ;;; RETURNS: its x or y coordinate or radius
              
              ;;; overlapping-flapjacks : ListOfFlapjack -> ListOfListOfFlapjack
              ;;; GIVEN: a list of flapjacks
              ;;; RETURNS: a list of the same length whose i-th element
              ;;;     is a list of the flapjacks in the given list that
              ;;;     overlap with the i-th flapjack in the given list
              ;;; EXAMPLES:
              ;;;   (overlapping-flapjacks empty)  =>  empty
              ;;;   (overlapping-flapjacks
              ;;;    (list (make-flapjack -10  2 5)
              ;;;          (make-flapjack  -3  0 4)
              ;;;          (make-flapjack   4 -2 4.6)
              ;;;          (make-flapjack 7.2  6 5)
              ;;;          (make-flapjack  20  4 4.2)))
              ;;;   =>
              ;;;   (list (list (make-flapjack -10  2 5)
              ;;;               (make-flapjack  -3  0 4))
              ;;;         (list (make-flapjack -10  2 5)
              ;;;               (make-flapjack  -3  0 4)
              ;;;               (make-flapjack   4 -2 4.6))
              ;;;         (list (make-flapjack  -3  0 4)
              ;;;               (make-flapjack   4 -2 4.6)
              ;;;               (make-flapjack 7.2  6 5))
              ;;;         (list (make-flapjack   4 -2 4.6)
              ;;;               (make-flapjack 7.2  6 5))
              ;;;         (list (make-flapjack  20  4 4.2)))
              
              ;;; non-overlapping-flapjacks : ListOfFlapjack -> ListOfFlapjack
              ;;; GIVEN: a list of flapjacks
              ;;; RETURNS: a list of the flapjacks in the given list that
              ;;;     do not overlap with any other flapjacks in the list
              ;;; EXAMPLES:
              ;;;   (non-overlapping-flapjacks empty)  =>  empty
              ;;;   (non-overlapping-flapjacks
              ;;;    (list (make-flapjack -10  2 5)
              ;;;          (make-flapjack  -3  0 4)
              ;;;          (make-flapjack   4 -2 4.6)
              ;;;          (make-flapjack 7.2  6 5)
              ;;;          (make-flapjack  20  4 4.2)))
              ;;;   =>
              ;;;   (list (make-flapjack  20  4 4.2))
              
              ;;; flapjacks-in-skillet : ListOfFlapjack Skillet -> ListOfFlapjack
              ;;; GIVEN: a list of flapjacks and a skillet
              ;;; RETURNS: a list of the given flapjacks that fit entirely
              ;;;     within the skillet
              ;;; EXAMPLE:
              ;;;   (flapjacks-in-skillet
              ;;;    (list (make-flapjack -10  2 5)
              ;;;          (make-flapjack  -3  0 4)
              ;;;          (make-flapjack   4 -2 4.6)
              ;;;          (make-flapjack 7.2  6 5)
              ;;;          (make-flapjack  20  4 4.2))
              ;;;    (make-skillet 2 3 12))
              ;;; =>
              ;;;   (list (make-flapjack  -3  0 4)
              ;;;         (make-flapjack   4 -2 4.6)
              ;;;         (make-flapjack 7.2  6 5))
            

    Remember that we will be doing automated testing of your solution, so be sure your solution is in the right place (set04/q2.rkt in your private cs5010sp16/pdp-YOURUSERNAME repository), and that it provides all the functions listed above. To see if your file is in the right place, insert the following line somewhere near the top of your file:

              (check-location "04" "q1.rkt")
            

For debugging: Click here to validate.