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) |