comparison examples_forth/tetris.4 @ 57:2088fd998865

sbc09 directry clean up
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 23 Jul 2018 16:07:12 +0900
parents
children
comparison
equal deleted inserted replaced
56:4fa2bdb0c457 57:2088fd998865
1 \
2 \ tetris.4th Tetris for terminals, redone in ANSI-Forth.
3 \ Written 05Apr94 by Dirk Uwe Zoller, e-mail:
4 \ duz@roxi.rz.fht-mannheim.de.
5 \ Look&feel stolen from Mike Taylor's "TETRIS FOR TERMINALS"
6 \
7 \ Please copy and share this program, modify it for your system
8 \ and improve it as you like. But don't remove this notice.
9 \
10 \ Thank you.
11 \
12 \ Changes:
13 \
14 \
15
16 ONLY FORTH DEFINITIONS
17 \ S" FORGET-TT" DROP 1 CHARS - FIND NIP [IF] FORGET-TT [THEN]
18 \ MARKER FORGET-TT
19
20 DECIMAL
21
22 WORDLIST CONSTANT TETRIS
23 GET-ORDER TETRIS DUP ROT 2 + SET-ORDER DEFINITIONS
24
25
26 \ Variables, constants
27
28 BL BL 2CONSTANT EMPTY \ an empty position
29 VARIABLE WIPING \ if true: wipe brick, else draw brick
30 2 CONSTANT COL0 \ position of the pit on screen
31 0 CONSTANT ROW0
32
33 10 CONSTANT WIDE \ size of pit in brick positions
34 20 CONSTANT DEEP
35
36 CHAR J VALUE LEFT-KEY \ customize if you don't like them
37 CHAR K VALUE ROT-KEY
38 CHAR L VALUE RIGHT-KEY
39 BL VALUE DROP-KEY
40 CHAR P VALUE PAUSE-KEY
41 12 VALUE REFRESH-KEY
42 CHAR Q VALUE QUIT-KEY
43
44 VARIABLE SCORE
45 VARIABLE PIECES
46 VARIABLE LEVELS
47 VARIABLE DELAY
48
49 VARIABLE BROW \ where the brick is
50 VARIABLE BCOL
51
52
53 \ stupid random number generator
54
55 VARIABLE SEED
56
57 : RANDOMIZE 0 ." Press any key." CR BEGIN 1+ KEY? UNTIL KEY DROP SEED ! ;
58
59 : RANDOM \ max --- n ; return random number < max
60 SEED @ 1103515245 * 12345 + [ HEX ] 07FFF [ DECIMAL ] AND
61 DUP SEED ! SWAP MOD ;
62
63
64 \ Access pairs of characters in memory:
65
66 : 2C@ DUP 1+ C@ SWAP C@ ;
67 : 2C! DUP >R C! R> 1+ C! ;
68
69
70 : <= > INVERT ;
71 : >= < INVERT ;
72 : D<> D= INVERT ;
73
74
75 \ Drawing primitives:
76
77 : 2EMIT EMIT EMIT ;
78
79 : POSITION \ row col --- ; cursor to the position in the pit
80 2* COL0 + SWAP ROW0 + AT-XY ;
81
82 : STONE \ c1 c2 --- ; draw or undraw these two characters
83 WIPING @ IF 2DROP 2 SPACES ELSE 2EMIT THEN ;
84
85
86 \ Define the pit where bricks fall into:
87
88 : DEF-PIT CREATE WIDE DEEP * 2* ALLOT
89 DOES> ROT WIDE * ROT + 2* CHARS + ;
90
91 DEF-PIT PIT
92
93 : EMPTY-PIT DEEP 0 DO WIDE 0 DO EMPTY J I PIT 2C!
94 LOOP LOOP ;
95
96
97 \ Displaying:
98
99 : DRAW-BOTTOM \ --- ; redraw the bottom of the pit
100 DEEP -1 POSITION
101 [CHAR] + DUP STONE
102 WIDE 0 DO [CHAR] = DUP STONE LOOP
103 [CHAR] + DUP STONE ;
104
105 : DRAW-FRAME \ --- ; draw the border of the pit
106 DEEP 0 DO
107 I -1 POSITION [CHAR] | DUP STONE
108 I WIDE POSITION [CHAR] | DUP STONE
109 LOOP DRAW-BOTTOM ;
110
111 : BOTTOM-MSG \ addr cnt --- ; output a message in the bottom of the pit
112 DEEP OVER 2/ WIDE SWAP - 2/ POSITION TYPE ;
113
114 : DRAW-LINE \ line ---
115 DUP 0 POSITION WIDE 0 DO DUP I PIT 2C@ 2EMIT LOOP DROP ;
116
117 : DRAW-PIT \ --- ; draw the contents of the pit
118 DEEP 0 DO I DRAW-LINE LOOP ;
119
120 : SHOW-KEY \ char --- ; visualization of that character
121 DUP BL <
122 IF [CHAR] @ OR [CHAR] ^ EMIT EMIT SPACE
123 ELSE [CHAR] ` EMIT EMIT [CHAR] ' EMIT
124 THEN ;
125
126 : SHOW-HELP \ --- ; display some explanations
127 30 1 AT-XY ." ***** T E T R I S *****"
128 30 2 AT-XY ." ======================="
129 30 4 AT-XY ." Use keys:"
130 32 5 AT-XY LEFT-KEY SHOW-KEY ." Move left"
131 32 6 AT-XY ROT-KEY SHOW-KEY ." Rotate"
132 32 7 AT-XY RIGHT-KEY SHOW-KEY ." Move right"
133 32 8 AT-XY DROP-KEY SHOW-KEY ." Drop"
134 32 9 AT-XY PAUSE-KEY SHOW-KEY ." Pause"
135 32 10 AT-XY REFRESH-KEY SHOW-KEY ." Refresh"
136 32 11 AT-XY QUIT-KEY SHOW-KEY ." Quit"
137 32 13 AT-XY ." -> "
138 30 16 AT-XY ." Score:"
139 30 17 AT-XY ." Pieces:"
140 30 18 AT-XY ." Levels:"
141 0 22 AT-XY ." ======= This program was written 1994 in ANS Forth by Dirk Uwe Zoller ========"
142 0 23 AT-XY ." =================== Copy it, port it, play it, enjoy it! =====================" ;
143
144 : UPDATE-SCORE \ --- ; display current score
145 38 16 AT-XY SCORE @ 3 .R
146 38 17 AT-XY PIECES @ 3 .R
147 38 18 AT-XY LEVELS @ 3 .R ;
148
149 : REFRESH \ --- ; redraw everything on screen
150 PAGE DRAW-FRAME DRAW-PIT SHOW-HELP UPDATE-SCORE ;
151
152
153 \ Define shapes of bricks:
154
155 : DEF-BRICK CREATE 4 0 DO
156 ' EXECUTE 0 DO DUP I CHARS + C@ C, LOOP DROP
157 REFILL DROP
158 LOOP
159 DOES> ROT 4 * ROT + 2* CHARS + ;
160
161 DEF-BRICK BRICK1 S" "
162 S" ###### "
163 S" ## "
164 S" "
165
166 DEF-BRICK BRICK2 S" "
167 S" <><><><>"
168 S" "
169 S" "
170
171 DEF-BRICK BRICK3 S" "
172 S" {}{}{}"
173 S" {} "
174 S" "
175
176 DEF-BRICK BRICK4 S" "
177 S" ()()() "
178 S" () "
179 S" "
180
181 DEF-BRICK BRICK5 S" "
182 S" [][] "
183 S" [][] "
184 S" "
185
186 DEF-BRICK BRICK6 S" "
187 S" @@@@ "
188 S" @@@@ "
189 S" "
190
191 DEF-BRICK BRICK7 S" "
192 S" %%%% "
193 S" %%%% "
194 S" "
195
196 \ this brick is actually in use:
197
198 DEF-BRICK BRICK S" "
199 S" "
200 S" "
201 S" "
202
203 DEF-BRICK SCRATCH S" "
204 S" "
205 S" "
206 S" "
207
208 CREATE BRICKS ' BRICK1 , ' BRICK2 , ' BRICK3 , ' BRICK4 ,
209 ' BRICK5 , ' BRICK6 , ' BRICK7 ,
210
211 CREATE BRICK-VAL 1 C, 2 C, 3 C, 3 C, 4 C, 5 C, 5 C,
212
213
214 : IS-BRICK \ brick --- ; activate a shape of brick
215 >BODY ['] BRICK >BODY 32 CMOVE ;
216
217 : NEW-BRICK \ --- ; select a new brick by random, count it
218 1 PIECES +! 7 RANDOM
219 BRICKS OVER CELLS + @ IS-BRICK
220 BRICK-VAL SWAP CHARS + C@ SCORE +! ;
221
222 : ROTLEFT 4 0 DO 4 0 DO
223 J I BRICK 2C@ 3 I - J SCRATCH 2C!
224 LOOP LOOP
225 ['] SCRATCH IS-BRICK ;
226
227 : ROTRIGHT 4 0 DO 4 0 DO
228 J I BRICK 2C@ I 3 J - SCRATCH 2C!
229 LOOP LOOP
230 ['] SCRATCH IS-BRICK ;
231
232 : DRAW-BRICK \ row col ---
233 4 0 DO 4 0 DO
234 J I BRICK 2C@ EMPTY D<>
235 IF OVER J + OVER I + POSITION
236 J I BRICK 2C@ STONE
237 THEN
238 LOOP LOOP 2DROP ;
239
240 : SHOW-BRICK FALSE WIPING ! DRAW-BRICK ;
241 : HIDE-BRICK TRUE WIPING ! DRAW-BRICK ;
242
243 : PUT-BRICK \ row col --- ; put the brick into the pit
244 4 0 DO 4 0 DO
245 J I BRICK 2C@ EMPTY D<>
246 IF OVER J + OVER I + PIT
247 J I BRICK 2C@ ROT 2C!
248 THEN
249 LOOP LOOP 2DROP ;
250
251 : REMOVE-BRICK \ row col --- ; remove the brick from that position
252 4 0 DO 4 0 DO
253 J I BRICK 2C@ EMPTY D<>
254 IF OVER J + OVER I + PIT EMPTY ROT 2C! THEN
255 LOOP LOOP 2DROP ;
256
257 : TEST-BRICK \ row col --- flag ; could the brick be there?
258 4 0 DO 4 0 DO
259 J I BRICK 2C@ EMPTY D<>
260 IF OVER J + OVER I +
261 OVER DUP 0< SWAP DEEP >= OR
262 OVER DUP 0< SWAP WIDE >= OR
263 2SWAP PIT 2C@ EMPTY D<>
264 OR OR IF UNLOOP UNLOOP 2DROP FALSE EXIT THEN
265 THEN
266 LOOP LOOP 2DROP TRUE ;
267
268 : MOVE-BRICK \ rows cols --- flag ; try to move the brick
269 BROW @ BCOL @ REMOVE-BRICK
270 SWAP BROW @ + SWAP BCOL @ + 2DUP TEST-BRICK
271 IF BROW @ BCOL @ HIDE-BRICK
272 2DUP BCOL ! BROW ! 2DUP SHOW-BRICK PUT-BRICK TRUE
273 ELSE 2DROP BROW @ BCOL @ PUT-BRICK FALSE
274 THEN ;
275
276 : ROTATE-BRICK \ flag --- flag ; left/right, success
277 BROW @ BCOL @ REMOVE-BRICK
278 DUP IF ROTRIGHT ELSE ROTLEFT THEN
279 BROW @ BCOL @ TEST-BRICK
280 OVER IF ROTLEFT ELSE ROTRIGHT THEN
281 IF BROW @ BCOL @ HIDE-BRICK
282 IF ROTRIGHT ELSE ROTLEFT THEN
283 BROW @ BCOL @ PUT-BRICK
284 BROW @ BCOL @ SHOW-BRICK TRUE
285 ELSE DROP FALSE THEN ;
286
287 : INSERT-BRICK \ row col --- flag ; introduce a new brick
288 2DUP TEST-BRICK
289 IF 2DUP BCOL ! BROW !
290 2DUP PUT-BRICK DRAW-BRICK TRUE
291 ELSE 2DROP FALSE THEN ;
292
293 : DROP-BRICK \ --- ; move brick down fast
294 BEGIN 1 0 MOVE-BRICK 0= UNTIL ;
295
296 : MOVE-LINE \ from to ---
297 OVER 0 PIT OVER 0 PIT WIDE 2* CMOVE DRAW-LINE
298 DUP 0 PIT WIDE 2* BLANK DRAW-LINE ;
299
300 : LINE-FULL \ line-no --- flag
301 TRUE WIDE 0
302 DO OVER I PIT 2C@ EMPTY D=
303 IF DROP FALSE LEAVE THEN
304 LOOP NIP ;
305
306 : REMOVE-LINES \ ---
307 DEEP DEEP
308 BEGIN
309 SWAP
310 BEGIN 1- DUP 0< IF 2DROP EXIT THEN DUP LINE-FULL
311 WHILE 1 LEVELS +! 10 SCORE +! REPEAT
312 SWAP 1-
313 2DUP <> IF 2DUP MOVE-LINE THEN
314 AGAIN ;
315
316 : TO-UPPER \ char --- char ; convert to upper case
317 DUP [CHAR] a >= OVER [CHAR] z <= AND
318 IF [ CHAR A CHAR a - ] LITERAL + THEN ;
319
320 : DISPATCH \ key --- flag
321 CASE TO-UPPER
322 LEFT-KEY OF 0 -1 MOVE-BRICK DROP ENDOF
323 RIGHT-KEY OF 0 1 MOVE-BRICK DROP ENDOF
324 ROT-KEY OF 0 ROTATE-BRICK DROP ENDOF
325 DROP-KEY OF DROP-BRICK ENDOF
326 PAUSE-KEY OF S" Paused " BOTTOM-MSG KEY DROP
327 DRAW-BOTTOM ENDOF
328 REFRESH-KEY OF REFRESH ENDOF
329 QUIT-KEY OF FALSE EXIT ENDOF
330 ENDCASE TRUE ;
331
332 : INITIALIZE \ --- ; prepare for playing
333 RANDOMIZE EMPTY-PIT REFRESH
334 0 SCORE ! 0 PIECES ! 0 LEVELS ! 100 DELAY ! ;
335
336 : ADJUST-DELAY \ --- ; make it faster with increasing score
337 LEVELS @
338 DUP 50 < IF 100 OVER - ELSE
339 DUP 100 < IF 62 OVER 4 / - ELSE
340 DUP 500 < IF 31 OVER 16 / - ELSE 0 THEN THEN THEN
341 DELAY ! DROP ;
342
343 : PLAY-GAME \ --- ; play one tetris game
344 BEGIN
345 NEW-BRICK
346 -1 3 INSERT-BRICK
347 WHILE
348 BEGIN 4 0
349 DO 35 13 AT-XY
350 DELAY @ MS KEY?
351 IF BEGIN KEY KEY? WHILE DROP REPEAT
352 DISPATCH 0=
353 IF UNLOOP EXIT THEN
354 THEN
355 LOOP
356 1 0 MOVE-BRICK 0=
357 UNTIL
358 REMOVE-LINES
359 UPDATE-SCORE
360 ADJUST-DELAY
361 REPEAT ;
362
363 FORTH DEFINITIONS
364
365 : TT \ --- ; play the tetris game
366 INITIALIZE
367 S" Press any key " BOTTOM-MSG KEY DROP DRAW-BOTTOM
368 BEGIN
369 PLAY-GAME
370 S" Again? " BOTTOM-MSG KEY TO-UPPER [CHAR] Y =
371 WHILE INITIALIZE REPEAT
372 0 23 AT-XY CR ;
373
374 ONLY FORTH ALSO DEFINITIONS