View difference between Paste ID: dWNiCaHh and PM8QqUEn
SHOW: | | - or go back to the newest paste.
1
 -- Tetris by MKmisfit
2
3
 --level increases every 10 lines cleared
4
 --score rewards increase by 100% per 5 levels
5
 --speed increases by 100% per 10 levels
6
7
 --Z00WXkk0
8
 --if border were a character it would help judge depth
9
 
10
local timerLength = 0.5
11
local timerLengthMin = 0.05
12
13
local pieceX
14
local pieceY
15
local pieceR
16
local pieceType
17
local nextPieceType
18
local score
19
local level
20
local gameOver
21
22
local pieceArray = {
23
{ {0,0},{-1,0},{1,0},{0,1} },
24
{ {0,0},{-1,0},{-2,0},{1,0} },
25
{ {0,0},{-1,0},{0,1},{1,1} },
26
{ {0,0},{-1,1},{0,1},{1,0} },
27
{ {0,0},{1,0},{0,1},{1,1} },
28
{ {0,0},{-1,0},{1,0},{1,1} },
29
{ {0,0},{-1,0},{1,0},{-1,1} }
30
}
31
32
local pieceColor = {colors.magenta, colors.lightBlue, colors.red, colors.lime, colors.yellow, colors.blue, colors.orange}
33
34
local edgeCharacter = "+"
35
36
local numPieces = 7
37
38
local boardArray
39
local boardWidth = 12
40
local boardHeight = 21
41
local edgeColor = colors.white
42
local boardColor = colors.black
43
44
local boardX = 8
45
local boardY = -1
46
local scoreX = 26
47
local scoreY = 3
48
local nextPieceX = 26
49
local nextPieceY = 8
50
51
local highScore = {}
52
local saveFile = "tetris_scores"
53
54
local function loadHighScore()
55
56
	if fs.exists(saveFile) then
57
		local file = fs.open(saveFile,"r")				
58
		for n = 1, 10 do
59
			highScore[n] = {file.readLine(), tonumber(file.readLine())}
60
		end	
61
		file.close()
62
	else
63
		for n = 1, 10 do
64
			highScore[n] = {"", 0}
65
		end
66
	end
67
end
68
69
local function saveHighScore()
70
	local file = fs.open(saveFile,"w")	
71
			
72
	for n = 1, 10 do
73
		file.write(highScore[n][1].."\n")
74
		file.write(tostring(highScore[n][2]).."\n")
75
	end
76
	file.close()
77
end
78
79
local function testHighScore()
80
	for n = 1, 10 do
81
		if score > highScore[n][2] then
82
			term.setCursorPos(1,1)
83
			term.write("You got a High Score!")
84
			term.setCursorPos(1,2)
85
			term.write("Enter your name: ")
86
			name = string.sub(io.read(), 1, 16)
87
			name = name .. string.sub("                  ", 1, 18 - string.len(name))
88
			table.insert(highScore, n, {name, score})
89
			return true
90
		end
91
	end
92
	return false
93
end
94
95
local function drawCredits()
96
	term.setCursorPos(1,1)
97
	term.write("Tetris")
98
	term.setCursorPos(1,2)
99
	term.write("Original by Alexey Pajitnov circa 1984")
100
	term.setCursorPos(1,3)
101
	term.write("Lua adaptation by MKmisfit")
102
	term.setCursorPos(1,4)
103
	term.write("arrow keys move, (1, 2) keys rotate, ENTER pauses")
104
105
	if highScore[1][2] > 0 then
106
		term.setCursorPos(1,6)
107
		term.write("High Scores")
108
		for n = 1, 10 do
109
			if highScore[n][2] == 0 then break end
110
			term.setCursorPos(1,n+6)
111
			term.write(highScore[n][1] .. highScore[n][2])
112
		end
113
	end
114
115
end
116
117
local function testPiece(piece, x, y, rotation)
118
	local c
119
	if rotation == 0 then
120
		for i = 1, 4 do
121
			c = boardArray[x + piece[i][1]][y + piece[i][2]]
122
			if c ~= boardColor then
123
				return c
124
			end
125
		end
126
	end
127
	if rotation == 1 then
128
		for i = 1, 4 do
129
			c = boardArray[x - piece[i][2]][y + piece[i][1]]
130
			if c ~= boardColor then
131
				return c
132
			end
133
		end
134
	end
135
	if rotation == 2 then
136
		for i = 1, 4 do
137
			c = boardArray[x - piece[i][1]][y - piece[i][2]] 
