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