RU beehive logo ITEC dept promo banner
ITEC 380
2014fall
ibarland

homelecturesrecipeexamshwsD2Lbreeze (snow day)

hw05
Breakout II: list-processing

Part A, Problems 1,2: due Oct 14 (Tue) 23:59 and (section 01:) hardcopy the following class for those two only.
Part B, the remainder: due Oct.18 (Sat(!))19 (Sun.) 23:59.

Your name and the assignment-number must be in a comment at the start of the file, and your hardcopy must be stapled. All functions/data must include the appropriate steps1 of the-design-recipe—the design recipe: final version. In particular, test cases alone might be worth half the credit for a function. Unless otherwise indicated, two test cases will suffice for most problems, if they are testing different situations.

Unless otherwise indicated, all problems are to be written in Racket.

  1. (5pts) Write the function count-bigs : number, list-of-number → natnum, which takes in a threshold and a list of numbers, and returns how many of them are larger than the threshold.
      (check-expect (count-bigs 7 empty) 0)
      (check-expect (count-bigs 7 (cons 5 empty)) 0)
      (check-expect (count-bigs 7 (cons 7 empty)) 0)
      (check-expect (count-bigs 7 (cons 9 empty)) 1)
      (check-expect (count-bigs 7 (cons 3 (cons 7 empty))) 0)
      (check-expect (count-bigs 7 (cons 9 (cons 7 empty))) 1)
      (check-expect (count-bigs 7 (cons 3 (cons 9 empty))) 1)
      (check-expect (count-bigs 7 (cons 8 (cons 9 empty))) 2)
      (check-expect (count-bigs 7 (cons 3 (cons 7 (cons 8 (cons 2 empty))))) 1)
      
  2. (5pts) Write the racket function map-sqr : list-of-number → list-of-number, which squares each number in a list:
      (check-expect (map-sqr empty)  empty)
      (check-expect (map-sqr (cons 7 empty))  (cons 49 empty))
      (check-expect (map-sqr (cons 9 (cons 7 empty)))  (cons 81 (cons 49 empty)))
      
  3. Copy your hw04 racket file to one that we'll use for hw05. Add a very noticeable dividing-line (say, 80 ;s) between old code and the new.

    You will not need to turn in hardcopy of things before the dividing-line if they were in your hw04 solution or in the posted hw04 solution2. Any changes you make (e.g. updating the world examples to have a list-of-bricks) will be moved below the dividing line. You do not need to include part A (problems 1,2) in your part B hardcopy.

    Right now, you can go ahead and move all the world definitions, examples, and functions below the dividing-line, since we'll be updating world to include a list-of-bricks. 3

  4. (5pts) List-of-bricks:
    1. Give the data-definition for list-of-brick, along with any necessary define-structs. (Be sure to indicate the type of each field of the struct, as in lecture.)(Note: no define-structs are necessary, for list-of-X)
    2. Give at least 4 example values of this type. Your last example should contain at least six bricks; you may use this as the bricks in your game's initial world.
    3. Write the template for any brick-processing function.
  5. (5pts) Write draw-bricks : list-of-brick, image → image, similar to the draw-* functions from hw04—Breakout I; grammars. (One test case will suffice; write it before you write the code, to make your life easier.)
    hint: When creating the expected-output for you test case, feel free to call draw-brick. This will help remind you how we drew multiple items onto a single image, back in hw04 #4c and #4e.
  6. (5pts) Modify your world struct so that it includes a field which which is a list of bricks, rather than just a single brick.

    You'll need to make updates to your examples of world-structs, along with draw-world, world-handle-key, and update-world. (This last function will get a major re-write, below.) Verify that all updated test cases still pass, of course.

  7. (5pts) Write brick-collide-ball?, which determines whether a brick overlaps with a ball. It's okay to approximate overlap by only looking at the ball's “bounding box”, and calling overlap?. Have two test cases (this is reasonable, given that you already have overlap? fully tested).
  8. (5pts) Write bricks-remaining : list-of-brick, ball → list-of-brick which returns all bricks in the given list which are not colliding with the given ball.

Bouncing