138
			if c ~= boardColor then
139
				return c
140
			end
141
		end
142
	end
143
	if rotation == 3 then
144
		for i = 1, 4 do
145
			c = boardArray[x + piece[i][2]][y - piece[i][1]]
146
			if c ~= boardColor then
147
				return c
148
			end
149
		end
150
	end
151
152
	return boardColor
153
end
154
155
local function setPiece(piece, x, y, rotation, color)
156
	if rotation == 0 then
157
		for i = 1, 4 do
158
			boardArray[x + piece[i][1]][y + piece[i][2]] = color 
159
		end
160
	end
161
	if rotation == 1 then
162
		for i = 1, 4 do
163
			boardArray[x - piece[i][2]][y + piece[i][1]] = color 
164
		end
165
	end
166
	if rotation == 2 then
167
		for i = 1, 4 do
168
			boardArray[x - piece[i][1]][y - piece[i][2]] = color
169
		end
170
	end
171
	if rotation == 3 then
172
		for i = 1, 4 do
173
			boardArray[x + piece[i][2]][y - piece[i][1]] = color
174
		end
175
	end
176
	
177
	--test for completed lines
178
	local minX = 2
179
	local maxX = boardWidth - 1	
180
	local minY = y - 2
181
	local maxY = y + 2
182
183
	local hasPixels
184
	local linesCleared = 0
185
186
	if minY < 3 then minY = 3 end
187
	if maxY >= boardHeight then maxY = boardHeight - 1 end
188
	
189
	for by = minY, maxY do
190
	for bx = minX, maxX do
191
		if boardArray[bx][by] == boardColor then break end
192
		if bx == maxX then
193
			linesCleared = linesCleared + 1
194
			for copyy = by - 1, 2, -1 do			
195
				term.setCursorPos(minX + boardX, copyy + 1 + boardY)
196
				hasPixels = false
197
				for copyx = minX, maxX do
198
					term.setBackgroundColor(boardArray[copyx][copyy])
199
					term.write(" ")
200
					hasPixels = hasPixels or (boardArray[copyx][copyy] ~= boardColor)
201
					boardArray[copyx][copyy + 1] = boardArray[copyx][copyy]	
202
				end
203
				if not hasPixels then break end
204
				--clear top line
205
				if copyy == 2 then
206
					term.setCursorPos(minX + boardX, copyy + boardY)
207
					term.setBackgroundColor(boardColor)
208
					for copyx = minX, maxX do
209
						term.write(" ")
210
						boardArray[copyx][copyy] = boardColor
211
					end
212
				end
213
			end
214
			sleep(0.5)
215
		end
216
	end
217
	end
218
219
	if linesCleared ~= 0 then
220
		if linesCleared == 1 then
221
			score = score + 100 * (1 + level / 5)
222
		end
223
		if linesCleared == 2 then
224
			score = score + 200 * (1 + level / 5)
225
		end
226
		if linesCleared == 3 then
227
			score = score + 400 * (1 + level / 5)
228
		end
229
		if linesCleared == 4 then
230
			score = score + 800 * (1 + level / 5)
231
		end
232
		score = math.floor(score)
233
234
		level = level + linesCleared * 0.1
235
		timerLength = 0.5 / (1 + level / 10)
236
		if timerLength < timerLengthMin then timerLength = timerLengthMin end
237
238
		term.setBackgroundColor(boardColor)
239
		term.setCursorPos(scoreX + 7, scoreY)
240
		term.write(tostring(score) .. "       ")
241
		term.setCursorPos(scoreX + 7, scoreY + 1)
242
		term.write(tostring(math.floor(level)) .. "       ")
243
	end
244
end
245
246
local function drawPiece(piece, x, y, rotation, color)
247
	if rotation == 0 then
248
		for i = 1, 4 do
249
			term.setCursorPos(x + piece[i][1], y + piece[i][2])
250
			term.setBackgroundColor(color)
251
			term.write(" ")
252
		end
253
	end
254
	if rotation == 1 then
255
		for i = 1, 4 do
256
			term.setCursorPos(x - piece[i][2], y + piece[i][1])
257
			term.setBackgroundColor(color)
258
			term.write(" ")
259
		end
260
	end
261
	if rotation == 2 then
262
		for i = 1, 4 do
263
			term.setCursorPos(x - piece[i][1], y - piece[i][2])
264
			term.setBackgroundColor(color)
265
			term.write(" ")
266
		end
267
	end
268
	if rotation == 3 then
269
		for i = 1, 4 do
