(require 2htdp/image) (require 2htdp/universe) (define-struct world (snake food)) (define-struct snake (dir segs)) ;;; SNAKE WORLD ;;; ;;; World is: (make-world Snake Food) ;;; Food is: Posn ;;; Snake is: (make-snake Direction Segs) ;;; A snake's Segs may not be empty. ;;; The first element of the list is the head. ;;; Direction is one of: 'up 'down 'left 'right ;;; Segs is one of: ;;; -- empty ;;; -- (cons Posn Segs) ;;; Coordinates are in "grid" units, with X running left-to-right, ;;; and Y running bottom-to-top. ;;; Start with the world, when you make up a wish list, the others will fall ;;; out. This should suggest something like that. ;;; Rendering system ;;; world->scene : World -> Scene Top-level big-bang renderer ;;; food+scene : Food Scene -> Scene ;;; snake+scene : Snake Scene -> Scene ;;; ;;; Other big-bang interface ;;; next-world : World -> World ;;; key-handler : World Key-Event -> World ;;; ;;; Snake simulation ;;; snake-slither : Snake -> Snake ;;; new-direction : Snake Direction -> Snake ;;; snake-eat : World -> World ;;; snake-grow : Snake -> Snake ;;; ;;; Various kinds of collision detection ;;; snake-death? : Snake -> Boolean ;;; snake-self-collide? : Snake -> Boolean ;;; snake-wall-collide? : Snake -> Boolean ;;; snake-eating? : World -> Boolean ;; Add purpose statements. Then pick a place and start. ;; --- CONSTANTS : DESCRIBE PROPERTIES THAT ARE ALWAYS THE SAME (define GRID-SIZE 10) ; width of a game-board square (define BOARD-HEIGHT 20) ; height in grid squares (define BOARD-WIDTH 30) ; width in grid squares (define BOARD-HEIGHT-PIXELS (* GRID-SIZE BOARD-HEIGHT)) (define BOARD-WIDTH-PIXELS (* GRID-SIZE BOARD-WIDTH)) (define BACKGROUND (empty-scene BOARD-WIDTH-PIXELS BOARD-HEIGHT-PIXELS)) (define SEGMENT-RADIUS (quotient GRID-SIZE 2)) (define SEGMENT-IMAGE (circle SEGMENT-RADIUS 'solid 'red)) (define FOOD-RADIUS (floor (* 0.9 SEGMENT-RADIUS))) (define FOOD-IMAGE (circle FOOD-RADIUS 'solid 'green)) (define Snake1 (make-snake 'right (list (make-posn 5 3)))) (define Snake2 (make-snake 'right (list (make-posn 5 3) (make-posn 5 2)))) (define Food1 (make-posn 8 12)) (define World1 (make-world Snake1 Food1)) (define World2 (make-world Snake1 (make-posn 5 3))) ; An eating scenario ;; --- FUNCTIONS ;;; Image-painting functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; world->scene : World -> Scene ;;; Build an image of the given world. (define (world->scene w) (snake+scene (world-snake w) (food+scene (world-food w) BACKGROUND))) ;;; food+scene : Food Scene -> Scene ;;; Add image of food to the given scene. (define (food+scene f scn) (place-image/grid FOOD-IMAGE (posn-x f) (posn-y f) scn)) ;;; place-image/grid Image Number Number Scene ;;; Just like PLACE-IMAGE, but use grid coordinates. (define (place-image/grid img x y scn) (place-image img (round (* GRID-SIZE (+ 1/2 x))) (round (- BOARD-HEIGHT-PIXELS (* GRID-SIZE (+ 1/2 y)))) scn)) ;;; snake+scene : Snake Scene -> Scene ;;; Add an image of the snake to the scene. (define (snake+scene snk scn) (segments+scene (snake-segs snk) scn)) ;;; segments+scene : Segs Scene -> Scene ;;; Add an image of the snake segments to the scene. (define (segments+scene segs scn) (cond [(empty? segs) scn] [else (segment+scene (first segs) (segments+scene (rest segs) scn))])) ;;; segment+scene : Posn Scene -> Scene ;;; Add one snake segment to a scene. (define (segment+scene seg scn) (place-image/grid SEGMENT-IMAGE (posn-x seg) (posn-y seg) scn)) ;;; Examples/tests: Scene-painting functions (check-expect (segments+scene empty BACKGROUND) BACKGROUND) (check-expect (segments+scene (snake-segs Snake2) BACKGROUND) (place-image/grid SEGMENT-IMAGE 5 3 (place-image/grid SEGMENT-IMAGE 5 2 BACKGROUND))) (check-expect (snake+scene Snake2 BACKGROUND) (place-image/grid SEGMENT-IMAGE 5 3 (place-image/grid SEGMENT-IMAGE 5 2 BACKGROUND))) (check-expect (world->scene World1) (place-image/grid FOOD-IMAGE 8 12 (place-image/grid SEGMENT-IMAGE 5 3 BACKGROUND))) ;;; Snake motion & growth ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; snake-slither : Snake -> Snake ;;; Move the snake by one step in the appropriate direction. ;;; ...