Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Tetris Game for SimpleOS
- -- CC: Tweaked compatible
- local w, h = term.getSize()
- -- Game board dimensions
- local boardWidth = 10
- local boardHeight = 18
- local boardX = math.floor((w - boardWidth * 2) / 2)
- local boardY = 2
- -- Tetromino shapes
- local shapes = {
- { -- I
- {{1,1,1,1}},
- {{1},{1},{1},{1}}
- },
- { -- O
- {{1,1},{1,1}}
- },
- { -- T
- {{0,1,0},{1,1,1}},
- {{1,0},{1,1},{1,0}},
- {{1,1,1},{0,1,0}},
- {{0,1},{1,1},{0,1}}
- },
- { -- S
- {{0,1,1},{1,1,0}},
- {{1,0},{1,1},{0,1}}
- },
- { -- Z
- {{1,1,0},{0,1,1}},
- {{0,1},{1,1},{1,0}}
- },
- { -- J
- {{1,0,0},{1,1,1}},
- {{1,1},{1,0},{1,0}},
- {{1,1,1},{0,0,1}},
- {{0,1},{0,1},{1,1}}
- },
- { -- L
- {{0,0,1},{1,1,1}},
- {{1,0},{1,0},{1,1}},
- {{1,1,1},{1,0,0}},
- {{1,1},{0,1},{0,1}}
- }
- }
- local shapeColors = {
- colors.cyan,
- colors.yellow,
- colors.purple,
- colors.green,
- colors.red,
- colors.blue,
- colors.orange
- }
- -- Game state
- local board = {}
- local currentShape = nil
- local currentRotation = 1
- local currentX, currentY = 1, 1
- local currentType = 1
- local score = 0
- local level = 1
- local lines = 0
- local gameOver = false
- local speed = 0.5
- -- Initialize board
- local function initBoard()
- board = {}
- for y = 1, boardHeight do
- board[y] = {}
- for x = 1, boardWidth do
- board[y][x] = 0
- end
- end
- end
- -- Get current shape data
- local function getShape()
- local rotations = shapes[currentType]
- return rotations[((currentRotation - 1) % #rotations) + 1]
- end
- -- Check collision
- local function checkCollision(shape, px, py)
- for y, row in ipairs(shape) do
- for x, cell in ipairs(row) do
- if cell == 1 then
- local bx = px + x - 1
- local by = py + y - 1
- if bx < 1 or bx > boardWidth or by > boardHeight then
- return true
- end
- if by >= 1 and board[by][bx] ~= 0 then
- return true
- end
- end
- end
- end
- return false
- end
- -- Spawn new piece
- local function spawnPiece()
- currentType = math.random(1, #shapes)
- currentRotation = 1
- currentX = math.floor(boardWidth / 2) - 1
- currentY = 1
- if checkCollision(getShape(), currentX, currentY) then
- gameOver = true
- end
- end
- -- Lock piece to board
- local function lockPiece()
- local shape = getShape()
- for y, row in ipairs(shape) do
- for x, cell in ipairs(row) do
- if cell == 1 then
- local by = currentY + y - 1
- local bx = currentX + x - 1
- if by >= 1 and by <= boardHeight and bx >= 1 and bx <= boardWidth then
- board[by][bx] = currentType
- end
- end
- end
- end
- end
- -- Clear completed lines
- local function clearLines()
- local cleared = 0
- local y = boardHeight
- while y >= 1 do
- local full = true
- for x = 1, boardWidth do
- if board[y][x] == 0 then
- full = false
- break
- end
- end
- if full then
- table.remove(board, y)
- local newRow = {}
- for x = 1, boardWidth do
- newRow[x] = 0
- end
- table.insert(board, 1, newRow)
- cleared = cleared + 1
- else
- y = y - 1
- end
- end
- if cleared > 0 then
- local points = {40, 100, 300, 1200}
- score = score + (points[cleared] or 1200) * level
- lines = lines + cleared
- level = math.floor(lines / 10) + 1
- speed = math.max(0.05, 0.5 - (level - 1) * 0.05)
- end
- end
- -- Draw game
- local function draw()
- term.setBackgroundColor(colors.black)
- term.clear()
- -- Draw border
- term.setBackgroundColor(colors.gray)
- for y = 0, boardHeight + 1 do
- term.setCursorPos(boardX - 1, boardY + y)
- term.write(" ")
- term.setCursorPos(boardX + boardWidth * 2, boardY + y)
- term.write(" ")
- end
- for x = -1, boardWidth * 2 do
- term.setCursorPos(boardX + x, boardY + boardHeight + 1)
- term.write(" ")
- end
- -- Draw board
- for y = 1, boardHeight do
- for x = 1, boardWidth do
- term.setCursorPos(boardX + (x - 1) * 2, boardY + y - 1)
- if board[y][x] ~= 0 then
- term.setBackgroundColor(shapeColors[board[y][x]])
- term.write(" ")
- else
- term.setBackgroundColor(colors.black)
- term.write(" ")
- end
- end
- end
- -- Draw current piece
- if not gameOver then
- local shape = getShape()
- term.setBackgroundColor(shapeColors[currentType])
- for y, row in ipairs(shape) do
- for x, cell in ipairs(row) do
- if cell == 1 then
- local dy = currentY + y - 1
- local dx = currentX + x - 1
- if dy >= 1 then
- term.setCursorPos(boardX + (dx - 1) * 2, boardY + dy - 1)
- term.write(" ")
- end
- end
- end
- end
- end
- -- Draw info
- term.setBackgroundColor(colors.black)
- term.setTextColor(colors.white)
- term.setCursorPos(2, 2)
- term.write("TETRIS")
- term.setCursorPos(2, 4)
- term.write("Score:")
- term.setCursorPos(2, 5)
- term.write(tostring(score))
- term.setCursorPos(2, 7)
- term.write("Level:")
- term.setCursorPos(2, 8)
- term.write(tostring(level))
- term.setCursorPos(2, 10)
- term.write("Lines:")
- term.setCursorPos(2, 11)
- term.write(tostring(lines))
- term.setCursorPos(2, h - 1)
- term.write("[Q] Quit")
- end
- -- Game over screen
- local function showGameOver()
- term.setBackgroundColor(colors.black)
- term.setTextColor(colors.red)
- term.setCursorPos(boardX + 2, boardY + 7)
- term.write("GAME OVER")
- term.setTextColor(colors.white)
- term.setCursorPos(boardX, boardY + 9)
- term.write("ENTER=Restart")
- end
- -- Move piece
- local function movePiece(dx, dy)
- local shape = getShape()
- if not checkCollision(shape, currentX + dx, currentY + dy) then
- currentX = currentX + dx
- currentY = currentY + dy
- return true
- end
- return false
- end
- -- Rotate piece
- local function rotatePiece()
- local oldRotation = currentRotation
- currentRotation = currentRotation + 1
- local shape = getShape()
- if checkCollision(shape, currentX, currentY) then
- currentRotation = oldRotation
- end
- end
- -- Drop piece
- local function dropPiece()
- while movePiece(0, 1) do end
- lockPiece()
- clearLines()
- spawnPiece()
- end
- -- Main game loop
- local function run()
- initBoard()
- spawnPiece()
- score = 0
- level = 1
- lines = 0
- gameOver = false
- speed = 0.5
- while true do
- draw()
- if gameOver then
- showGameOver()
- while true do
- local event, key = os.pullEvent("key")
- if key == keys.enter then
- initBoard()
- spawnPiece()
- score = 0
- level = 1
- lines = 0
- gameOver = false
- speed = 0.5
- break
- elseif key == keys.q then
- return
- end
- end
- end
- local timer = os.startTimer(speed)
- while true do
- local event, p1 = os.pullEvent()
- if event == "key" then
- if p1 == keys.left then
- movePiece(-1, 0)
- draw()
- elseif p1 == keys.right then
- movePiece(1, 0)
- draw()
- elseif p1 == keys.down then
- movePiece(0, 1)
- draw()
- elseif p1 == keys.up then
- rotatePiece()
- draw()
- elseif p1 == keys.space then
- dropPiece()
- break
- elseif p1 == keys.q then
- return
- end
- elseif event == "timer" and p1 == timer then
- break
- end
- end
- if not gameOver then
- if not movePiece(0, 1) then
- lockPiece()
- clearLines()
- spawnPiece()
- end
- end
- end
- end
- run()
Advertisement
Add Comment
Please, Sign In to add comment