270
			term.setCursorPos(x + piece[i][2], y - piece[i][1])
271
			term.setBackgroundColor(color)
272
			term.write(" ")
273
		end
274
	end
275
end
276
277
local function dropNewPiece()
278
	pieceX = boardWidth / 2
279
	pieceY = 2
280
	pieceType = nextPieceType
281
	nextPieceType = math.floor(math.random(1, numPieces + 0.999))
282
	pieceR = 0
283
284
	if testPiece(pieceArray[pieceType], pieceX, pieceY, pieceR) ~= boardColor then
285
		gameOver = true
286
	end
287
	
288
	drawPiece(pieceArray[pieceType], nextPieceX + 2, nextPieceY + 2, 0, boardColor)
289
	drawPiece(pieceArray[nextPieceType], nextPieceX + 2, nextPieceY + 2, 0, pieceColor[nextPieceType])
290
end
291
292
local function main()
293
	--clear the board	
294
295
	term.setTextColor(colors.black)
296
	for x = 1, boardWidth do
297
	for y = 1, boardHeight do
298
		if x == 1 or y == 1 or x == boardWidth or y == boardHeight then		
299
			boardArray[x][y] = edgeColor
300
			if y > 1 and y < boardHeight then 
301
				term.setCursorPos(x + boardX, y + boardY)
302
				term.setBackgroundColor(edgeColor)
303
				term.write(edgeCharacter)
304
			end
305
		else	
306
			boardArray[x][y] = boardColor
307
			term.setCursorPos(x + boardX, y + boardY)
308
			term.setBackgroundColor(boardColor)
309
			term.write(" ")
310
		end
311
	end
312
	end
313
	term.setTextColor(colors.white)
314
	
315
	term.setBackgroundColor(boardColor)
316
	term.setCursorPos(scoreX, scoreY)
317
	term.write("Score: 0       ")
318
	term.setCursorPos(scoreX, scoreY + 1)
319
	term.write("Level: 0       ")
320
	term.setCursorPos(nextPieceX, nextPieceY)
321
	term.write("Next:")
322
323
	gameOver = false
324
	score = 0
325
	level = 0
326
	nextPieceType = math.floor(math.random(1, numPieces + 0.999))
327
	dropNewPiece()
328
	
329
	local event, param
330
	local blockColor
331
	timer1 = os.startTimer(timerLength)
332
	while true do		
333
		event, param = os.pullEvent()
334
335
		if event == "timer" and param == timer1 then 
336
			if testPiece(pieceArray[pieceType], pieceX, pieceY + 1, pieceR) ~= boardColor then
337
				setPiece(pieceArray[pieceType], pieceX, pieceY, pieceR, pieceColor[pieceType])
338
				dropNewPiece()
339
				drawPiece(pieceArray[pieceType], pieceX + boardX, pieceY + boardY, pieceR, pieceColor[pieceType])
340
			else
341
				drawPiece(pieceArray[pieceType], pieceX + boardX, pieceY + boardY, pieceR, boardColor)
342
				pieceY = pieceY + 1
343
				drawPiece(pieceArray[pieceType], pieceX + boardX, pieceY + boardY, pieceR, pieceColor[pieceType])
344
			end
345
		
346
			if gameOver then
347
				break
348
			end
349
350
			timer1 = os.startTimer(timerLength)
351
		end
352
353
		if event == "key" then
354
			if param == 203 then
355
				if testPiece(pieceArray[pieceType], pieceX - 1, pieceY, pieceR) == boardColor then
356
					drawPiece(pieceArray[pieceType], pieceX + boardX, pieceY + boardY, pieceR, boardColor)
357
					pieceX = pieceX - 1
358
					drawPiece(pieceArray[pieceType], pieceX + boardX, pieceY + boardY, pieceR, pieceColor[pieceType])
359
				end
360
			elseif param == 205 then
361
				if testPiece(pieceArray[pieceType], pieceX + 1, pieceY, pieceR) == boardColor then
362
					drawPiece(pieceArray[pieceType], pieceX + boardX, pieceY + boardY, pieceR, boardColor)
363
					pieceX = pieceX + 1
364
					drawPiece(pieceArray[pieceType], pieceX + boardX, pieceY + boardY, pieceR, pieceColor[pieceType])
365
				end
366
			elseif param == 208 then
367
				local adjustment = 0
368
				while testPiece(pieceArray[pieceType], pieceX, pieceY + adjustment + 1, pieceR) == boardColor do
369
					adjustment = adjustment + 1