Getting fully-realistic bouncing off the sides would be rather involved; we'll settle for an approximate version To get full credit, you only need:

    1. (5pts) Write reflect-ball-horizontvertically : rectangle, ball → ball detecting just if the ball overlaps the given rectanglular-zone, and if so returns the ball with its y-velocity flipped (multiplied by -1).

      You may represent a rectangle however you like; myself I just passed in four numbers, the same ones eventually given to overlap?.

    2. (2pts) Write reflect-ball-off-brick : brick, ball → ball, which is a thin wrapper over reflect-ball-horizontally.
    3. (2pts) Write reflect-ball-off-paddle : brickpaddle, ball → ball, which is a thin wrapper over reflect-ball-horizontally.
      Possible tweak:

      Some breakout implementation give the ball an “imperfect” reflection off the paddle — perhaps due to some “spin” imparted by a paddle moving while it hits the ball4. Adding such a small, random tweak to the direction has the gameplay advantage that it can get the ball out of any “rut” where it is bouncing around in a perfect diamond, if the world's dimensions happen to allow that.

      No extra-credit awarded for doing this, beyond the satisfaction of superior gameplay.

  1. (5pts) Write reflect-ball-off-bricks : list-of-brick, ball → ball, which returns a ball that has been reflected for every brick it overlaps.
  2. (5pts) Write a function update-ball which moves a ball, accounting for bouncing off with any of the bricks in the world, and the paddle, and the ceiling, as well as the right- and left- sides. We'll say that a bounce just consists of moving the ball (perhaps into a brick/wall/paddle), and then reflecting its direction appropriately. Be sure to make sufficient tests first (but you can have faith in the details of your helper-functions working).
  3. (2pts) Modify your update-world to include udpate-ball, and your draw-world to include drawing all the bricks. (No further test cases required, beyond what you had for those functions, though myself, I chose to include one more test case for each of these functions, to verify that the helpers really were called.)

    At this point you should be able to call big-bang and have a totally-playable game.

    If you wish, you may provide a stop condition to big-bang (the ball going off the bottom of the screen). We'll see soon how to do this with an anonymous function, rather than needing to write a new function.

  4. Extra credit: I'll award a small amount of extra-credit for improved bouncing, but you must first get the approximate version above working.
    To improve the physics (though it still won't be perfect5), I recommend: detect hitting the right- or left-edge of a paddle by checking if the ball overlap?s just a brick's right-edge — that is, a 1-pixel-wide rectangle that cover's the brick's right edge. Then, check separately for overlapping the bricks' left edge. If the ball overlaps either of these to sliver-thick rectangles, then we would reflect the ball horizontally.

All the above should have their tests, as well as signatures and (brief) purpose statements. Only after all tests pass, you can check that the following works:

(require 2htdp/universe)

(big-bang some-initial-world
          [on-key  world-handle-key]
          [on-tick update-world]
          [to-draw draw-world])


1 Your final program doesn't need to include any "transitional" results from the template: For example, you don't need the stubbed-out version of a function from step 5. However, you should still have passed through this phase.      

2 Your hw05 may use any/all of the hw04-soln.rkt; of course, cite any code you use like this (including a URL), just as would do for any purpose, hw or not.      

3 Alternately, you can leave world untouched, but make a new structure named “world2”. Presumably you'd copy and slightly-modify the world examples and functions.      

4 Maybe a ball should have, in addition to its location and speed, a spin which affects how it gets reflected!      

5

And even truer bouncing would require detecting whether just the circle overlaps a rectangle, and and even what the first, exact point of contact would be.

For a more full-fledged physics simulator, you'd take a ball and any polygon (allowing diagonal sides), and determine the point-of-impact, and the direction it bounces. And for even more accuracy, you would need to account for multiple bounces against several bricks/surfaces, which involves first looking for overlap with the nearest brick, determining that bounce (if any), and then repeat for each brick in order of nearness. If there is a bounce off one object, you need to account for that bounce and how much travel-time was “used up”, and then look for later bounces that only use the remaining travel-time.

So to truly do bouncing correctly, we'd really like three inputs: where the ball is, where it “wants” to move to, and the rectangle we might bounce off of.

     

homelecturesrecipeexamshwsD2Lbreeze (snow day)


©2014, Ian Barland, Radford University
Last modified 2014.Nov.29 (Sat)
Please mail any suggestions
(incl. typos, broken links)
to ibarlandradford.edu
Rendered by Racket.