]> git.jsancho.org Git - gacela.git/blob - gacela_tetris.lisp
(no commit message)
[gacela.git] / gacela_tetris.lisp
1 (in-package :gacela)
2
3 (set-game-properties :title "Gacela Tetris" :fps 15)
4
5 (defun tetramine-i ()
6   (let ((color '(1 0 0)))
7     `((,color ,color ,color ,color))))
8
9 (defun tetramine-j ()
10   (let ((color '(1 0.5 0)))
11     `((,color ,color ,color)
12       (nil nil ,color))))
13
14 (defun tetramine-l ()
15   (let ((color '(1 0 1)))
16     `((nil nil ,color)
17       (,color ,color ,color))))
18
19 (defun tetramine-o ()
20   (let ((color '(0 0 1)))
21     `((,color ,color)
22       (,color ,color))))
23
24 (defun tetramine-s ()
25   (let ((color '(0 1 0)))
26     `((nil ,color ,color)
27       (,color ,color nil))))
28
29 (defun tetramine-t ()
30   (let ((color '(0.5 0 0)))
31     `((,color ,color ,color)
32       (nil ,color nil))))
33
34 (defun tetramine-z ()
35   (let ((color '(0 1 1)))
36     `((,color ,color nil)
37       (nil ,color ,color))))
38
39 (defun random-tetramine ()
40   (let ((n (random 7)))
41     (cond ((= n 0) (tetramine-i))
42           ((= n 1) (tetramine-j))
43           ((= n 2) (tetramine-l))
44           ((= n 3) (tetramine-o))
45           ((= n 4) (tetramine-s))
46           ((= n 5) (tetramine-t))
47           ((= n 6) (tetramine-z)))))
48
49 (defun draw-cell (cell)
50   (cond ((null cell) nil)
51         (t (with-color cell (draw-square :size 20)))))
52
53 (defun draw-row (row)
54   (mapcar (lambda (cell) (draw-cell cell) (translate 23 0)) row))
55
56 (defun draw-grid (grid)
57   (mapcar (lambda (row) (draw-row row) (translate (* -23 (length row)) -23)) grid))
58
59 (defun join-rows (source destination &optional (offset 0))
60   (cond ((null source) destination)
61         ((null destination) nil)
62         ((> offset 0) (cons (car destination) (join-rows source (cdr destination) (- offset 1))))
63         (t (cons (or (car source) (car destination))
64                  (join-rows (cdr source) (cdr destination) offset)))))
65
66 (defun join-grids (source destination &optional (x 0) (y 0))
67   (cond ((null source) destination)
68         ((null destination) nil)
69         ((> y 0) (cons (car destination)
70                        (join-grids source (cdr destination) x (- y 1))))
71         (t (cons (join-rows (car source) (car destination) x)
72                  (join-grids (cdr source) (cdr destination) x y)))))
73
74 (defun collide-rows (row1 row2 &optional (offset 0))
75   (cond ((not (or row1 row2)) nil)
76         ((> offset 0) (collide-rows row1 (cdr row2) (- offset 1)))
77         (t (or (and (car row1) (car row2)) (collide-rows (cdr row1) (cdr row2))))))
78
79 (defun collide-grids (grid1 grid2 &optional (x 0) (y 0))
80   (cond ((not (or grid1 grid2)) nil)
81         ((> y 0) (collide-grids grid1 (cdr grid2) x (- y 1)))
82         (t (or (collide-rows (car grid1) (car grid2) x)
83                (collide-grids (cdr grid1) (cdr grid2) x y)))))
84
85 (defun rotate-tetramine (grid)
86   (labels ((rot (grid res)
87                 (cond ((null grid) res)
88                       (t (rot (cdr grid) (mapcar #'cons (car grid) res))))))
89           (rot grid (make-list (length (car grid))))))
90
91 (defun row-completed (row)
92   (cond ((null row) t)
93         (t (and (car row) (row-completed (cdr row))))))
94
95 (defun remove-rows-completed (grid)
96   (let ((res (remove-if (lambda (x) (row-completed x)) grid)))
97     (inc-points (- (length grid) (length res)))
98     (labels ((fill (grid n)
99                    (cond ((< n 1) grid)
100                          (t (fill (cons (make-list 14) grid) (- n 1))))))
101             (fill res (- 20 (length res))))))
102
103 (let ((points 0) (lines 0))
104   (defun get-points ()
105     points)
106
107   (defun get-lines ()
108     lines)
109
110   (defun inc-points (l)
111     (incf points
112           (labels ((more-lines-better (n)
113                                       (cond ((= n 0) n)
114                                             (t (+ n (more-lines-better (- n 1)))))))
115                   (* (more-lines-better l) 10)))
116     (incf lines l)))
117
118 (let ((tetramine (random-tetramine)) (x 6) (y 0)
119       (next (random-tetramine))
120       (timer (make-timer))
121       (grid (make-list 20 :initial-element (make-list 14)))
122       (background (load-texture "fondo_tetris.png"))
123 ;      (background (load-texture "../../nehe/lesson06/data/nehe.bmp"))
124       (font (load-font "lazy.ttf" :size 20))
125       (game-over))
126
127   (defun game ()
128     (if game-over (game-over) (tetramine)))
129
130   (defun game-over ()
131     (translate -100 0)
132     (render-text "Game Over" font :size 50))
133
134   (defun tetramine ()
135     (cond ((eq (timer-state timer) 'stopped) (start-timer timer)))
136
137     (cond ((key? 'right)
138            (cond ((not (collide-grids tetramine grid (+ x 1) y))
139                   (incf x)))))
140     (cond ((key? 'left)
141            (cond ((not (collide-grids tetramine grid (- x 1) y))
142                   (decf x)))))
143     (cond ((< x 0) (setq x 0))
144           ((> (+ x (length (car tetramine))) 14) (setq x (- 14 (length (car tetramine))))))
145
146     (cond ((key-pressed? 'up)
147            (let ((t1 (rotate-tetramine tetramine)))
148              (cond ((not (collide-grids t1 grid x y))
149                     (setq tetramine t1))))))
150
151     (cond ((or (key? 'down) (> (get-time timer) 5000))
152            (cond ((or (collide-grids tetramine grid x (+ y 1))
153                       (> (+ y 1 (length tetramine)) 20))
154                   (setq grid (remove-rows-completed (join-grids tetramine grid x y)))
155                   (setq tetramine next x 6 y 0)
156                   (cond ((collide-grids tetramine grid x y) (setq game-over t)))
157                   (setq next (random-tetramine)))
158                  (t (incf y) (start-timer timer)))))
159     (draw-texture background)
160     (translate -288 218)
161     (draw-grid (join-grids tetramine grid x y))
162     (translate 440 440)
163     (draw-grid next)
164     (translate -40 -100)
165     (render-text (format nil "Points: ~d" (get-points)) font)
166     (translate 0 -30)
167     (render-text (format nil "Lines: ~d" (get-lines)) font)))
168
169 (let ((frame 0.0) (fps (make-timer)) (update (make-timer)))
170   (start-timer update)
171   (start-timer fps)
172   (run-game
173    (game)
174    (incf frame)
175    (cond ((> (get-time update) 1000) (print (/ frame (/ (get-time fps) 1000.0))) (start-timer update))))
176   (quit-game))