370
				end
371
372
				if adjustment ~= 0 then
373
					drawPiece(pieceArray[pieceType], pieceX + boardX, pieceY + boardY, pieceR, boardColor)
374
					pieceY = pieceY + adjustment
375
					drawPiece(pieceArray[pieceType], pieceX + boardX, pieceY + boardY, pieceR, pieceColor[pieceType])
376
					score = score + 2 * adjustment
377
					term.setBackgroundColor(boardColor)
378
					term.setCursorPos(scoreX + 7, scoreY)
379
					term.write(tostring(score) .. "       ")
380
					timer1 = os.startTimer(timerLength)
381
				end
382
			elseif param == 2 then
383
				local blockColor
384
				local adjustment = 0
385
				blockColor = testPiece(pieceArray[pieceType], pieceX, pieceY, (pieceR + 1) % 4)
386
				if blockColor == edgeColor then
387
					if pieceX < boardWidth / 2 then
388
						while adjustment < 2 and blockColor == edgeColor do
389
							adjustment  = adjustment + 1
390
							blockColor = testPiece(pieceArray[pieceType], pieceX + adjustment, pieceY, (pieceR + 1) % 4)
391
						end
392
					else
393
						while adjustment > -2 and blockColor == edgeColor do
394
							adjustment  = adjustment - 1
395
							blockColor = testPiece(pieceArray[pieceType], pieceX + adjustment, pieceY, (pieceR + 1) % 4)
396
						end
397
					end
398
				end
399
				if blockColor == boardColor then
400
					drawPiece(pieceArray[pieceType], pieceX + boardX, pieceY + boardY, pieceR, boardColor)
401
					pieceX = pieceX + adjustment
402
					pieceR = (pieceR + 1) % 4
403
					drawPiece(pieceArray[pieceType], pieceX + boardX, pieceY + boardY, pieceR, pieceColor[pieceType])
404
				end
405
			elseif param == 3 then --this code duplicated from above with only the rotation offset changed
406
				local blockColor
407
				local adjustment = 0
408
				blockColor = testPiece(pieceArray[pieceType], pieceX, pieceY, (pieceR + 3) % 4)
409
				if blockColor == edgeColor then
410
					if pieceX < boardWidth / 2 then
411
						while adjustment < 2 and blockColor == edgeColor do
412
							adjustment  = adjustment + 1
413
							blockColor = testPiece(pieceArray[pieceType], pieceX + adjustment, pieceY, (pieceR + 3) % 4)
414
						end
415
					else
416
						while adjustment > -2 and blockColor == edgeColor do
417
							adjustment  = adjustment - 1
418
							blockColor = testPiece(pieceArray[pieceType], pieceX + adjustment, pieceY, (pieceR + 3) % 4)
419
						end
420
					end
421
				end
422
				if blockColor == boardColor then
423
					drawPiece(pieceArray[pieceType], pieceX + boardX, pieceY + boardY, pieceR, boardColor)
424
					pieceX = pieceX + adjustment
425
					pieceR = (pieceR + 3) % 4
426
					drawPiece(pieceArray[pieceType], pieceX + boardX, pieceY + boardY, pieceR, pieceColor[pieceType])
427
				end
428
			elseif param == 28 then
429
				term.setBackgroundColor(boardColor)
430
				term.setCursorPos(scoreX, scoreY + 2)
431
				term.write("Paused")
432
				
433
				repeat
434
					event, param = os.pullEvent()
435
				until event == "key" and param == 28
436
437
				term.setCursorPos(scoreX, scoreY + 2)
438
				term.write("      ")
439
				timer1 = os.startTimer(timerLength)
440
			end
441
		end
442
	end
443
end
444
445
boardArray = {}
446
for x = 1, boardWidth do
447
	boardArray[x] = {}
448
end
449
450
loadHighScore()
451
term.setBackgroundColor(boardColor)
452
term.clear()
453
drawCredits()
454
term.setCursorPos(1,19)
455
term.write("Press ENTER to continue")
456
repeat
457
	event, param = os.pullEvent()
458
until event == "key" and param == 28
459
term.clear()
460
461
main()
462
463
term.setBackgroundColor(colors.black)
464
term.clear()
465
if testHighScore() then
466
	saveHighScore()
467
	term.clear()
468
end
469
drawCredits()
470
term.setCursorPos(1,17)
471
term.write("Your final score was " .. tostring(score))
472
term.setCursorPos(1,18)
473
term.write("Thank You for Playing!")
474
term.setCursorPos(1,19)