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