Last updated: Tue, 14 Apr 2015 14:47:36 -0400
DUE: Monday 4/20/2015, 9pm EST
Use the full Racket language to complete this assignment. Enable it by adding #lang racket (case-sensitive) at the top of the file. In addition, the Choose Language... menu located at the bottom-left of the DrRacket window must be set to Determine language from source.
Put all your solution files in a directory named set13 in your repository.
Download extras.rkt to this directory (right-click and choose "Save As"; don’t copy and paste) and commit it as well.
Use begin-for-test and rackunit to define your examples and tests.
- Don’t forget to tell us how many hours you spent working on the assignment. This should be a global variable called TIME-ON-TASK in each file. For example:
(define TIME-ON-TASK 10.5) ; hours
- So each solution file must have at least the following at the top:
(require "extras.rkt") (require rackunit) (define TIME-ON-TASK <number-of-hours-you-spent>)
- After you’ve submitted your solution, use a web browser to go to https://github.ccs.neu.edu/ and check that your repository contains the following files:
Git Commit Requirement: For this assignment, you must have at least three well-labeled git commits (including the final commit). A well-labeled git commit accurately and succinctly describes the changes since the previous commit. Something like "commit2", or "home work 3" is not an acceptable git commit label. Failure to meet this requirement will result in loss of points.
Use the posn struct from the lang/posn library.
You may use set! in this problem set to mutate object fields.
Make sure to follow the Effectful Methods style guide if you write any effectful methods.
Alternate Designs: At the end of your solution file, describe a possible alternate design for two parts of your program. Justify the decisions you made. For example, you might say "I could have used the publish-subscribe pattern in class X, but I didn’t because ...". Vague justifications without supporting evidence such as "it made the code simpler" will not be accepted.
(check-location "13" "defense.rkt")
AllyUnit: These are your reinforcements arriving to help. Represent them as a solid green square with a side of 20 pixels.
EnemyUnit: These are enemies attacking the base. Represent them as solid red circle with a radius of 12 pixels.
- MercenaryUnit: These units switch sides from enemy to ally every 3 ticks.
When the game begins they behave and look like an AllyUnit.
On the third tick, they turn into an EnemyUnit.
- This cycle repeats for the remainder of the game. Specifically, imagine there exists a tick-merc function, an INITIAL-MERC constant, and ally? and enemy? predicates. Then the following tests should pass. NOTE: This code is meant only to demonstrate the timing of the transitions. It may or may not be a good idea to write these actual functions.
If at the time of entering the base if this unit is an enemy then you will lose points.
If at the time of entering the base if this is an ally then you will gain points.
EnemyUnit eliminated: ( +40 )
EnemyUnit reaches Base: ( -40 )
AllyUnit eliminated: ( -20 )
AllyUnit reaches Base: ( +20 )
- MercenaryUnit eliminated:
when it is impersonating an EnemyUnit: ( +60 )
when it is impersonating an AllyUnit: ( -60 )
- MercenaryUnit reaches Base:
when it is impersonating an EnemyUnit: ( -60 )
when it is impersonating an AllyUnit: ( +60 )
The World is displayed as a canvas of width = 400 and height = 500 pixels.
The Base is a yellow solid rectangle of width = 400 and initial height = 50 pixels and situated at the bottom of the canvas.
The score should be displayed in the middle of the base and should fit within the bounds of the base.
The height of the base also represents your progress in the battle and should grow or shrink as the score increases or decreases such that height of base = 50 + score/5 pixels.
- The game ends when either
height of base <= 10 pixels, i.e., score <= -200
height of base >= 500 pixels, i.e., score >= 2250
The aiming point is represented as two concentric circles and a "plus sign" crosshair. The inner and outer radii should be 5 and 10 pixels, respectively. The crosshair should be a vertical "plus sign" of height and width equal to the diameter of the outer circle.
As soon as an unit reaches the base it should be removed from the game state. A unit "reaches" the base when either their edges touch or any part of the unit overlaps with the base.
The game starts with some number of units at the top of the canvas. A new random unit should enter from the top of the canvas every 4 ticks. Entering units should have a random velocity between a specified min and max velocity, a center x coordinate within the canvas bounds, and a center y coordinate of 0.
; Represents a unit in the game. (define Unit<%> (interface () ; get-loc : -> posn ; Returns the location of this unit as a posn. get-loc ; get-color : -> Color ; Returns the color of this unit. get-color)) ; Represents a mutable world object. (define StatefulWorld<%> (interface () ; on-tick! : -> Void ; EFFECT: mutates this world to its next state. on-tick! ; on-mouse! : Coordinate Coordinate MouseEvent -> Void ; EFFECT: mutates this world to its next state from the given mouse parameters. on-mouse! ; target-loc : -> posn ; Returns the center of the target as a posn. target-loc ; get-units : -> ListOf<Unit<%>> ; Returns the current units in this world. get-units ; add-unit! : Unit<%> -> Void ; EFFECT: adds the given unit to the world add-unit! ; get-base-height : -> Natural ; Returns the height of the base, in pixels. get-base-height)) ; A Velocity is a Natural, representing Pixels/tick in the downward direction. ; mk-world : Velocity Velocity Natural -> StatefulWorld<%> ; Creates a world with num-units initial random units, ; where units have the specified min and max velocity. ; WHERE: minvel <= maxvel (define (mk-world maxvel minvel num-units) ...) ; mk-enemy : posn Velocity -> Unit<%> ; Creates an enemy unit with the given parameters. ; mk-ally : posn Velocity -> Unit<%> ; Creates an ally unit with the given parameters. ; mk-merc : posn Velocity -> Unit<%> ; Creates a mercenary unit with the given parameters.