(require 2htdp/image) (require 2htdp/universe) ;;; ======================================================= ;;; CMPU-101, Spring 2013 ;;; Assignment 8 ;;; ======================================================= (display "\n CS101 Assignment 8, Spring 2013") (display "\n Please write your name here\n\n") ; ; Design an interactive program that starts by moving a one-segment ; worm and enables a player to control the movement of the worm with the ; up, down, right, and left arrow keys. Your program should use a red disk ; to render the initial segment of the worm and other segments as they ; are added. On each clock tick, the worm should move DIAMETER distance ; either up, down, right, or left. ; ; Add a food component to the world to allow the worm to grow. At any point ; in time, the grid should contain one randomly placed piece of food. To keep ; things simple, a piece of food is of the same size as a worm segment, but ; is a different color. When the worm’s head segment is located next to the ; food and the worm is moving toward the food, the worm eats the food, meaning ; the worm’s head is extended by one segment. As the piece of food is eaten, ; another piece of food should show up at a different random location. ; ; Adding food to the game requires changes to the data representation ; of the world state from what it was in lecture 19. The worm will consist of ; a list of segments, as you saw in lecture 19, along with a dx and dy to ; represent the change in position of the worm on each clock time. But now, ; instead of representing just the worm, the state of the world should include ; the current location of the food. ; ; You will need a new function for adding food to the grid in a random ; location. Also, the tick handler must not only move the worm -- in addition, ; it should check to see if the worm is eating and call for creation of new ; food. ; ; ; ; ; ; ; ; ; ; ; ;; ; ; ; ; ; ; ;;; ;; ; ;;; ; ; ; ;; ; ; ;;; ; ;; ; ; ; ; ;;; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;; ; ; ; ; ; ; ; ; ; ; ;; ; ; ; ; ;;;; ;;; ; ; ; ; ;;; ;; ;; ;; ;; ; ; A list of posns (lop) is ; 1. empty, or ; 2. (cons posn lop) ; The state of the world is given below: (define-struct worm (segs dx dy food)) ; A wormscene is a (make-worm segs dx dy food), where segs is a list of posns ; representing the x, y position of each segment of the worm on the x,y ; plane, the dx and dy are either DIAMETER, 0, or -DIAMETER, representing ; the direction of worm movement, and the food is a posn OR a list of posns ; that contains at most one posn. Representing the food field as a list of ; posns will allow you to make the list empty when the worm eats the food ; and generate a new food posn to put on the list on the next clock tick ; when the food list is empty. Representing the food as a posn will mean ; you need to generate a new food posn at the same time the worm eats the ; food. The first representation is more like the original game, but the ; second is easier to code. ; Contract of CONSTRUCTOR: ; ; Contracts of ACCESSOR functions: ; ; Contracts of MUTATOR functions: ; ; Contract of TYPE-CHECKER function: ; ; ; ; ; ; ; ; ; ; ; ;; ; ;;; ; ; ;;; ;; ;;; ; ;;; ; ; ;; ; ;;; ; ; ; ; ; ; ; ;; ; ; ; ;; ; ;; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;; ;; ;;; ; ;; ;;;; ; ; ; ; ; ; ; ; ; ; Problem 1: ; ; List the functions created by the define-struct statement written above for ; a worm struct. ; ; ; ; ; ; ;; ;; ; ; ; ; ;;; ;;; ; ;; ;;; ;;;; ;;; ; ;; ;;;; ;;; ; ; ; ; ; ;;; ; ; ; ;; ; ;;; ; ; ; ; ; ; ;; ; ;; ; ; ; ; ; ;; ; ; ; ; ; ; ; ;; ; ;; ; ; ; ;; ; ; ;; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;; ; ; ; ; ;; ; ; ; ; ;;; ; ; ; ; ; ;; ; ; ;;; ;;; ; ;; ;;;; ;; ;; ;; ; ;; ;; ;;;; ; Constants (define RADIUS 10) ;\ (define DIAMETER (* RADIUS 2)) ; worm-related (define SEGMENT (circle RADIUS 'solid 'red)) ;/ ;; NOTE: Since the grid is square, we can replace HEIGHT and ;; WIDTH with SIDE. (define SIDE 800) ;\ (define MT (empty-scene SIDE SIDE)) ; scene-related (define COLOR 'black) ; (define CENTER (make-posn (/ SIDE 2) (/ SIDE 2))) ;/ (define ROWS/COLS (/ SIDE DIAMETER)) ; The food will be drawn as a green circle the same size as SEGMENT (define FOOD (circle RADIUS 'solid 'green)) ; food-related (define RATE 1/4) ; clock-related ;; The initial state of the world is a single-segment worm positioned ;; at the middle of the scene and whose direction is to the right. The initial ;; world should also contain a single food particle (see discussion written ;; above near the define-struct for the worm on the choice of data type for ;; the worm-food field). ;; READ PROBLEM 2 INSTRUCTIONS TO COMPLETE THIS DEFINITION. ;(define INIT-WORM ; ; ; ; ; ; ;;; ; ; ;; ;; ; ;; ; ; ; ; ; ;;; ;; ;;; ; ;;; ; ; ; ;; ; ;;; ; ; ; ; ; ; ; ; ;; ; ; ; ;; ; ;; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;; ; ; ; ; ; ; ; ; ; ; ;; ; ; ;; ;; ;;; ; ;; ;;;;;;; ; ; ; ; ; ; ; ; ; ; Problem 2: ; ; Create an initial worm above, where it says "(define INIT-WORM". ; ; Be sure to include values for each field of the worm, including the ; food for the worm. Remember that there is an initial posn called ; CENTER that can be put into a list to create the initial worm-segs field. ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;; ; ; ;;;;;; ; ;;; ; ; ; ;;; ; ;; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;; ; ; ;;;; ;;; ; ; ;;; ; ;; ;; ;; ;; ; ; ; ; ; ; ; ; ; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Contract: (make-grid-hor-lines-v2) -> list of posn pairs ;; Header: (define make-grid-hor-lines-v1 (lambda () ...)) ;; Purpose: To make horizontal lines at every DIAMETER position in ;; grid (uses build-list for recursion). (define make-grid-hor-lines-v2 (lambda () (build-list (sub1 (/ SIDE DIAMETER)) (lambda (c) (list (make-posn 0 (* (add1 c) DIAMETER)) (make-posn SIDE (* (add1 c) DIAMETER))))))) ;; Contract: (make-grid-vert-lines-v2) -> list of posn pairs ;; Header: (define make-grid-vert-lines-v2 (lambda () ...)) ;; Purpose: To make vertical lines at every DIAMETER position in ;; grid (uses build-list). (define make-grid-ver-lines-v2 (lambda () (build-list (sub1 (/ SIDE DIAMETER)) (lambda (c) (list (make-posn (* (add1 c) DIAMETER) 0) (make-posn (* (add1 c) DIAMETER) SIDE)))))) ;; Contract: (draw-lines list-of-posn-pairs) -> image ;; Header: (define draw-lines (lambda (lopp) ...)) ;; Purpose: To draw lines between endpoints specified by each posn ;; pair in input list (define draw-lines (lambda (lopp) (cond [(empty? lopp) MT] [else (scene+line (draw-lines (rest lopp)) (posn-x (first (first lopp))) (posn-y (first (first lopp))) (posn-x (first (rest (first lopp)))) (posn-y (first (rest (first lopp)))) COLOR)]))) ;; Make the endpoints of all the lines to be in grid (define LOPS (append (make-grid-hor-lines-v2) (make-grid-ver-lines-v2))) ;; The game board: the equivalent of the empty-scene (define GRID (draw-lines LOPS)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; READ PROBLEM 3 INSTRUCTIONS TO COMPLETE THE WORM-MAIN FUNCTION. ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;;; ; ;;;; ; ;;; ;;; ; ;; ;;;; ; ; ; ; ; ; ; ; ; ; ;; ; ;;; ; ; ; ; ;; ; ; ; ; ;; ; ; ; ;; ; ; ; ; ; ; ; ; ; ;;; ; ; ; ; ;; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;;;; ;; ; ; ; ;;; ; ; ; ; ; ;; ; ;; ;; ;;; ; ; ;; ;; ;; ; ;; ;;; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;; ;; ; ; Contract: (worm-main number) -> worm ; Header: (define worm-main (lambda (w) ... )) ; Purpose: starts big-bang using the INIT-WORM constant for the initial ; world. Uncomment clauses as you write their argument functions. ;(define worm-main ; (lambda (w) ; (big-bang ; w ; (on-tick worm-tick RATE) ; (on-key worm-ctrl) ; (to-draw draw-worm) ; (stop-when at-wall? final-scene)))) ; ; ; ; ; ; ; ; ;;;;;; ; ;; ; ; ; ; ; ;;; ;; ;;; ; ;;; ; ; ;; ; ;;; ; ; ; ; ; ;; ; ;; ; ; ; ;; ; ;; ; ; ;; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;; ; ; ; ;; ;; ;;; ; ;; ;;;; ; ; ; ; ; ; ; ; ; ; Problem 3: ; ; Fix the contract, header, and purpose of the worm-main function so ; that it reflects the new worm data type as the state of the world. ; ; Uncomment clauses of the worm-main function as you write the argument ; functions used as inputs. The worm-main function is called at the ; bottom of this code. You need to uncomment the call to worm-main after ; you write the functions for problems 4 through 8. ; ; It is a good idea to write and test each function before uncommenting ; the corresponding line in worm-main. ; ; ; ; ; ; ; ; ; ; ; ; ; ;; ; ;;; ; ;; ;;; ;; ;;; ; ; ; ; ; ; ;;; ; ;; ; ;;; ;; ; ; ; ;; ; ;; ; ;; ; ; ; ; ; ; ; ; ; ; ; ; ; ;; ; ;;; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;; ; ; ; ; ; ; ; ; ;;; ; ; ; ; ;;; ; ; ; ;; ; ;;; ; ;; ;; ;; ;; ;; ;; ; ; ;; READ PROBLEM 4 INSTRUCTIONS FOR THIS FUNCTION. ; Contract: (draw-worm worm) -> image ; Header: (define draw-worm (lambda (w) ... )) ; Purpose: draws the worm in the grid ;(define draw-worm ; (lambda (w) ;(printf "(draw-worm INIT-WORM) ~%") ;(draw-worm INIT-WORM) ; ; ; ; ; ; ; ; ; ; ; ;; ; ; ; ; ;;; ;; ;;; ; ;;; ; ; ; ;; ; ;;; ; ; ; ; ; ; ; ; ;; ; ; ; ;; ; ;; ; ; ; ; ; ; ; ; ; ; ; ; ;;;;;;; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;; ;; ;;; ; ;; ; ; ; ; ; ; ; ; ; ; ; Problem 4: ; ; Modify the draw-worm function above so that it takes in a worm ; and places all the segments of the worm AND the food particle ; on the grid. Placing segments of the worm was shown in lecture ; 19. ; ; When placing the worm-food, you will take different actions ; depending upon whether the worm-food is a posn or a list of ; posns: ; ; 1. If the worm-food is a posn, you can include a place-image ; for the FOOD image on top of the GRID in the base case of ; the inner helper function that does recursion over the list ; (worm-segs w). ; ; 2. If the worm-food is a list-of-posns, you need to check ; if the worm-food list is empty before trying to place the ; FOOD image, placing the worm-food only if the worm-food list ; is not empty. A new posn will be created on the next clock ; tick. ; ;; READ PROBLEM 5 INSTRUCTIONS FOR THIS FUNCTION. ; Contract: (random-within worm) -> posn ; Header: (define random-within (lambda (w) ... )) ; Purpose: Generate a food particle at a random location. ; Function definition: ;(define random-within ; (lambda (w) ; Post-function printf: ;(printf "(random-within INIT-WORM) =>~%") ;(random-within INIT-WORM) ; ; ; ; ; ; ; ; ; ;;;; ; ;; ; ; ; ; ;;; ;; ;;; ; ;;; ;;; ; ;; ; ;;; ; ; ; ; ; ;; ; ;; ; ; ; ;; ; ;; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;; ;; ;;; ; ;; ;;; ; ; ; ; ; ; ; ; Problem 5: RANDOM-WITHIN (above) ; ; Write a function to generate a food particle at a random ; location. The food particle should occupy one of the ; line intersections on the grid. This function should make ; the particle's x and y coordinate between DIAMETER and ; (SIDE - DIAMETER) so that the food particle is not positioned ; off or at the edges of the scene. In other words, the new ; position for the food particle should be on one of the grid ; line crossings. You also need to be careful that the random ; food position is not part of the worm. The presence of the ; generated food particle in the list of posns representing the ; worm can be checked by using the function member? (look member? ; up in the help desk). ; ; When thinking about how to write the random-within function, ; consider that the number of rows and columns can be calculated ; by dividing the SIDE by the DIAMETER. This value is defined ; as the constant ROWS/COLS in the constants section. ; ; Generate a random number between 1 and (ROWS/COLS - 1) for ; the x and y coordinates of the food particle and multiply ; each of the resulting numbers by DIAMETER to produce the ; actual (x, y) position of the food. ; ; The function started for you above is called random-within. ; From the contract, you can see that it consumes a worm and ; generates a posn. You may choose to rename this function ; and change the data type it consumes and produces. ; ; ; ; ; ; ; ; ; ; ;; ; ; ; ; ; ;;; ; ;; ;;;; ; ;;; ; ;; ; ; ; ;;; ; ; ; ; ; ; ;; ; ;; ; ;; ; ; ; ; ; ;; ; ; ; ;; ; ;;; ; ; ; ;; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;;;; ;;; ; ; ; ;;; ; ;; ;; ;; ;;; ; ;; ; ;; READ PROBLEM 6 INSTRUCTIONS FOR THIS SET OF FUNCTIONS. ;;;Contract: (go worm) -> worm ;;;Header: (define go (lambda (w) ...)) ;;;Purpose: Move worm in direction indicated in the dx and dy fields of w. ; ;;;Function definition: ;(define go ; (lambda (w) ; ;; The move-worm function is where we'll create the new head segment. ; ;; This function will consume a worm and return a worm-lop ; (make-worm (move-worm w) (worm-dx w) (worm-dy w)))) ; ; ;; Contract: (move-worm worm) -> lop ;; Header: (define move-worm (lambda (w) .... )) ;; Purpose: Make new posn for head of worm and call remove-last to remove last ;(define move-worm ; (lambda (w) ; ;; make new posn for head of worm by adding the worm-dx onto the posn-x ; ;; of the first worm posn and adding worm-dy onto the posn-y of the ; ;; first worm posn ; (cons (make-posn (+ (worm-dx w) (posn-x (first (worm-lop w)))) ; (+ (worm-dy w) (posn-y (first (worm-lop w))))) ; (remove-last (worm-lop w))))) ; ;; Contract: (remove-last lop) -> lop ;; Header: (define remove-last (lambda (lp) .... )) ;; Purpose: remove last posn on lp. ;(define remove-last ; (lambda (lp) ; (cond ; ;; base case 1: Should never be used because the worm will always have ; ;; at least 1 segment. ; [(empty? lp) empty] ; ;; base case 2: We are at last segment of worm; just don't add it back ; ;; on to list of posns ; [(empty? (rest lp)) empty] ; ;; recursive case: Keep consing posns back onto the list. ; [else (cons (first lp) (remove-last (rest lp)))]))) ; ;; post function printf: ;(printf "(move-worm INIT-WORM) ") ;(move-worm INIT-WORM) ; ;; post function printf: ;(printf "(remove-last INIT-POS-LIST) ") ;(remove-last INIT-POS-LIST) ; ; ; ; ; ; ;;; ; ; ; ;; ; ;; ; ; ; ; ;;; ;; ;;; ; ;;; ; ;; ; ;; ; ;;; ; ; ; ; ; ;;; ; ; ;; ; ; ; ;; ; ;; ; ;; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;; ; ; ; ; ; ; ; ; ; ; ; ; ; ;; ;; ;;; ; ;; ;;; ; ; ; ; ; ; ; ; Problem 6: ; ; Modify the go function, the argument to the on-tick clause, above. ; This function should consume a worm and return a new worm. ; ; The functions we wrote in lecture 19 to move the worm are ; included above (although they are commented out). You should ; modify them so that they include the new field for the food ; particle in the worm state. You are not required to keep the ; same set of functions in your solution (although you can), ; nor do your functions have to consume the same input or produce ; the same output (aside from the go function itself which must ; consume and produce a worm.) ; ; On each clock tick, this set of functions should not only move the ; worm segments, it should also check if the worm is about to eat ; (meaning a food particle exists adjacent to the head of the worm ; and in the direction the worm is moving). If it is true that the ; worm can eat in the next step, you should add a segment to the ; head of the worm in the position of the food particle. ; ; If the worm-food field in your worm is a list of a single posn, ; you should return the new worm with an empty list for this ; field and generate another food particle on the next clock tick ; elsewhere in the grid, using the function you wrote for problem 5. ; ; If the worm-food field in your worm is a single posn, you should ; return the new worm with a new worm-field posn using the function ; you wrote for problem 5. ; ; ; ; ; ; ; ; ; ; ; ; ;;; ; ;; ; ;; ;;; ; ; ; ; ; ;;; ; ; ;; ; ; ; ; ; ;; ; ;; ; ;; ; ;; ; ; ; ; ; ;; ; ;;; ;; ; ; ;; ; ; ; ; ; ; ; ; ; ;; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;;; ; ;;; ; ;; ; ;; ;;; ;; ;; ; ; ; ; ; ; ; ; ; ; ;;; ;; READ PROBLEM 7 INSTRUCTIONS FOR THIS FUNCTION. ; Contract: (worm-ctrl worm string) -> worm ; Header: (define worm-ctrl (lambda (w k) ... )) ; Purpose: changes direction of worm given direction of arrow key pressed ;(define (worm-ctrl w k) ; (cond ; [(key=? k "up") ; (make-worm (worm-segs w) 0 (* -1 DIAMETER))] ; [(key=? k "down") ; (make-worm (worm-segs w) 0 DIAMETER)] ; [(key=? k "left") ; (make-worm (worm-segs w) (* -1 DIAMETER) 0)] ; [(key=? k "right") ; (make-worm (worm-segs w) DIAMETER 0)] ; [else w])) ; ; ; ; ; ; ; ; ;;;;; ; ;; ; ; ; ; ; ;;; ;; ;;; ; ;;; ; ; ;; ; ;;; ; ; ; ; ; ; ; ;; ; ; ; ;; ; ;; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;; ;; ;;; ; ;; ; ; ; ; ; ; ; ; ; Problem 7: ; ; Modify the function worm-ctrl, given above, so that it produces a ; worm struct that matches the new world state, a worm with food. ; ; This function should be the input to the on-key clause of big-bang. ; ; ; ; ; ;; ; ; ; ; ; ;;; ;;;; ;;; ; ;;; ; ; ; ; ;; ;;; ; ;; ; ; ; ; ; ;; ; ; ; ;;; ;; ; ; ; ;;; ; ; ; ; ;; ; ;; ; ; ; ;;; ; ; ;; ;; ; ; ;; ; ; ; ; ; ;;; ; ; ; ;; ; ; ;; ;; ; ; ; ; ; ; ; ; ; ;; ; ; ; ;; ; ; ; ; ; ; ; ; ; ; ; ; ;; ; ; ;; ; ; ; ; ; ;;; ;; ;;; ; ;; ; ; ; ;; ;;; ; ;; ; ; ; ; ; ; ;; READ PROBLEM 8 INSTRUCTIONS FOR THESE FUNCTIONS. ;; Contract: (at-wall? worm) -> boolean ;; Header: (define at-wall? (lambda (w) ... )) ;; Purpose: Returns true if head of worm is smashed into wall ;(define at-wall? ; (lambda (w) ; (or (< (posn-x (first (worm-segs w))) DIAMETER) ; (> (posn-x (first (worm-segs w))) SIDE) ; (< (posn-y (first (worm-segs w))) DIAMETER) ; (> (posn-y (first (worm-segs w))) SIDE)))) ; Contract: (final-scene worm) -> scene (image) ; Header: (define final-scene (lambda (w) ... )) ; Purpose: Returns text on last scene produced by draw-worm. ;(define final-scene ; (lambda (w) ; (overlay ; (text "WORM HIT WALL!!") 24 'blue) ; (draw-worm w))))) ; ; ; ; ; ; ;;;; ; ; ;; ;; ; ;; ; ; ; ; ; ;;; ;; ;;; ; ;;; ;; ; ; ;; ; ;;; ; ; ; ; ; ;;; ; ;; ; ; ; ;; ; ;; ; ;; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;; ;; ; ; ;; ;; ;;; ; ;; ;;;; ; ; ; ; ; ; ; ; ; ; ; ; ; Problem 8: ; ; The at-wall? function given above should work as-is with the new worm ; struct. The new function that is the first argument to the stop-when ; clause of big-bang should return true if: (1) the head of the worm hits ; a wall, (2) the head of the worm runs into the body of the worm, or ; (3) if the worm grows to MAX segments in length. The literal value for ; MAX should be defined amongst the constants at the top of the code. ; ; Write a new final-scene function that prints out "WORM HIT WALL, YOU LOSE" ; if the worm hits the wall, "WORM HIT SELF, YOU LOSE" if the worm hits itself, ; or "20 SEGMENTS, YOU WIN!!" if the worm reaches MAX = 20 segments in length. ; When testing the new final-scene function, start with a small number ; for MAX. Note that the new final-scene function will probably require ; a helper function to test for the worm hitting the wall (given in function ; at-wall? above), a function to test if the worm hit itself, and a function ; to test if the length of the worm-segs list is equal to MAX. Be sure to ; write contracts, headers and purpose statements for all helper functions. ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;;; ;;; ; ; ; ;; ;; ;;; ; ; ;; ; ; ; ;; ; ; ; ;;; ; ; ; ;; ; ; ;;; ; ; ; ; ; ; ; ; ;; ;; ; ; ; ; ;; ; ; ; ; ; ; ; ;; ;; ; ; ; ; ;; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;; ; ;;; ; ;;;;;; ; ; ; ;; ;;; ; ;;;; ; ; ; ;;; ;; ;; ;; ;; ; ; ;; ;; ;; ;; ; ;; ;; READ PROBLEM 9 INSTRUCTIONS FOR CALLING WORM-MAIN. ;(worm-main INIT-WORM) ; ; ; ; ; ; ;;; ; ; ; ; ; ;; ; ; ; ; ; ;;; ;; ;;; ; ;;; ; ; ; ;; ; ;;; ; ; ; ; ; ; ; ; ;; ; ; ; ;; ; ;; ; ; ; ; ; ; ; ; ; ; ; ; ;;;; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;; ;; ;;; ; ;; ;; ; ; ; ; ; ; ; ; Problem 9: ; ; When you have finished writing the functions requested above, ; go back to the big-bang invocation and uncomment all the clauses. ; ; Then uncomment the call to worm-main above and press run. ;