Due Date: Tuesday May 26th, 10pm EDT
Purpose Design and creation of a larger program; To practice abstracting similarities in functions.
You must submit a single .rkt file containing your responses to all exercises via the Handin Server. We accept no email submissions.
You must use the programming language specified at the top of this page.
Your code must conform to the guidelines outlined in the style guide on the course website. The style guide will be updated as the semester progresses, so revisit it before submitting each assignment.
Unless otherwise stated, for all programming problems you must provide (i) a signature, (ii) a purpose statement, (iii) sufficiently many check-expects (not for big-bang programs), and (iv) the actual code, in the language specified at the top of this page.
Be sure to look at the feedback for previous assignments before submitting, as we will be grading you more strictly on things we have pointed out before.
Failure to comply with these expectations will result in deductions and possibly a 0 score.
Exercise 1 Develop the Frogger game.
Here is a link to a free version of Frogger for those unfamiliar with the game: Frogger.
In your game, the player is a frog who tries to move from the bottom of the screen to the top of the screen. The screen is divided into rows. The player starts in the bottom row, crosses five rows of traffic, and wins if they reach the top row.
In the traffic rows, the player must not collide with any of the vehicles present in these rows. The traffic alternates direction and includes 4 vehicles per road. If the player gets hit by a vehicle, the player loses and the game ends. When a vehicle passes off the edge of the screen, a new entity of the same type is created on the opposite edge, so that there are always the same number of vehicles, and they are all evenly spaced.
The player can move their character using the arrow keys in four ways: up, down, left and right. Develop your own data definitions and structures for frogs, and vehicles (and any auxiliary ones you might need, like worlds).
The following data definitions may or may not be useful (and indicative of the kind of operations you might want to develop) for writing this program:
; Data Definitions ; A Direction is one of: "left" | "right" ; A Player is a (make-player Number Number) (define-struct player (x y)) ; A Vehicle is a (make-vehicle Number Number Direction) (define-struct vehicle (x y dir)) ; A Set of Vehicles (VSet) is one of: ; - empty ; - (cons Vehicle VSet) ; A World is a (make-world Player VSet) ; The VSet represents the set of vehicles moving across the screen (define-struct world (player vehicles))Some advice:
You can represent players and vehicles images using image functions such as circle, triangle, square, overlay, etc.
You may implement other features, if you like (e.g., fancier scoring, multiple lives, vehicles of varying lengths, and/or a river). However, extra features won’t save you from points taken off if your code has bugs or isn’t well designed. You will not receive 100% credit simply for having code that works. For full credit, your code must work and be well written. So you should put your effort into writing clean, readable, bug-free code.
You will be upgrading the game to full Frogger in a future assignment. So effort expended in making sure that your code is clean and well-designed will be rewarded when you have to extend it later – it is quite difficult to modify and extend code that is a snarled-up, confused pile of chaos.
As always, you should use the Design Recipe help get your code written.
As always, start early. It will take you time to work out the assignment.
Exercise 2 For this exercise, you may assume the definition for Position and [List-of Position] that you have seen in lecture, and do not need to define them or their templates. You can if you want to, though.Consider the following functions:
; sum-x-coords : [List-of Position] -> Number ; Sum all the x-coordinates in the list of positions (check-expect (sum-x-coords empty) 0) (check-expect (sum-x-coords (cons (make-posn 3 4) (cons (make-posn 5 12) empty))) 8) (define (sum-x-coords lop) (cond [(empty? lop) 0] [(cons? lop) (+ (posn-x (first lop)) (sum-x-coords (rest lop)))])) ; mult-distances : [List-of Position] -> Number ; Multiply all the distances from each position to the origin (check-expect (mult-distances empty) 1) (check-expect (mult-distances (cons (make-posn 3 4) (cons (make-posn 5 12) empty))) 65) (define (mult-distances lop) (cond [(empty? lop) 1] [(cons? lop) (* (distance-to-origin (first lop)) (mult-distances (rest lop)))])) ; distance-to-origin : Position -> Number ; Produces the distance from this position to the origin (check-within (distance-to-origin (make-posn 2 2)) (sqrt 8) 1e-06) (check-expect (distance-to-origin (make-posn 3 4)) 5) (define (distance-to-origin p) (sqrt (+ (sqr (posn-x p)) (sqr (posn-y p)))))
Abstract sum-x-coords and mult-distances. Be sure to re-define the functions using your new abstraction.
Use your new function to design the function biggest-difference, which produces the largest difference between a Position’s x and y values in a list of positions. Note that the difference should always be taken as an absolute value, whether the x or y value is bigger.
Exercise 3 Design the function earliest, which takes a non-empty list of strings and a function (that takes two strings and outputs a Boolean), which indicates whether or not the first string comes "before" the second one. The earliest function should output the string that comes earliest in the non-empty list according to the given function.Then, use earliest to define three other functions:
One that produces the string that comes earliest lexographically (i.e., which would come first in a dictionary). Hint: string<? is quite useful.
One that produces the string that comes last lexographically.
One that produces the last string in the non empty list.