-
Notifications
You must be signed in to change notification settings - Fork 1
/
tetromino.scm
158 lines (133 loc) · 3.78 KB
/
tetromino.scm
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
;;Tetromino library
(declare (unit tetromino))
(module tetromino *
(import scheme chicken)
(use ncurses))
(use ncurses extras)
;; The tetromino block is a defined as a list structure
;; with the first half describing the current position on the grid
;; and the color to display it as. The second half contains a list
;; of coordinates that define the shape.
;;
;; (COLOR, OFFSET-PAIR) . (P1, P2, P3, P4)
;;
;; We can access the individual elements using the following definitions
(define block-color caar) ;;First element of first pair
(define block-offset cdar) ;;Second element of first pair
(define block-coords cadr) ;;First element of second pair
;; We should also define the max blocks
(define MAX_TETRA 7)
;; All coordinate pairs are in the positive xy plane, which starts
;; from the upper left and goes to the bottom right of the screen.
;; A template for creating the basic building tetromino block
;; TODO: Change the offset for a real game
;;
(define (make-tetromino color x1 y1 x2 y2 x3 y3 x4 y4)
(list (cons color (cons 0 0)) ;;associated metadata
(list (cons x1 y1)
(cons x2 y2)
(cons x3 y3)
(cons x4 y4))))
;; Listed below are all the possible configurations of blocks
;; and their approximate look in ascii
;;
;; ## ## ## ##
;;
(define (I-block)
(make-tetromino
COLOR_RED 0 0 1 0 2 0 3 0))
;;
;; ##
;; ## ## ##
;;
(define (J-block)
(make-tetromino
COLOR_GREEN 0 0 0 1 1 1 2 1))
;; ##
;; ## ## ##
;;
(define (L-block)
(make-tetromino
COLOR_YELLOW 0 1 1 1 2 1 2 0))
;;
;; ## ##
;; ## ##
;;
(define (O-block)
(make-tetromino
COLOR_BLUE 0 0 0 1 1 0 1 1))
;;
;; ## ##
;; ## ##
;;
(define (S-block)
(make-tetromino
COLOR_MAGENTA
1 0 2 0 0 1 1 1))
;;
;; ##
;; ## ## ##
;;
(define (T-block)
(make-tetromino
COLOR_CYAN 1 0 0 1 1 1 2 1))
;;
;; ## ##
;; ## ##
;;
(define (Z-block)
(make-tetromino
COLOR_WHITE 0 0 1 0 1 1 2 1))
;; Below are functions that work on the tetromino block datatype
;; Generate a random tetromino
(define (new-tetra)
(case (random MAX_TETRA)
((0) (I-block))
((1) (J-block))
((2) (L-block))
((3) (O-block))
((4) (S-block))
((5) (T-block))
((6) (Z-block))))
;; Return a list of the actual coordinates of the blocks. The offset is applied to
;; each coordinate base to get the relative position of the block to the origin.
;;
(define (calc-offset tetra)
(let ([off (block-offset tetra)])
(map (lambda (item) (cons (+ (car item) (car off))
(+ (cdr item) (cdr off))))
(block-coords tetra))))
;;Displace the block by displacing the current offset by a delta x
;;and a delta y. Returns a tetra block.
;;
(define (move-block tetra dx dy)
(list (cons (block-color tetra)
(cons (+ (cadar tetra) dx)
(+ (cddar tetra) dy)))
(block-coords tetra)))
;; Rotate a block clockwise. We transform the block based on its position
;; from a relative origin. Takes a basic tetra block and returns a modified
;; block with transformed coordinates.
;;
;; TODO: Rotate the block around a central axis rather than corner point
;;
(define (rot-cw tetra)
(list (car tetra)
(map (lambda
(pair)(cons (* (cdr pair) -1) (car pair)))
(block-coords tetra))))
;;Same as rot-cw, except rotation is done counter-clockwise. The transform is
;;based on the position from a relative origin to the coordinates. Takes a tetra
;;block and returns a modified block with transformed coordinates.
;;
;;TODO: See above
;;
(define (rot-ccw tetra)
(list (car tetra)
(map(lambda (pair)
(cons (cdr pair) (* (car pair) -1)))
(block-coords tetra))))
;; Quick tests
(let ((x (L-block)))
(display x)
(display (rot-cw x)))