Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #lang racket
- #|
- The Snake game
- --------------
- The Snake game revolves around a room filled with pieces of radioactive goo
- and a snake that can remove this goo.
- When the snake eats the goo, it grows and new goo appears. Like all
- radioactive material, goo decays over time. Eventually it expires, but
- fortunately for the snake, a new piece of goo appears elsewhere.
- The player is in control of a snake, and the objective is to grow the snake as
- large as possible. She may change the direction of the snake by pressing one of
- the four arrow keys. When the snake gets close to a piece of goo, it eats the
- goo and grows a new segment. If the snake runs into itself or one of the four
- walls, the game is over. The length of the snake is the player's score.
- Play
- ----
- Run and evaluate
- (start-snake)
- This will pop up a window with instructions for interacting with the program.
- |#
- ;
- ;
- ;
- ;
- ; ;;
- ; ;;; ; ;
- ; ; ;; ;
- ; ; ; ;; ;;; ;;;; ; ;;; ;;;
- ; ; ;; ; ; ; ; ; ; ;
- ; ;;;; ; ; ; ; ; ; ;
- ; ; ; ; ;;;;;; ;;; ;;;;;;;
- ; ; ; ; ; ; ; ; ; ;
- ; ;; ; ; ; ; ;; ; ; ; ;
- ; ; ;;; ;;; ;;; ;;;; ;; ;; ;;;; ;;;;
- ;
- ;
- ;
- ;
- (require 2htdp/image 2htdp/universe)
- ;; -----------------------------------------------------------------------------
- ;; Data Definitions
- ;; A Pit is a (pit Snake (Listof Goo))
- (struct pit (snake goos) #:transparent)
- ;; A Snake is a (make-snake Direction (cons Seg [Listof Seg]))
- (struct snake (dir segs score) #:transparent)
- ;; The head of the snake is the first element in the list of segs.
- ;; Each segment of a snake is located with:
- ;; - x in (0,SIZE),
- ;; - y in (0,SIZE).
- ;; And is SEG-SIZE aligned (x and y are multiples of SEG-SIZE).
- ;; A Seg is a (posn Number Number)
- ;; A Goo is a (goo Posn Number)
- (struct goo (loc expire) #:transparent)
- ;; The expire field is a Natural Number that represents the number
- ;; of ticks until the goo expires. A goo is expired when this field is 1
- ;; A Direction is one of "up" "down" "left" "right"
- ;; A Posn is (posn number number)
- (struct posn (x y) #:transparent)
- ;; Represents a two dimensional point.
- ;; -----------------------------------------------------------------------------
- ;; Constants
- ;; Tick Rate
- (define TICK-RATE 0.2)
- ;; Board Size Constants
- (define SIZE 20)
- ;; Snake Constants
- (define SEG-SIZE 30)
- ;; Goo Constants
- (define MAX-GOO 5)
- (define EXPIRATION-TIME 150)
- ;; GRAPHICAL BOARD
- (define WIDTH-PX (* SEG-SIZE 20))
- (define HEIGHT-PX (* SEG-SIZE 20))
- ;; Visual constants
- (define MT-SCENE (empty-scene WIDTH-PX HEIGHT-PX))
- (define GOO-IMG (bitmap "graphics/goo.gif"))
- (define SEG-IMG (bitmap "graphics/body.gif"))
- (define HEAD-IMG (bitmap "graphics/head.gif"))
- (define HEAD-LEFT-IMG HEAD-IMG)
- (define HEAD-DOWN-IMG (rotate 90 HEAD-LEFT-IMG))
- (define HEAD-RIGHT-IMG (flip-horizontal HEAD-LEFT-IMG))
- (define HEAD-UP-IMG (flip-vertical HEAD-DOWN-IMG))
- (define ENDGAME-TEXT-SIZE 26)
- ;
- ;
- ;
- ; ;
- ; ;
- ; ;;; ;;;
- ; ;; ;;
- ; ; ; ; ; ;;;; ;;; ;; ;;;
- ; ; ; ; ; ; ; ; ;; ;
- ; ; ; ; ; ; ; ; ;
- ; ; ; ; ;;;;;; ; ; ;
- ; ; ; ; ; ; ; ;
- ; ; ; ; ;; ; ; ;
- ; ;;; ;;; ;;;; ;; ;;;;;;; ;;; ;;;
- ;
- ;
- ;
- ;
- ;; -----------------------------------------------------------------------------
- ;; Start the Game
- ;; старт программы. Вызывается фун. создания мира.
- (define (start-snake)
- (big-bang
- (pit (snake "right" (list (posn 1 1))0)
- (list (fresh-goo)
- ))
- ; (on-tick next-pit (begin (set! TICK-RATE (/ TICK-RATE 2)) (begin
- ;(display TICK-RATE) TICK-RATE)))
- (on-tick next-pit TICK-RATE)
- (on-key direct-snake)
- (to-draw render-pit)
- (stop-when dead? render-end)))
- (define (tim TICK-RATE)
- (set! TICK-RATE (/ TICK-RATE 2)))
- ;; Pit -> Pit
- ;; Проверяется есть ли яблоко и если есть выполняется действие
- (define (next-pit world)
- (define snake (pit-snake world))
- (define goos (pit-goos world))
- (define goo-to-eat (can-eat (pit-snake world) (pit-goos world)))
- (if goo-to-eat
- (pit (grow (pit-snake world)) (eat (pit-goos world) goo-to-eat (pit-snake world)))
- (pit (slither (pit-snake world)) (pit-goos world)) ))
- ;; если нажата одна из нужных клавиш то происходит действие
- (define (direct-snake w ke)
- (cond [(dir? ke) (world-change-dir w ke)]
- [else w]))
- ;; Начинается рендер мира
- (define (render-pit w)
- (define snakel (pit-snake w))
- (overlay/align "center" "top" (beside
- (text "Score: " ENDGAME-TEXT-SIZE "black")
- (text (number->string (koll snakel)) ENDGAME-TEXT-SIZE "black")
- )
- (snake+scene (pit-snake w)
- (goo-list+scene (pit-goos w) MT-SCENE))
- ))
- ;; проверка что змея умерла
- (define (dead? w)
- (define snake (pit-snake w))
- (or (self-colliding? snake) (wall-colliding? snake)))
- ;; Pit -> Scene
- ;; produces a gameover image
- ;(define (render-end w)
- ; (overlay (text "Game over" ENDGAME-TEXT-SIZE "black")
- ; (render-pit w)))
- (define (render-end w)
- (define snake (pit-snake w))
- (define snakel (pit-snake w))
- (overlay (above (text "Game over" ENDGAME-TEXT-SIZE "orange")
- (text "You score" ENDGAME-TEXT-SIZE "orange")
- (text (number->string (koll snakel)) ENDGAME-TEXT-SIZE "orange")
- )
- (render-pit w)
- )
- ;(display pit-score)
- )
- (define (koll sn)
- (snake-score sn))
- ;; узнает съела ли голова яблоко
- (define (can-eat snake goos)
- (if (close? (snake-head snake) (first goos))
- (first goos)
- #f))
- ;; Удаляется съединое яблоко и добовляется новое
- (define (eat goos goo-to-eat snake)
- (cons (fresh-goo1 snake) (remove goo-to-eat goos)))
- ;; Seg Goo -> Boolean
- ;; Is the segment close to the goo?
- ;; > (close? (posn 1 2) (goo (posn 1 2) 4))
- ;; #t
- (define (close? s g)
- (posn=? s (goo-loc g)))
- ;;Добовляет сигмент к змейки при съедином яблоке и увеличивает значение рекорда
- (define (grow sn)
- (snake (snake-dir sn) (cons (next-head sn) (snake-segs sn)) (+ (snake-score sn) 1))
- ) ;;когда кушает яблоко
- (define (plusgoo n)
- (+ n 1))
- ;; переводит змею на один фрагмент вперед
- (define (slither sn)
- (snake (snake-dir sn)
- (cons (next-head sn) (all-but-last (snake-segs sn))) (snake-score sn) ))
- ;;взависимости от нажатой клавиши изменяет положение
- (define (next-head sn)
- (define head (snake-head sn))
- (define dir (snake-dir sn))
- (cond [(string=? dir "up") (posn-move head 0 -1)]
- [(string=? dir "down") (posn-move head 0 1)]
- [(string=? dir "left") (posn-move head -1 0)]
- [(string=? dir "right") (posn-move head 1 0)]))
- ;; изменяет положение
- (define (posn-move p dx dy)
- (posn (+ (posn-x p) dx)
- (+ (posn-y p) dy)))
- ;;Так как змея не съела яблоко то уничножает конец змеи
- (define (all-but-last segs)
- (cond [(empty? (rest segs)) empty]
- [else (cons (first segs)
- (all-but-last (rest segs)))]))
- ;; -----------------------------------------------------------------------------
- ;; Rotting Goo
- ;; [Listof Goo] -> [Listof Goo]
- ;; Renew and rot goos.
- ;(define (age-goo goos)
- ; (rot (renew goos)))
- ;; [Listof Goo] -> [Listof Goo]
- ;; Renew any rotten goos.
- ;(define (renew goos)
- ; (cond [(empty? goos) empty]
- ; [(rotten? (first goos))
- ; (cons (fresh-goo) (renew (rest goos)))]
- ; [else
- ; (cons (first goos) (renew (rest goos)))]))
- ;; [Listof Goo] -> [Listof Goo]
- ;; Rot all of the goos.
- ;(define (rot goos)
- ; (cond [(empty? goos) empty]
- ; [else (cons (decay (first goos))
- ; (rot (rest goos)))]))
- ;; Goo -> Boolean
- ;; has the goo expired?
- ;; > (rotten? (goo 1 2) 0)
- ;; #t
- (define (rotten? g)
- (zero? (goo-expire g)))
- ;; Goo -> Goo
- ;; decreases the expire field of goo by one
- ;; > (decay (goo (posn 1 2) 2))
- ;; (goo (posn 1 2) 1)
- ;(define (decay g)
- ; (goo (goo-loc g) (sub1 (goo-expire g))))
- ;; Создает яблоко
- (define (fresh-goo)
- (goo (posn (add1 (random (sub1 SIZE)))
- (add1 (random (sub1 SIZE))))
- EXPIRATION-TIME)
- )
- (define (fresh-goo1 snake)
- (goo (posn (add1 (random (sub1 SIZE)))
- (add1 (random (sub1 SIZE))))
- EXPIRATION-TIME)
- )
- ;
- ;
- ;
- ;
- ;
- ; ;;; ;;;;
- ; ; ;
- ; ; ; ;;; ;;; ;;; ;;;; ;
- ; ; ; ; ; ; ; ; ;;
- ; ;;;; ; ; ; ; ;
- ; ; ; ;;;;;;; ; ; ;;;;;
- ; ; ; ; ; ; ;
- ; ; ; ; ; ; ; ; ;
- ; ;;; ;; ;;;; ; ;;;;;;
- ; ;
- ; ;
- ; ;;;;;
- ;
- ;; -----------------------------------------------------------------------------
- ;; String -> Boolean
- ;; Is the given value a direction?
- ;; > (dir? "up")
- ;; #t
- (define (dir? x)
- (or (string=? x "up")
- (string=? x "down")
- (string=? x "left")
- (string=? x "right"))
- )
- ;; Пороверяет два действия если нажата противоположная клавиша и меняет нажатую клавишу
- (define (world-change-dir w d)
- (define the-snake (pit-snake w))
- (cond
- [(opposite-dir? (snake-dir the-snake) d)
- w]
- [else
- (pit (snake-change-dir the-snake d)
- (pit-goos w))]))
- ;; проверяет нажата ли клавиша противополжноя приведушей
- (define (opposite-dir? d1 d2)
- (cond [(and (string=? "up" d1)
- (string=? "down" d2))
- true]
- [(and (string=? "down" d1)
- (string=? "up" d2))
- true]
- [(and (string=? "left" d1)
- (string=? "right" d2))
- true]
- [(and (string=? "right" d1)
- (string=? "left" d2))
- true]
- [else false]))
- ;
- ;
- ;
- ;
- ; ;;
- ; ;;;;;; ;
- ; ; ; ;
- ; ; ; ;;; ;; ;;; ;;; ; ;;; ;; ;;;
- ; ; ; ; ; ;; ; ; ;; ; ; ;;;
- ; ;;;;; ; ; ; ; ; ; ; ; ;
- ; ; ; ;;;;;;; ; ; ; ; ;;;;;;; ;
- ; ; ; ; ; ; ; ; ; ;
- ; ; ; ; ; ; ; ; ;; ; ; ;
- ; ;;; ;; ;;;; ;;; ;;; ;;; ;; ;;;; ;;;;;
- ;
- ;
- ;
- ;
- ;; -----------------------------------------------------------------------------
- ;; Snake Scene -> Scene
- ;; Draws the snake onto the scene
- ;; > (snake+scene snake0 MT-SCENE)
- ;; (place-image SEG-IMG 8 8 MT-SCENE)
- (define (snake+scene snake scene)
- (define snake-body-scene
- (img-list+scene (snake-body snake) SEG-IMG scene))
- (define dir (snake-dir snake))
- (img+scene (snake-head snake)
- (cond [(string=? "up" dir) HEAD-UP-IMG]
- [(string=? "down" dir) HEAD-DOWN-IMG]
- [(string=? "left" dir) HEAD-LEFT-IMG]
- [(string=? "right" dir) HEAD-RIGHT-IMG])
- snake-body-scene))
- ;; рисует яблоки на сцене
- (define (goo-list+scene goos scene)
- (define (get-posns-from-goo goos)
- (cond [(empty? goos) empty]
- [else (cons (goo-loc (first goos))
- (get-posns-from-goo (rest goos)))]))
- (img-list+scene (get-posns-from-goo goos) GOO-IMG scene))
- ;; отсылает отрисовщику элементы по очереди
- (define (img-list+scene posns img scene)
- (cond [(empty? posns) scene]
- [else (img+scene (first posns)
- img
- (img-list+scene (rest posns) img scene))]))
- ;; отрисовывает элемент в нужной позиции
- (define (img+scene posn img scene)
- (place-image img
- (* (posn-x posn) SEG-SIZE)
- (* (posn-y posn) SEG-SIZE)
- scene))
- ;
- ;
- ;
- ;
- ; ;;
- ; ;;;;;;; ; ;;;; ;
- ; ; ; ; ; ;;
- ; ; ; ;; ;;; ;;; ; ; ;;;; ;; ; ; ;;;
- ; ; ; ;; ; ; ;; ; ; ; ;; ;; ; ; ;
- ; ;;;; ; ; ; ; ; ; ; ; ; ; ;
- ; ; ; ; ; ; ; ; ;;;;; ;;;;;; ; ; ; ;;;;;;;
- ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
- ; ; ; ; ; ; ;; ; ; ; ;; ; ; ; ; ;
- ; ;;;;;;; ;;; ;;; ;;; ;; ;;;;; ;;;; ;; ;;; ;; ;; ;;;;
- ;
- ;
- ;
- ;
- ;; -----------------------------------------------------------------------------
- ;; проверка что змея сама себя укусила
- (define (self-colliding? sn)
- (cons? (member (snake-head sn) (snake-body sn))))
- ;; проверка что змея вышла за пределы сцены
- (define (wall-colliding? sn)
- (define x (posn-x (snake-head sn)))
- (define y (posn-y (snake-head sn)))
- (or (= 0 x) (= x SIZE)
- (= 0 y) (= y SIZE)))
- ;
- ;
- ;
- ;
- ;
- ; ;;; ;;; ;;; ;;; ;;; ;;;;;;; ;;;;; ;;;;;;; ;;; ;;;;;; ;;; ;;;
- ; ;; ; ; ; ; ; ; ; ;; ; ; ; ;
- ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
- ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
- ; ; ; ; ; ; ; ; ; ; ; ;;;;; ;
- ; ;;;;;; ; ; ; ; ; ; ; ; ;;;;;; ; ; ;
- ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
- ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
- ; ;;; ;;; ;;;; ;;; ;;; ;;;;;;; ;;;;;;;; ;;;;;;; ;;; ;;; ;;; ;; ;;;;;
- ;
- ;
- ;
- ;
- ;; -----------------------------------------------------------------------------
- ;; Posn Posn -> Boolean
- ;; Are the two posns are equal?
- ;; > (posn=? (posn 1 1) (posn 1 1))
- ;; true
- (define (posn=? p1 p2)
- (and (= (posn-x p1) (posn-x p2))
- (= (posn-y p1) (posn-y p2))))
- ;;Возращает позицию головы змеи
- (define (snake-head sn)
- (car (snake-segs sn)))
- ;; вовращает тело змеи без головы
- (define (snake-body sn)
- (rest (snake-segs sn)))
- ;; Snake Direction -> Snake
- (define (snake-change-dir sn d)
- (snake d (snake-segs sn) (snake-score sn)))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement