Tetris: Difference between revisions

37,748 bytes added ,  2 months ago
Added Yabasic
No edit summary
(Added Yabasic)
 
(One intermediate revision by one other user not shown)
Line 1,988:
 
=={{header|VBScript}}==
A '''playable''' Tetris in VBScript is not possible as it can't read single keystrokes.
 
=={{header|Wren}}==
 
See [[Tetris/Wren]]
 
=={{header|Yabasic}}==
The code is from Artur Spengler ([https://www.github.com/letztes/tetris])
<syntaxhighlight lang="vbnet" style="height:40ex;overflow:scroll;">REM requires yabasic 2.7x, download at www.yabasic.de
 
REM Author: Artur Spengler
REM Website: www.github.com/letztes/tetris
REM License: This program is free software; you can redistribute it and/or
REM modify it under the same terms as yabasic itself.
 
 
dim BLOCK_COLOR(4)
dim rotated_figure(4)
 
dim CLOCKWISE_ROTATED_FIGURE_NUMBER(19)
CLOCKWISE_ROTATED_FIGURE_NUMBER(1) = 2 REM horizontal stick rotates to vertical stick
CLOCKWISE_ROTATED_FIGURE_NUMBER(2) = 1 REM vertical stick
CLOCKWISE_ROTATED_FIGURE_NUMBER(3) = 3 REM No need to rotate the square block
CLOCKWISE_ROTATED_FIGURE_NUMBER(4) = 5 REM bottom-left: nose left down horizontal L
CLOCKWISE_ROTATED_FIGURE_NUMBER(5) = 6 REM bottom-right nose top left vertical L
CLOCKWISE_ROTATED_FIGURE_NUMBER(6) = 7 REM bottom-left nose up horizontal L
CLOCKWISE_ROTATED_FIGURE_NUMBER(7) = 4 REM nose bottom right vertical L
CLOCKWISE_ROTATED_FIGURE_NUMBER(8) = 9 REM bottom-right nose down horizontal J
CLOCKWISE_ROTATED_FIGURE_NUMBER(9) = 10 REM nose bottom left vertical J
CLOCKWISE_ROTATED_FIGURE_NUMBER(10) = 11 REM bottom-right nose up left horizontal J
CLOCKWISE_ROTATED_FIGURE_NUMBER(11) = 8 REM bottom-left nose top right vertical J
CLOCKWISE_ROTATED_FIGURE_NUMBER(12) = 13 REM left bottom horizontal S-block
CLOCKWISE_ROTATED_FIGURE_NUMBER(13) = 12 REM right bottom vertical S-block
CLOCKWISE_ROTATED_FIGURE_NUMBER(14) = 15 REM right bottom horizontal S-block
CLOCKWISE_ROTATED_FIGURE_NUMBER(15) = 14 REM left bottom vertical S-block
CLOCKWISE_ROTATED_FIGURE_NUMBER(16) = 17 REM left bottom nose top horizontal T-brick
CLOCKWISE_ROTATED_FIGURE_NUMBER(17) = 18 REM nose right vertical T-block
CLOCKWISE_ROTATED_FIGURE_NUMBER(18) = 19 REM nose down horizontal T-block
CLOCKWISE_ROTATED_FIGURE_NUMBER(19) = 16 REM nose left vertical T-block
 
dim CLOCKWISE_ROTATED_X_SHIFT(19)
CLOCKWISE_ROTATED_X_SHIFT(1) = 1
CLOCKWISE_ROTATED_X_SHIFT(2) = -1
CLOCKWISE_ROTATED_X_SHIFT(3) = 0
CLOCKWISE_ROTATED_X_SHIFT(4) = 1
CLOCKWISE_ROTATED_X_SHIFT(5) = -1
CLOCKWISE_ROTATED_X_SHIFT(6) = 2
CLOCKWISE_ROTATED_X_SHIFT(7) = -2
CLOCKWISE_ROTATED_X_SHIFT(8) = -2
CLOCKWISE_ROTATED_X_SHIFT(9) = 2
CLOCKWISE_ROTATED_X_SHIFT(10) = -1
CLOCKWISE_ROTATED_X_SHIFT(11) = 1
CLOCKWISE_ROTATED_X_SHIFT(12) = 1
CLOCKWISE_ROTATED_X_SHIFT(13) = -1
CLOCKWISE_ROTATED_X_SHIFT(14) = -1
CLOCKWISE_ROTATED_X_SHIFT(15) = 1
CLOCKWISE_ROTATED_X_SHIFT(16) = 1
CLOCKWISE_ROTATED_X_SHIFT(17) = 0
CLOCKWISE_ROTATED_X_SHIFT(18) = 0
CLOCKWISE_ROTATED_X_SHIFT(19) = -1
 
dim CLOCKWISE_ROTATED_Y_SHIFT(19)
CLOCKWISE_ROTATED_Y_SHIFT(1) = 1
CLOCKWISE_ROTATED_Y_SHIFT(2) = -1
CLOCKWISE_ROTATED_Y_SHIFT(3) = 0
CLOCKWISE_ROTATED_Y_SHIFT(4) = 0
CLOCKWISE_ROTATED_Y_SHIFT(5) = -1
CLOCKWISE_ROTATED_Y_SHIFT(6) = 1
CLOCKWISE_ROTATED_Y_SHIFT(7) = 0
CLOCKWISE_ROTATED_Y_SHIFT(8) = 0
CLOCKWISE_ROTATED_Y_SHIFT(9) = -1
CLOCKWISE_ROTATED_Y_SHIFT(10) = 1
CLOCKWISE_ROTATED_Y_SHIFT(11) = 0
CLOCKWISE_ROTATED_Y_SHIFT(12) = 0
CLOCKWISE_ROTATED_Y_SHIFT(13) = 0
CLOCKWISE_ROTATED_Y_SHIFT(14) = 0
CLOCKWISE_ROTATED_Y_SHIFT(15) = 0
CLOCKWISE_ROTATED_Y_SHIFT(16) = 1
CLOCKWISE_ROTATED_Y_SHIFT(17) = 0
CLOCKWISE_ROTATED_Y_SHIFT(18) = 0
CLOCKWISE_ROTATED_Y_SHIFT(19) = -1
 
dim COUNTERCLOCKWISE_ROTATED_FIGURE_NUMBER(19)
COUNTERCLOCKWISE_ROTATED_FIGURE_NUMBER(1) = 2
COUNTERCLOCKWISE_ROTATED_FIGURE_NUMBER(2) = 1
COUNTERCLOCKWISE_ROTATED_FIGURE_NUMBER(3) = 3
COUNTERCLOCKWISE_ROTATED_FIGURE_NUMBER(4) = 7
COUNTERCLOCKWISE_ROTATED_FIGURE_NUMBER(5) = 4
COUNTERCLOCKWISE_ROTATED_FIGURE_NUMBER(6) = 5
COUNTERCLOCKWISE_ROTATED_FIGURE_NUMBER(7) = 6
COUNTERCLOCKWISE_ROTATED_FIGURE_NUMBER(8) = 11
COUNTERCLOCKWISE_ROTATED_FIGURE_NUMBER(9) = 8
COUNTERCLOCKWISE_ROTATED_FIGURE_NUMBER(10) = 9
COUNTERCLOCKWISE_ROTATED_FIGURE_NUMBER(11) = 10
COUNTERCLOCKWISE_ROTATED_FIGURE_NUMBER(12) = 13
COUNTERCLOCKWISE_ROTATED_FIGURE_NUMBER(13) = 12
COUNTERCLOCKWISE_ROTATED_FIGURE_NUMBER(14) = 15
COUNTERCLOCKWISE_ROTATED_FIGURE_NUMBER(15) = 14
COUNTERCLOCKWISE_ROTATED_FIGURE_NUMBER(16) = 19
COUNTERCLOCKWISE_ROTATED_FIGURE_NUMBER(17) = 16
COUNTERCLOCKWISE_ROTATED_FIGURE_NUMBER(18) = 17
COUNTERCLOCKWISE_ROTATED_FIGURE_NUMBER(19) = 18
 
dim COUNTERCLOCKWISE_ROTATED_X_SHIFT(19)
COUNTERCLOCKWISE_ROTATED_X_SHIFT(1) = 1
COUNTERCLOCKWISE_ROTATED_X_SHIFT(2) = -1
COUNTERCLOCKWISE_ROTATED_X_SHIFT(3) = 0
COUNTERCLOCKWISE_ROTATED_X_SHIFT(4) = 1
COUNTERCLOCKWISE_ROTATED_X_SHIFT(7) = -1
COUNTERCLOCKWISE_ROTATED_X_SHIFT(6) = 2
COUNTERCLOCKWISE_ROTATED_X_SHIFT(5) = -2
COUNTERCLOCKWISE_ROTATED_X_SHIFT(8) = -2
COUNTERCLOCKWISE_ROTATED_X_SHIFT(11) = 2
COUNTERCLOCKWISE_ROTATED_X_SHIFT(10) = -1
COUNTERCLOCKWISE_ROTATED_X_SHIFT(9) = 1
COUNTERCLOCKWISE_ROTATED_X_SHIFT(12) = 1
COUNTERCLOCKWISE_ROTATED_X_SHIFT(13) = -1
COUNTERCLOCKWISE_ROTATED_X_SHIFT(14) = -1
COUNTERCLOCKWISE_ROTATED_X_SHIFT(15) = 1
COUNTERCLOCKWISE_ROTATED_X_SHIFT(16) = 1
COUNTERCLOCKWISE_ROTATED_X_SHIFT(19) = 0
COUNTERCLOCKWISE_ROTATED_X_SHIFT(18) = 0
COUNTERCLOCKWISE_ROTATED_X_SHIFT(17) = -1
 
dim COUNTERCLOCKWISE_ROTATED_Y_SHIFT(19)
COUNTERCLOCKWISE_ROTATED_Y_SHIFT(1) = 1
COUNTERCLOCKWISE_ROTATED_Y_SHIFT(2) = -1
COUNTERCLOCKWISE_ROTATED_Y_SHIFT(3) = 0
COUNTERCLOCKWISE_ROTATED_Y_SHIFT(4) = 0
COUNTERCLOCKWISE_ROTATED_Y_SHIFT(5) = 0
COUNTERCLOCKWISE_ROTATED_Y_SHIFT(6) = 1
COUNTERCLOCKWISE_ROTATED_Y_SHIFT(7) = -1
COUNTERCLOCKWISE_ROTATED_Y_SHIFT(8) = 0
COUNTERCLOCKWISE_ROTATED_Y_SHIFT(9) = 0
COUNTERCLOCKWISE_ROTATED_Y_SHIFT(10) = 1
COUNTERCLOCKWISE_ROTATED_Y_SHIFT(11) = -1
COUNTERCLOCKWISE_ROTATED_Y_SHIFT(12) = 0
COUNTERCLOCKWISE_ROTATED_Y_SHIFT(13) = 0
COUNTERCLOCKWISE_ROTATED_Y_SHIFT(14) = 0
COUNTERCLOCKWISE_ROTATED_Y_SHIFT(15) = 0
COUNTERCLOCKWISE_ROTATED_Y_SHIFT(16) = 1
COUNTERCLOCKWISE_ROTATED_Y_SHIFT(17) = -1
COUNTERCLOCKWISE_ROTATED_Y_SHIFT(18) = 0
COUNTERCLOCKWISE_ROTATED_Y_SHIFT(19) = 0
 
COLUMNS = 10
ROWS = 20
 
REM measures in pixels
WINDOW_WIDTH = 640 rem PAL TV norm. More or less.
WINDOW_HEIGHT = 512
BLOCK_WIDTH = 25
FIELD_OFFSET_X = 200
FIELD_OFFSET_Y = 5
FIELD_WIDTH = BLOCK_WIDTH * COLUMNS
FIELD_HEIGHT = BLOCK_WIDTH * ROWS
 
PREVIEW_WINDOW_WIDTH = BLOCK_WIDTH*6
PREVIEW_WINDOW_HEIGHT = BLOCK_WIDTH*6
PREVIEW_WINDOW_OFFSET_X = FIELD_OFFSET_X+FIELD_WIDTH+BLOCK_WIDTH
PREVIEW_WINDOW_OFFSET_Y = FIELD_OFFSET_Y+PREVIEW_WINDOW_HEIGHT/2+BLOCK_WIDTH*2
 
LINES_COUNT_WINDOW_WIDTH = BLOCK_WIDTH*4
LINES_COUNT_WINDOW_HEIGHT = BLOCK_WIDTH
LINES_COUNT_WINDOW_OFFSET_X = 50
LINES_COUNT_WINDOW_OFFSET_Y = PREVIEW_WINDOW_OFFSET_Y
 
LEVEL_COUNT_WINDOW_WIDTH = BLOCK_WIDTH*4
LEVEL_COUNT_WINDOW_HEIGHT = BLOCK_WIDTH
LEVEL_COUNT_WINDOW_OFFSET_X = LINES_COUNT_WINDOW_OFFSET_X
LEVEL_COUNT_WINDOW_OFFSET_Y = PREVIEW_WINDOW_OFFSET_Y + 50
 
POINTS_COUNT_WINDOW_WIDTH = BLOCK_WIDTH*4
POINTS_COUNT_WINDOW_HEIGHT = BLOCK_WIDTH
POINTS_COUNT_WINDOW_OFFSET_X = LEVEL_COUNT_WINDOW_OFFSET_X
POINTS_COUNT_WINDOW_OFFSET_Y = LEVEL_WINDOW_OFFSET_Y + 50
 
REM measures in blocks
dim MATRIX(10,20)
 
REM needs to be adjusted to the actual figure when necessary
START_X = 5
START_Y = 0
PREVIEW_START_X = 3
PREVIEW_START_Y = 0
 
REM subroutines can return only one single value. so when rotating the brick, the adjustment of root_block_x and root_block_y needs the workaround with global intermediate variables
INTERMEDIATE_BLOCK_X = 0
INTERMEDIATE_BLOCK_y = 0
 
REM measures in seconds
TIMEQUANT = 0.1
 
REM various
TIMELOOPS = 15
LINES_TOTAL = 0
LEVEL_TOTAL = 0
POINTS_TOTAL = 0
 
dim TOPSCORE$(3)
TOPSCORE$(0) = "JOSE 010000 09"
TOPSCORE$(1) = "JUAN 005278 03"
TOPSCORE$(2) = "YOU 000000 00"
 
sub check_topscore_file()
local filehandle, i
filehandle = open("topscore.txt", "r")
if filehandle = 0 then
filehandle = open("topscore.txt", "w")
if filehandle = 0 error "Could not open 'topscore.txt' for writing"
for i=0 to arraysize(TOPSCORE$(), 1)
print #filehandle TOPSCORE$(i)
next
close filehandle
else
for i=0 to arraysize(TOPSCORE$(), 1)
line input #filehandle TOPSCORE$(i)
print TOPSCORE$(i)
next
close filehandle
fi
end sub
 
sub clear_block(block_x, block_y)
MATRIX(block_x, block_y) = 0
color 0,0,0
fill rectangle FIELD_OFFSET_X+block_x*BLOCK_WIDTH, FIELD_OFFSET_Y+block_y*BLOCK_WIDTH to FIELD_OFFSET_X+block_x*BLOCK_WIDTH+BLOCK_WIDTH, FIELD_OFFSET_Y+block_y*BLOCK_WIDTH+BLOCK_WIDTH
end sub
 
sub draw_block(block_x, block_y, figure_number, preview)
local inner_color$ REM dark blue or bright blue
local border_color$ REM dark blue
local shining_color$ REM white
local dark_blue$, bright_blue$
local offset_x, offset_y
shining_color$ = "234,234,234"
dark_blue$ = "105,105,220"
bright_blue$ = "155,155,220"
if preview=1 then
offset_x = PREVIEW_WINDOW_OFFSET_X
offset_y = PREVIEW_WINDOW_OFFSET_Y+BLOCK_WIDTH
else
offset_x = FIELD_OFFSET_X
offset_y = FIELD_OFFSET_Y
MATRIX(block_x, block_y) = -1 * figure_number
fi
switch figure_number
case 0: return REM empty block
case 4: case 5: case 6: case 7: case 14: case 15: inner_color$=bright_blue$: border_color$=bright_blue$: break
case 8: case 9: case 10: case 11: case 12: case 13: inner_color$=dark_blue$: border_color$=dark_blue$: break
default: inner_color$=shining_color$: border_color$=dark_blue$
end switch
color inner_color$
fill rectangle offset_x+block_x*BLOCK_WIDTH, offset_y+block_y*BLOCK_WIDTH to offset_x+block_x*BLOCK_WIDTH+BLOCK_WIDTH, offset_y+block_y*BLOCK_WIDTH+BLOCK_WIDTH
color 1,1,1
REM Black border around the brick, 2px thick
rectangle offset_x+block_x*BLOCK_WIDTH, offset_y+block_y*BLOCK_WIDTH to offset_x+block_x*BLOCK_WIDTH+BLOCK_WIDTH, offset_y+block_y*BLOCK_WIDTH+BLOCK_WIDTH
rectangle offset_x+block_x*BLOCK_WIDTH+1, offset_y+block_y*BLOCK_WIDTH+1 to offset_x+block_x*BLOCK_WIDTH+BLOCK_WIDTH-1, offset_y+block_y*BLOCK_WIDTH+BLOCK_WIDTH-1
REM Colored Border, 2px thick
color border_color$
rectangle offset_x+block_x*BLOCK_WIDTH+2, offset_y+block_y*BLOCK_WIDTH+2 to offset_x+block_x*BLOCK_WIDTH+BLOCK_WIDTH-2, offset_y+block_y*BLOCK_WIDTH+BLOCK_WIDTH-2
rectangle offset_x+block_x*BLOCK_WIDTH+3, offset_y+block_y*BLOCK_WIDTH+3 to offset_x+block_x*BLOCK_WIDTH+BLOCK_WIDTH-3, offset_y+block_y*BLOCK_WIDTH+BLOCK_WIDTH-3
REM White shining in the upper right corner
color shining_color$
dot offset_x+block_x*BLOCK_WIDTH, offset_y+block_y*BLOCK_WIDTH
dot offset_x+block_x*BLOCK_WIDTH+1, offset_y+block_y*BLOCK_WIDTH
dot offset_x+block_x*BLOCK_WIDTH, offset_y+block_y*BLOCK_WIDTH+1
dot offset_x+block_x*BLOCK_WIDTH+1, offset_y+block_y*BLOCK_WIDTH+1
dot offset_x+block_x*BLOCK_WIDTH+4, offset_y+block_y*BLOCK_WIDTH+4
dot offset_x+block_x*BLOCK_WIDTH+4, offset_y+block_y*BLOCK_WIDTH+5
dot offset_x+block_x*BLOCK_WIDTH+5, offset_y+block_y*BLOCK_WIDTH+4
dot offset_x+block_x*BLOCK_WIDTH+6, offset_y+block_y*BLOCK_WIDTH+4
dot offset_x+block_x*BLOCK_WIDTH+4, offset_y+block_y*BLOCK_WIDTH+6
dot offset_x+block_x*BLOCK_WIDTH+5, offset_y+block_y*BLOCK_WIDTH+5
end sub
 
sub clear_figure(block_x, block_y, figure())
local i
for i = 0 to arraysize(figure(), 1)
if figure(i) = 0 then
clear_block(block_x, block_y)
elsif figure(i) = 1 then
block_x = block_x + 1
clear_block(block_x, block_y)
elsif figure(i) = 2 then
block_x = block_x - 1
clear_block(block_x, block_y)
elsif figure(i) = 3 then
block_y = block_y - 1
clear_block(block_x, block_y)
fi
next
end sub
 
sub draw_figure(block_x, block_y, figure(), figure_number)
local i
for i = 0 to arraysize(figure(), 1)
if figure(i) = 0 then
draw_block(block_x, block_y, figure_number)
elsif figure(i) = 1 then
block_x = block_x + 1
draw_block(block_x, block_y, figure_number)
elsif figure(i) = 2 then
block_x = block_x - 1
draw_block(block_x, block_y, figure_number)
elsif figure(i) = 3 then
block_y = block_y - 1
draw_block(block_x, block_y, figure_number)
fi
next
end sub
 
sub display_preview_figure(next_figure_number)
local next_figure_root_block_x
local next_figure_root_block_y
local next_figure(4)
choose_figure(next_figure(), next_figure_number)
next_figure_root_block_x = set_root_block_x(PREVIEW_START_X, next_figure_number)
next_figure_root_block_y = set_root_block_y(PREVIEW_START_Y, next_figure_number)
 
REM clear the preview window
color 11,11,51
fill rectangle PREVIEW_WINDOW_OFFSET_X, PREVIEW_WINDOW_OFFSET_Y to PREVIEW_WINDOW_OFFSET_X+PREVIEW_WINDOW_WIDTH, PREVIEW_WINDOW_OFFSET_Y+PREVIEW_WINDOW_HEIGHT
REM draw the next figure
color 150,150,150
draw_preview_figure(next_figure_root_block_x, next_figure_root_block_y, next_figure(), next_figure_number)
end sub
 
sub draw_preview_figure(block_x, block_y, preview_figure(), next_figure_number)
local i, preview
preview = 1
for i = 0 to arraysize(preview_figure(), 1)
if preview_figure(i) = 0 then
draw_block(block_x, block_y, next_figure_number, preview)
elsif preview_figure(i) = 1 then
block_x = block_x + 1
draw_block(block_x, block_y, next_figure_number, preview)
elsif preview_figure(i) = 2 then
block_x = block_x - 1
draw_block(block_x, block_y, next_figure_number, preview)
elsif preview_figure(i) = 3 then
block_y = block_y - 1
draw_block(block_x, block_y, next_figure_number, preview)
fi
next
end sub
 
 
sub choose_figure(figure(), figure_number)
if figure_number = 1 then REM horizontal stick
figure(0) = 0
figure(1) = 1
figure(2) = 1
figure(3) = 1
figure(4) = 0
return 1
elsif figure_number = 2 then REM vertical stick
figure(0) = 0
figure(1) = 3
figure(2) = 3
figure(3) = 3
figure(4) = 0
return 1
elsif figure_number = 3 then REM square block
figure(0) = 0
figure(1) = 1
figure(2) = 3
figure(3) = 2
figure(4) = 0
return 1
elsif figure_number = 4 then REM bottom-left nose down horizontal L
figure(0) = 0
figure(1) = 3
figure(2) = 1
figure(3) = 1
figure(4) = 0
return 1
elsif figure_number = 5 then REM bottom-right nose top left vertical L
figure(0) = 0
figure(1) = 3
figure(2) = 3
figure(3) = 2
figure(4) = 0
return 1
elsif figure_number = 6 then REM bottom-left nose up horizontal L
figure(0) = 0
figure(1) = 1
figure(2) = 1
figure(3) = 3
figure(4) = 0
return 1
elsif figure_number = 7 then REM nose bottom right vertical L
figure(0) = 0
figure(1) = 2
figure(2) = 3
figure(3) = 3
figure(4) = 0
return 1
elsif figure_number = 8 then REM bottom-right nose down horizontal L
figure(0) = 0
figure(1) = 3
figure(2) = 2
figure(3) = 2
figure(4) = 0
return 1
elsif figure_number = 9 then REM nose bottom left vertical L
figure(0) = 0
figure(1) = 1
figure(2) = 3
figure(3) = 3
figure(4) = 0
return 1
elsif figure_number = 10 then REM bottom-right nose up left horizontal L
figure(0) = 0
figure(1) = 2
figure(2) = 2
figure(3) = 3
figure(4) = 0
return 1
elsif figure_number = 11 then REM bottom-left nose top right vertical L
figure(0) = 0
figure(1) = 3
figure(2) = 3
figure(3) = 1
figure(4) = 0
return 1
elsif figure_number = 12 then REM left bottom horizontal S-block
figure(0) = 0
figure(1) = 1
figure(2) = 3
figure(3) = 1
figure(4) = 0
return 1
elsif figure_number = 13 then REM right bottom vertical S-block
figure(0) = 0
figure(1) = 3
figure(2) = 2
figure(3) = 3
figure(4) = 0
return 1
elsif figure_number = 14 then REM right bottom horizontal S-block
figure(0) = 0
figure(1) = 2
figure(2) = 3
figure(3) = 2
figure(4) = 0
return 1
elsif figure_number = 15 then REM left bottom vertical S-block
figure(0) = 0
figure(1) = 3
figure(2) = 1
figure(3) = 3
figure(4) = 0
return 1
elsif figure_number = 16 then REM nose top horizontal T-block
figure(0) = 0
figure(1) = 1
figure(2) = 1
figure(3) = 2
figure(4) = 3
return 1
elsif figure_number = 17 then REM nose right vertical T-block
figure(0) = 0
figure(1) = 3
figure(2) = 1
figure(3) = 2
figure(4) = 3
return 1
elsif figure_number = 18 then REM nose down horizontal T-block
figure(0) = 0
figure(1) = 3
figure(2) = 2
figure(3) = 1
figure(4) = 1
return 1
elsif figure_number = 19 then REM nose left vertical T-block
figure(0) = 0
figure(1) = 3
figure(2) = 2
figure(3) = 1
figure(4) = 3
return 1
fi
end sub
 
 
sub set_root_block_x(root_block_x, figure_number)
switch figure_number
case 1: return root_block_x-2 REM horizontal stick
case 3: return root_block_x-1 REM square block
case 4: return root_block_x-1 REM bottom-left horizontal L
case 5: return root_block_x+1 REM L
case 6: return root_block_x-1 REM L
case 7: return root_block_x+1 REM L
case 8: return root_block_x+1 REM right bottom horizontal S-block
case 9: return root_block_x-1 REM L
case 10: return root_block_x+1 REM L
case 11: return root_block_x-1 REM L
case 12: return root_block_x-1 REM left bottom horizontal S-block
case 13: return root_block_x+1 REM right bottom vertical S-block
case 14: return root_block_x REM right bottom horizontal S-block
case 15: return root_block_x REM left bottom vertical S-block
case 16: return root_block_x-1 REM nose top horizontal T-block
case 18: return root_block_x-1 REM nose down horizontal T-block
default: return root_block_x
end switch
end sub
 
 
sub set_root_block_y(root_block_y, figure_number)
switch figure_number
case 1: return root_block_y REM horizontal stick
case 2: return root_block_y+3 REM vertical stick
case 5: return root_block_y+2 REM vertical L
case 7: return root_block_y+2 REM vertical L
case 9: return root_block_y+2 REM vertical L
case 11: return root_block_y+2 REM vertical L
case 13: return root_block_y+2 REM vertical S-block
case 15: return root_block_y+2 REM vertical S-block
case 17: return root_block_y+2 REM nose left vertical T-block
case 19: return root_block_y+2 REM nose right vertical T-block
default: return root_block_y+1
end switch
end sub
 
 
sub pause_game()
local keystroke$
 
keystroke$ = inkey$()
if keystroke$ = "p" return 1
end sub
 
 
sub game_over()
local filehandle, i
color 0,0,0
fill rectangle 0,0 to WINDOW_WIDTH, WINDOW_HEIGHT
color 150,150,150
text int(WINDOW_WIDTH/2)-25, int(WINDOW_HEIGHT/2), "Game Over"
inkey$
check_topscore_file()
local current_character_input$
local total_user_input$
for i = 0 to arraysize(TOPSCORE$(), 1)-1
topscore_line_substring = val(mid$(TOPSCORE$(i), 8, 6))
if POINTS_TOTAL >= topscore_line_substring then
color 0,0,0
fill rectangle int(WINDOW_WIDTH/2)-10,int(WINDOW_HEIGHT/2)+BLOCK_WIDTH*3 to WINDOW_WIDTH, WINDOW_HEIGHT
color 150,150,150
REM the better topscores
for k=0 to i-1
text int(WINDOW_WIDTH/2)-10, int(WINDOW_HEIGHT/2)+BLOCK_WIDTH*(4+k), TOPSCORE$(k)
next
REM the worse topscores
for j = 2 to k+1 step -1
text int(WINDOW_WIDTH/2)-10, int(WINDOW_HEIGHT/2)+BLOCK_WIDTH*(4+j), TOPSCORE$(j-1)
TOPSCORE$(j) = TOPSCORE$(j-1)
next
REM the player's topscore
points_local_string$ = "000000"
if POINTS_TOTAL < 10 then
right$(points_local_string$, 1) = str$(POINTS_TOTAL)
elsif POINTS_TOTAL < 100 then
right$(points_local_string$, 2) = str$(POINTS_TOTAL)
elsif POINTS_TOTAL < 1000 then
right$(points_local_string$, 3) = str$(POINTS_TOTAL)
elsif POINTS_TOTAL < 10000 then
right$(points_local_string$, 4) = str$(POINTS_TOTAL)
elsif POINTS_TOTAL < 100000 then
right$(points_local_string$, 5) = str$(POINTS_TOTAL)
elsif POINTS_TOTAL < 1000000 then
points_local_string$ = str$(POINTS_TOTAL)
fi
level_local_string$ = "00"
if LEVEL_TOTAL < 10 then
right$(level_local_string$, 1) = str$(LEVEL_TOTAL-1)
else
level_local_string$ = str$(LEVEL_TOTAL-1)
fi
text int(WINDOW_WIDTH/2)-60, int(WINDOW_HEIGHT/2)+BLOCK_WIDTH, "You are a tetris master."
text int(WINDOW_WIDTH/2)-60, int(WINDOW_HEIGHT/2)+BLOCK_WIDTH*2, "Please enter your name."
repeat
current_character_input$=inkey$(0.5)
total_user_input$ = check_character_input$(current_character_input$, total_user_input$)
cursor$=blink_cursor$()
color 0,0,0
fill rectangle int(WINDOW_WIDTH/2)-10,int(WINDOW_HEIGHT/2)+BLOCK_WIDTH*(3+k) to WINDOW_WIDTH,int(WINDOW_HEIGHT/2)+BLOCK_WIDTH*(4+k)
color 150,150,150
text int(WINDOW_WIDTH/2)-10, int(WINDOW_HEIGHT/2)+BLOCK_WIDTH*(4+k), total_user_input$+cursor$
text int(WINDOW_WIDTH/2)+30, int(WINDOW_HEIGHT/2)+BLOCK_WIDTH*(4+k), points_local_string$+" "+level_local_string$
 
cursor_blinker=cursor_blinker+1
until(current_character_input$="enter")
total_user_input$ = left$(total_user_input$, len(total_user_input$)-5)
color 0,0,0
fill rectangle int(WINDOW_WIDTH/2)-10,int(WINDOW_HEIGHT/2)+BLOCK_WIDTH*(3+k) to WINDOW_WIDTH,int(WINDOW_HEIGHT/2)+BLOCK_WIDTH*(4+k)
color 150,150,150
text int(WINDOW_WIDTH/2)+30, int(WINDOW_HEIGHT/2)+BLOCK_WIDTH*(4+k), points_local_string$
text int(WINDOW_WIDTH/2)+75, int(WINDOW_HEIGHT/2)+BLOCK_WIDTH*(4+k), level_local_string$
text int(WINDOW_WIDTH/2)-10, int(WINDOW_HEIGHT/2)+BLOCK_WIDTH*(4+k), total_user_input$
 
left$(TOPSCORE$(i), 6) = " "
left$(TOPSCORE$(i), len(total_user_input$)) = total_user_input$
mid$(TOPSCORE$(i), 8, 6) = points_local_string$
right$(TOPSCORE$(i), 2) = level_local_string$
break
fi
next
filehandle = open("topscore.txt", "w")
if filehandle=0 then
error "Could not open 'topscore.txt' for writing"
exit
fi
for i = 0 to arraysize(TOPSCORE$(), 1)
print #filehandle TOPSCORE$(i)
print TOPSCORE$(i)
next
close filehandle
inkey$
exit
end sub
 
sub blink_cursor$()
static i
i = i+1
if mod(i, 2) = 0 then
i = 0
return "_"
fi
end sub
 
 
sub is_bad_input(current_character_input$)
if len(current_character_input$)>10 or current_character_input$="left" or current_character_input$="right" or current_character_input$="up" or current_character_input$="down" or current_character_input$="tab" or current_character_input$="scrnup" or current_character_input$="scrndown" or current_character_input$="end" or current_character_input$="home" or current_character_input$="del" or current_character_input$="ins" or current_character_input$="f0" or current_character_input$="f1" or current_character_input$="f2" or current_character_input$="f3" or current_character_input$="f4" or current_character_input$="f5" or current_character_input$="f6" or current_character_input$="f7" or current_character_input$="f8" or current_character_input$="f9" or current_character_input$="f10" or current_character_input$="f11" or current_character_input$="f12" then
return 1
else
return 0
fi
end sub
 
sub check_character_input$(current_character_input$, total_user_input$)
if current_character_input$="backspace" then
total_user_input$=left$(total_user_input$,len(total_user_input$)-1)
current_character_input$=""
elsif is_bad_input(current_character_input$) then
current_character_input$=""
elsif current_character_input$="esc" then
exit
fi
if len(total_user_input$) < 6 then
total_user_input$=total_user_input$+current_character_input$
fi
return total_user_input$
end sub
 
sub is_move_ok(figure(), block_x, block_y)
local i
for i = 0 to arraysize(figure(), 1)
if figure(i) = 1 then
block_x = block_x + 1
elsif figure(i) = 2 then
block_x = block_x - 1
elsif figure(i) = 3 then
block_y = block_y - 1
fi
if block_x < 0: return 0
if block_x > 9: return 0
if block_y < 0: return 0
if block_y > 19: return 0
if MATRIX(block_x, block_y) > 0: return 0
next
return 1
end sub
 
sub rotate(figure(), figure_number, figure_number_rotated, x_shift, y_shift)
choose_figure(rotated_figure(), figure_number_rotated)
if is_move_ok(rotated_figure(), INTERMEDIATE_BLOCK_X+x_shift, INTERMEDIATE_BLOCK_Y+y_shift) then
clear_figure(INTERMEDIATE_BLOCK_X, INTERMEDIATE_BLOCK_Y, figure())
 
INTERMEDIATE_BLOCK_X = INTERMEDIATE_BLOCK_X+x_shift
INTERMEDIATE_BLOCK_Y = INTERMEDIATE_BLOCK_Y+y_shift
choose_figure(figure(), figure_number_rotated)
 
draw_figure(INTERMEDIATE_BLOCK_X, INTERMEDIATE_BLOCK_Y, figure(), figure_number_rotated)
return figure_number_rotated
fi
return figure_number
end sub
 
sub calculate_figure_number()
local figure_number
random_number = int(ran(6))+1 REM 0 means empty
switch random_number
REM stick
case 1: figure_number = 1:break
REM square block
case 2: figure_number = 3:break
REM L block
case 3: figure_number = 4:break
REM J block
case 4: figure_number = 8:break
REM S block
case 5: figure_number = 12:break
REM Z block
case 6: figure_number = 14:break
end switch
return figure_number
end sub
 
sub turn_is_over(block_x, block_y, figure())
REM This subroutine is divided into four parts
REM Part 1: Fixate the current brick
REM Part 2: Check if some lines are complete; exit the routine if none
REM Part 3: Remove the complete lines
REM Part 4: Drop the lines above
 
REM Before any parts, define the local variables for this subroutine
local i
local complete_lines(4) REM array to store the y-coordinates of complete lines
local complete_lines_in_figure(4) REM array to store the y-coordinates of complete lines
local block_y_to_check REM iterator variable
local block_x_to_check REM iterator variable
local block_y_original REM needed for checking the lines
local lines_dropped REM counter variable for gaining the level and the speed
local y_iterator
local figure_number_above
local lines_in_figure
local lowest_complete_line
local complete_lines_in_figure_cat$
local points_base REM base points number will be multiplied with level etc
block_y_original = block_y
complete_lines_in_figure_cat$ = "0000"
REM First part:
REM Fixate the current brick
for i = 0 to arraysize(figure(), 1)
if figure(i) = 1 then
block_x = block_x + 1
elsif figure(i) = 2 then
block_x = block_x - 1
elsif figure(i) = 3 then
block_y = block_y - 1
fi
MATRIX(block_x, block_y) = abs(MATRIX(block_x, block_y))
next
REM Second part:
REM Check if some lines are compelete and if so remove them in the next step;
REM exit the routine otherwise
i = 0
for block_y_to_check = 0 to 3 REM the rows in the figure
for block_x_to_check = 0 to 9 REM the columns in the field
if block_y_original-block_y_to_check < 0 then
game_over()
elsif MATRIX(block_x_to_check, block_y_original-block_y_to_check) = 0 then
goto CHECK_LINES_NEXT
fi
next
complete_lines(i) = block_y_original-block_y_to_check
complete_lines_in_figure(i) = 1
lines_dropped = lines_dropped + 1
 
label CHECK_LINES_NEXT
i=i+1
next
REM Add some points as reward for successful move
points_base = block_y
POINTS_TOTAL = POINTS_TOTAL + points_base * LEVEL_TOTAL
display_points()
REM If no lines were completed, exit the subroutine
if lines_dropped = 0 return
REM Part 3: Remove the complete lines
REM Remove the lines
REM remove in the current line all blocks, beginning with
REM blocks 4 and 5, then wait 0.1 sec, then blocks 3 and 6, etc.
for block_x_to_change=0 to 4
for i=0 to 3
REM if in the line no empty blocks are encountered
if complete_lines_in_figure(i)=1 then
clear_block(5+block_x_to_change, complete_lines(i))
clear_block(4-block_x_to_change, complete_lines(i))
fi
next
wait 0.1
next
REM Part 4: Drop the lines above
REM Therefore first the array with the lines in figure needs to be
REM adjusted, so the dropping routine does not need to look ahead
REM but simple drops the line according to the array
REM adjust the number of lines to look ahead when dropping
mid$(complete_lines_in_figure_cat$,1,1) = str$(complete_lines_in_figure(0))
mid$(complete_lines_in_figure_cat$,2,1) = str$(complete_lines_in_figure(1))
mid$(complete_lines_in_figure_cat$,3,1) = str$(complete_lines_in_figure(2))
mid$(complete_lines_in_figure_cat$,4,1) = str$(complete_lines_in_figure(3))
# print complete_lines_in_figure_cat$
switch complete_lines_in_figure_cat$
case "1000": complete_lines_in_figure_cat$ = "1111": break
case "0100": complete_lines_in_figure_cat$ = "0111": break
case "0010": complete_lines_in_figure_cat$ = "0011": break
case "0001": complete_lines_in_figure_cat$ = "0001": break
case "1100": complete_lines_in_figure_cat$ = "2222": break
case "0110": complete_lines_in_figure_cat$ = "0222": break
case "0011": complete_lines_in_figure_cat$ = "0022": break
case "1010": complete_lines_in_figure_cat$ = "1222": break
case "0101": complete_lines_in_figure_cat$ = "0122": break
case "1001": complete_lines_in_figure_cat$ = "1122": break
case "0111": complete_lines_in_figure_cat$ = "0333": break
case "1011": complete_lines_in_figure_cat$ = "1333": break
case "1101": complete_lines_in_figure_cat$ = "2333": break
case "1110": complete_lines_in_figure_cat$ = "3333": break
case "1111": complete_lines_in_figure_cat$ = "4444": break
end switch
complete_lines_in_figure(0) = val(mid$(complete_lines_in_figure_cat$,1,1))
complete_lines_in_figure(1) = val(mid$(complete_lines_in_figure_cat$,2,1))
complete_lines_in_figure(2) = val(mid$(complete_lines_in_figure_cat$,3,1))
complete_lines_in_figure(3) = val(mid$(complete_lines_in_figure_cat$,4,1))
# print complete_lines_in_figure_cat$
# inkey$
REM Determine the lowest complete lines, i.e. where to start to drop
for i = 0 to 3
if complete_lines(i) <> 0 then
lowest_complete_line = complete_lines(i)
lowest_complete_line_index = i
break
fi
next
REM Begin to actually drop the lines above the complete ones
lines_in_figure = lowest_complete_line_index
for y_iterator = lowest_complete_line to 1 step -1
for block_x_to_change = 0 to 9
clear_block(block_x_to_change, y_iterator)
if y_iterator-lines_in_figure > 0 then
figure_number_above = abs(MATRIX(block_x_to_change, y_iterator-complete_lines_in_figure(lines_in_figure)))
draw_block(block_x_to_change, y_iterator, figure_number_above)
REM because draw_block() makes only negative entries into MATRIX
MATRIX(block_x_to_change, y_iterator) = MATRIX(block_x_to_change, y_iterator) * -1
fi
next
if lines_in_figure < 3 then
lines_in_figure = lines_in_figure + 1
fi
next
count_lines(lines_dropped) REM and levels and points
end sub
 
sub count_lines(lines_dropped)
REM and print them out
LINES_TOTAL = LINES_TOTAL + lines_dropped
REM clear rectangle for text and print LINES_TOTAL
color 0,0,0
fill rectangle LINES_COUNT_WINDOW_OFFSET_X,LINES_COUNT_WINDOW_OFFSET_Y to LINES_COUNT_WINDOW_OFFSET_X+LINES_COUNT_WINDOW_WIDTH, LINES_COUNT_WINDOW_OFFSET_Y+LINES_COUNT_WINDOW_HEIGHT
REM print text
color 255,255,255
text LINES_COUNT_WINDOW_OFFSET_X+10,LINES_COUNT_WINDOW_OFFSET_Y+20,"Lines: "+str$(LINES_TOTAL)
REM gain speed if another 10 lines are full
REM or the game just begun
if LINES_TOTAL - LEVEL_TOTAL * 10 >= 0 then
color 0,0,0
fill rectangle LEVEL_COUNT_WINDOW_OFFSET_X,LEVEL_COUNT_WINDOW_OFFSET_Y to LEVEL_COUNT_WINDOW_OFFSET_X+LEVEL_COUNT_WINDOW_WIDTH, LEVEL_COUNT_WINDOW_OFFSET_Y+LEVEL_COUNT_WINDOW_HEIGHT
REM print text LEVEL_TOTAL
if TIMELOOPS > 0 TIMELOOPS = TIMELOOPS - 1
LEVEL_TOTAL = LEVEL_TOTAL + 1
color 255,255,255
text LEVEL_COUNT_WINDOW_OFFSET_X+10,LEVEL_COUNT_WINDOW_OFFSET_Y+20,"LEVEL: "+str$(LEVEL_TOTAL-1)
fi
REM print text POINTS_TOTAL
REM
REM 1 line = 40 points
REM 2 lines = 100 points
REM 3 lines = 300 points
REM 4 lines = 1200
REM 1 line at level 2 = 80 points
switch lines_dropped
case 1: points_base = 40: break
case 2: points_base = 100: break
case 3: points_base = 300: break
case 4: points_base = 1200: break
end switch
POINTS_TOTAL = POINTS_TOTAL + points_base * LEVEL_TOTAL
display_points()
end sub
 
sub display_points()
REM clear window area for POINTS_TOTAL
color 0,0,0
fill rectangle POINTS_COUNT_WINDOW_OFFSET_X,POINTS_COUNT_WINDOW_OFFSET_Y to POINTS_COUNT_WINDOW_OFFSET_X+POINTS_COUNT_WINDOW_WIDTH, POINTS_COUNT_WINDOW_OFFSET_Y+POINTS_COUNT_WINDOW_HEIGHT
color 255,255,255
text POINTS_COUNT_WINDOW_OFFSET_X+10,POINTS_COUNT_WINDOW_OFFSET_Y+20,"POINTS: "+str$(POINTS_TOTAL)
end sub
 
sub main()
REM Testvariables
local y, x
 
clear screen REM reading keystrokes with inkey$() needs 'clear screen'
open window WINDOW_WIDTH, WINDOW_HEIGHT
backcolor 0,0,0
REM backcolor does not work, that is why big black rectangle
color 0,0,0
fill rectangle 0,0 to WINDOW_WIDTH, WINDOW_HEIGHT
REM draw field border
color 150,150,150
rectangle FIELD_OFFSET_X-1, FIELD_OFFSET_Y-1 to FIELD_OFFSET_X+FIELD_WIDTH+1, FIELD_OFFSET_Y+FIELD_HEIGHT+1
REM draw next figure window
rectangle PREVIEW_WINDOW_OFFSET_X-1, PREVIEW_WINDOW_OFFSET_Y-1 to PREVIEW_WINDOW_OFFSET_X+PREVIEW_WINDOW_WIDTH+1, PREVIEW_WINDOW_OFFSET_Y+PREVIEW_WINDOW_HEIGHT+1
REM draw total lines counter
count_lines(LINES_TOTAL)
local figure_number, next_figure_number
local figure(4)
next_figure_number = calculate_figure_number()
local i
REM "while not game over"-LOOP
while(1=1)
figure_number = next_figure_number
next_figure_number = calculate_figure_number()
display_preview_figure(next_figure_number)
REM arrays are passed by reference to subroutines; no need to return the array
choose_figure(figure(), figure_number)
root_block_x = set_root_block_x(START_X, figure_number)
root_block_y = set_root_block_y(START_Y, figure_number)
if !is_move_ok(figure(), root_block_x, root_block_y) then
draw_figure(root_block_x, root_block_y, figure(), figure_number)
wait TIMEQUANT*10
game_over()
fi
if root_block_y > 0: clear_figure(root_block_x, root_block_y, figure())
root_block_y = root_block_y + 1
draw_figure(root_block_x, root_block_y, figure(), figure_number)
REM "while figure is falling down and has not landed yet"-LOOP
while(1=1)
for i = 1 to TIMELOOPS
keystroke$ = inkey$(TIMEQUANT)
if !keystroke$="" then
if keystroke$ = "right" then
if is_move_ok(figure(), root_block_x+1, root_block_y) then
clear_figure(root_block_x, root_block_y, figure())
root_block_x = root_block_x + 1
draw_figure(root_block_x, root_block_y, figure(), figure_number)
fi
elsif keystroke$ = "left" then
if is_move_ok(figure(), root_block_x-1, root_block_y) then
clear_figure(root_block_x, root_block_y, figure())
root_block_x = root_block_x - 1
draw_figure(root_block_x, root_block_y, figure(), figure_number)
fi
elsif keystroke$ = "down" then
if is_move_ok(figure(), root_block_x, root_block_y+1) then
clear_figure(root_block_x, root_block_y, figure())
root_block_y = root_block_y + 1
draw_figure(root_block_x, root_block_y, figure(), figure_number)
fi
elsif keystroke$ = "up" or keystroke$ = "s" then
INTERMEDIATE_BLOCK_X = root_block_x
INTERMEDIATE_BLOCK_Y = root_block_y
figure_number = rotate(figure(), figure_number, CLOCKWISE_ROTATED_FIGURE_NUMBER(figure_number), CLOCKWISE_ROTATED_X_SHIFT(figure_number), CLOCKWISE_ROTATED_Y_SHIFT(figure_number))
root_block_x = INTERMEDIATE_BLOCK_X
root_block_y = INTERMEDIATE_BLOCK_Y
elsif keystroke$ = "d" then
INTERMEDIATE_BLOCK_X = root_block_x
INTERMEDIATE_BLOCK_Y = root_block_y
figure_number = rotate(figure(), figure_number, COUNTERCLOCKWISE_ROTATED_FIGURE_NUMBER(figure_number), COUNTERCLOCKWISE_ROTATED_X_SHIFT(figure_number), COUNTERCLOCKWISE_ROTATED_Y_SHIFT(figure_number))
root_block_x = INTERMEDIATE_BLOCK_X
root_block_y = INTERMEDIATE_BLOCK_Y
elsif keystroke$ = "p" then
pause_game()
elsif keystroke$ = "q" or keystroke$ = "esc" then
exit
fi
fi
next
if root_block_y < 19 and is_move_ok(figure(), root_block_x, root_block_y+1) then
clear_figure(root_block_x, root_block_y, figure())
root_block_y = root_block_y + 1
draw_figure(root_block_x, root_block_y, figure(), figure_number)
else
turn_is_over(root_block_x, root_block_y, figure())
break
fi
wend
sleep 0.5 REM sleep half a second before new brick appears
wend
print "not allowed to get to here!"
sleep 1
game_over()
end sub
 
main()
 
REM ######################</syntaxhighlight>
2,122

edits