This repository has been archived by the owner on Mar 30, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
snake.rkt
125 lines (117 loc) · 3.96 KB
/
snake.rkt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#lang racket
(require
"config.rkt")
(provide
snake%
food%)
; Snake class
(define snake% (class object%
(init [body-arg empty])
; Initialize body as the provided list or a random grid location
; Body is a list of each of the snake's squares, denoted as '(x y) where x and y are the coordinates within grid system
(define body
(cond
[(empty? body-arg) (list (random-square))]
[else body-arg]))
(define direction 'right)
(super-new)
(define/public (draw dc)
(send dc set-pen "Black" 0 'transparent)
(send dc set-brush "Dark Green" 'solid)
(map (lambda (elem)
(draw-square elem dc))
body))
(define/public (get-body)
body)
(define/public (get-head)
(car body))
(define/public (set-direction val)
(set! direction val))
(define/public (dying?)
(define offscreen? (not (onscreen? (get-head))))
; If head is colliding with some other part of the body, dying is true
(define overlap? (collides? (cdr body) (get-head)))
(and debug? (printf "offscreen?: ~v~n" offscreen?))
(and debug? (printf "overlap?: ~v~n" overlap?))
(or offscreen? overlap?))
(define/public (eating? food-location)
(collides? body food-location))
(define/public (move)
; 1. Add new head in proper direction
(grow)
(and debug? (printf "Moved head: ~v, ~v\n" (car (car body)) (cdr (car body))))
; 2. Remove tail (unless instructed to grow during this step)
(set! body (remove-tail body)))
(define/public (grow)
; Add one more square to the snake according to direction
(define new-head (get-head))
(cond
[(eq? direction 'right)
(set! new-head (square-right new-head))]
[(eq? direction 'left)
(set! new-head (square-left new-head))]
[(eq? direction 'up)
(set! new-head (square-above new-head))]
[(eq? direction 'down)
(set! new-head (square-below new-head))])
(set! body (cons new-head body)))))
; Food class
(define food% (class object%
(define body (random-square))
(super-new)
(define/public (draw dc)
(send dc set-brush "Green" 'solid)
(draw-square body dc))
(define/public (get-body)
body)
(define/public (move)
(set! body (random-square)))))
; Helper functions for grid system
; Draw-square: Draws square in grid system
(define (draw-square position dc)
(let ([x (car position)]
[y (cdr position)])
(send dc draw-rectangle (* x square-size) (* y square-size) square-size square-size)))
; collides? Check if `list` has any collisions with `point` (check if list contains the point)
(define (collides? arg-list arg-pair)
(define result #f)
; Check each body element to see if collides with given pair
(for ([i arg-list])
#:break (equal? result #t)
(when (equal? arg-pair i)
(set! result #t)))
; Return the resulting boolean
result)
; random-square: gets random square in grid
(define (random-square)
(cons (random (+ 1 (car (grid-max)))) (random (cdr (grid-max)))))
; grid-max: returns a pair containing the max x and y values that are onscreen in grid system
(define (grid-max)
(define pix-width (car window-size))
(define pix-height (cdr window-size))
(define dc-width (/ pix-width default-scale))
(define dc-height (/ pix-height default-scale))
(cons (- (/ dc-width square-size) 1) (- (/ dc-height square-size) 1)))
; onscreen?
(define (onscreen? pair)
(define local-max (grid-max))
(define x (car pair))
(define y (cdr pair))
(define within-x-axis? (and (>= x 0) (<= x (car local-max))))
(define within-y-axis? (and (>= y 0) (<= y (cdr local-max))))
(and within-x-axis? within-y-axis?))
; remove-tail: Remove tail from l and return result
(define (remove-tail l)
(cond
[(empty? l) (error "remove-tail: list cannot be empty")]
[(empty? (cdr l)) empty]
[else (cons (car l) (remove-tail (cdr l)))]))
; Helper functions for relative square locations
(define (square-above square)
(cons (car square) (- (cdr square) 1)))
(define (square-below square)
(cons (car square) (+ (cdr square) 1)))
(define (square-left square)
(cons (- (car square) 1) (cdr square)))
(define (square-right square)
(cons (+ (car square) 1) (cdr square)))