ElijahCrafter

Tetris

Nov 27th, 2025
848
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 8.81 KB | Source Code | 0 0
  1. -- Tetris Game for SimpleOS
  2. -- CC: Tweaked compatible
  3.  
  4. local w, h = term.getSize()
  5.  
  6. -- Game board dimensions
  7. local boardWidth = 10
  8. local boardHeight = 18
  9. local boardX = math.floor((w - boardWidth * 2) / 2)
  10. local boardY = 2
  11.  
  12. -- Tetromino shapes
  13. local shapes = {
  14.     { -- I
  15.         {{1,1,1,1}},
  16.         {{1},{1},{1},{1}}
  17.     },
  18.     { -- O
  19.         {{1,1},{1,1}}
  20.     },
  21.     { -- T
  22.         {{0,1,0},{1,1,1}},
  23.         {{1,0},{1,1},{1,0}},
  24.         {{1,1,1},{0,1,0}},
  25.         {{0,1},{1,1},{0,1}}
  26.     },
  27.     { -- S
  28.         {{0,1,1},{1,1,0}},
  29.         {{1,0},{1,1},{0,1}}
  30.     },
  31.     { -- Z
  32.         {{1,1,0},{0,1,1}},
  33.         {{0,1},{1,1},{1,0}}
  34.     },
  35.     { -- J
  36.         {{1,0,0},{1,1,1}},
  37.         {{1,1},{1,0},{1,0}},
  38.         {{1,1,1},{0,0,1}},
  39.         {{0,1},{0,1},{1,1}}
  40.     },
  41.     { -- L
  42.         {{0,0,1},{1,1,1}},
  43.         {{1,0},{1,0},{1,1}},
  44.         {{1,1,1},{1,0,0}},
  45.         {{1,1},{0,1},{0,1}}
  46.     }
  47. }
  48.  
  49. local shapeColors = {
  50.     colors.cyan,
  51.     colors.yellow,
  52.     colors.purple,
  53.     colors.green,
  54.     colors.red,
  55.     colors.blue,
  56.     colors.orange
  57. }
  58.  
  59. -- Game state
  60. local board = {}
  61. local currentShape = nil
  62. local currentRotation = 1
  63. local currentX, currentY = 1, 1
  64. local currentType = 1
  65. local score = 0
  66. local level = 1
  67. local lines = 0
  68. local gameOver = false
  69. local speed = 0.5
  70.  
  71. -- Initialize board
  72. local function initBoard()
  73.     board = {}
  74.     for y = 1, boardHeight do
  75.         board[y] = {}
  76.         for x = 1, boardWidth do
  77.             board[y][x] = 0
  78.         end
  79.     end
  80. end
  81.  
  82. -- Get current shape data
  83. local function getShape()
  84.     local rotations = shapes[currentType]
  85.     return rotations[((currentRotation - 1) % #rotations) + 1]
  86. end
  87.  
  88. -- Check collision
  89. local function checkCollision(shape, px, py)
  90.     for y, row in ipairs(shape) do
  91.         for x, cell in ipairs(row) do
  92.             if cell == 1 then
  93.                 local bx = px + x - 1
  94.                 local by = py + y - 1
  95.                 if bx < 1 or bx > boardWidth or by > boardHeight then
  96.                     return true
  97.                 end
  98.                 if by >= 1 and board[by][bx] ~= 0 then
  99.                     return true
  100.                 end
  101.             end
  102.         end
  103.     end
  104.     return false
  105. end
  106.  
  107. -- Spawn new piece
  108. local function spawnPiece()
  109.     currentType = math.random(1, #shapes)
  110.     currentRotation = 1
  111.     currentX = math.floor(boardWidth / 2) - 1
  112.     currentY = 1
  113.    
  114.     if checkCollision(getShape(), currentX, currentY) then
  115.         gameOver = true
  116.     end
  117. end
  118.  
  119. -- Lock piece to board
  120. local function lockPiece()
  121.     local shape = getShape()
  122.     for y, row in ipairs(shape) do
  123.         for x, cell in ipairs(row) do
  124.             if cell == 1 then
  125.                 local by = currentY + y - 1
  126.                 local bx = currentX + x - 1
  127.                 if by >= 1 and by <= boardHeight and bx >= 1 and bx <= boardWidth then
  128.                     board[by][bx] = currentType
  129.                 end
  130.             end
  131.         end
  132.     end
  133. end
  134.  
  135. -- Clear completed lines
  136. local function clearLines()
  137.     local cleared = 0
  138.     local y = boardHeight
  139.     while y >= 1 do
  140.         local full = true
  141.         for x = 1, boardWidth do
  142.             if board[y][x] == 0 then
  143.                 full = false
  144.                 break
  145.             end
  146.         end
  147.         if full then
  148.             table.remove(board, y)
  149.             local newRow = {}
  150.             for x = 1, boardWidth do
  151.                 newRow[x] = 0
  152.             end
  153.             table.insert(board, 1, newRow)
  154.             cleared = cleared + 1
  155.         else
  156.             y = y - 1
  157.         end
  158.     end
  159.    
  160.     if cleared > 0 then
  161.         local points = {40, 100, 300, 1200}
  162.         score = score + (points[cleared] or 1200) * level
  163.         lines = lines + cleared
  164.         level = math.floor(lines / 10) + 1
  165.         speed = math.max(0.05, 0.5 - (level - 1) * 0.05)
  166.     end
  167. end
  168.  
  169. -- Draw game
  170. local function draw()
  171.     term.setBackgroundColor(colors.black)
  172.     term.clear()
  173.    
  174.     -- Draw border
  175.     term.setBackgroundColor(colors.gray)
  176.     for y = 0, boardHeight + 1 do
  177.         term.setCursorPos(boardX - 1, boardY + y)
  178.         term.write(" ")
  179.         term.setCursorPos(boardX + boardWidth * 2, boardY + y)
  180.         term.write(" ")
  181.     end
  182.     for x = -1, boardWidth * 2 do
  183.         term.setCursorPos(boardX + x, boardY + boardHeight + 1)
  184.         term.write(" ")
  185.     end
  186.    
  187.     -- Draw board
  188.     for y = 1, boardHeight do
  189.         for x = 1, boardWidth do
  190.             term.setCursorPos(boardX + (x - 1) * 2, boardY + y - 1)
  191.             if board[y][x] ~= 0 then
  192.                 term.setBackgroundColor(shapeColors[board[y][x]])
  193.                 term.write("  ")
  194.             else
  195.                 term.setBackgroundColor(colors.black)
  196.                 term.write("  ")
  197.             end
  198.         end
  199.     end
  200.    
  201.     -- Draw current piece
  202.     if not gameOver then
  203.         local shape = getShape()
  204.         term.setBackgroundColor(shapeColors[currentType])
  205.         for y, row in ipairs(shape) do
  206.             for x, cell in ipairs(row) do
  207.                 if cell == 1 then
  208.                     local dy = currentY + y - 1
  209.                     local dx = currentX + x - 1
  210.                     if dy >= 1 then
  211.                         term.setCursorPos(boardX + (dx - 1) * 2, boardY + dy - 1)
  212.                         term.write("  ")
  213.                     end
  214.                 end
  215.             end
  216.         end
  217.     end
  218.    
  219.     -- Draw info
  220.     term.setBackgroundColor(colors.black)
  221.     term.setTextColor(colors.white)
  222.     term.setCursorPos(2, 2)
  223.     term.write("TETRIS")
  224.     term.setCursorPos(2, 4)
  225.     term.write("Score:")
  226.     term.setCursorPos(2, 5)
  227.     term.write(tostring(score))
  228.     term.setCursorPos(2, 7)
  229.     term.write("Level:")
  230.     term.setCursorPos(2, 8)
  231.     term.write(tostring(level))
  232.     term.setCursorPos(2, 10)
  233.     term.write("Lines:")
  234.     term.setCursorPos(2, 11)
  235.     term.write(tostring(lines))
  236.     term.setCursorPos(2, h - 1)
  237.     term.write("[Q] Quit")
  238. end
  239.  
  240. -- Game over screen
  241. local function showGameOver()
  242.     term.setBackgroundColor(colors.black)
  243.     term.setTextColor(colors.red)
  244.     term.setCursorPos(boardX + 2, boardY + 7)
  245.     term.write("GAME OVER")
  246.     term.setTextColor(colors.white)
  247.     term.setCursorPos(boardX, boardY + 9)
  248.     term.write("ENTER=Restart")
  249. end
  250.  
  251. -- Move piece
  252. local function movePiece(dx, dy)
  253.     local shape = getShape()
  254.     if not checkCollision(shape, currentX + dx, currentY + dy) then
  255.         currentX = currentX + dx
  256.         currentY = currentY + dy
  257.         return true
  258.     end
  259.     return false
  260. end
  261.  
  262. -- Rotate piece
  263. local function rotatePiece()
  264.     local oldRotation = currentRotation
  265.     currentRotation = currentRotation + 1
  266.     local shape = getShape()
  267.     if checkCollision(shape, currentX, currentY) then
  268.         currentRotation = oldRotation
  269.     end
  270. end
  271.  
  272. -- Drop piece
  273. local function dropPiece()
  274.     while movePiece(0, 1) do end
  275.     lockPiece()
  276.     clearLines()
  277.     spawnPiece()
  278. end
  279.  
  280. -- Main game loop
  281. local function run()
  282.     initBoard()
  283.     spawnPiece()
  284.     score = 0
  285.     level = 1
  286.     lines = 0
  287.     gameOver = false
  288.     speed = 0.5
  289.    
  290.     while true do
  291.         draw()
  292.        
  293.         if gameOver then
  294.             showGameOver()
  295.             while true do
  296.                 local event, key = os.pullEvent("key")
  297.                 if key == keys.enter then
  298.                     initBoard()
  299.                     spawnPiece()
  300.                     score = 0
  301.                     level = 1
  302.                     lines = 0
  303.                     gameOver = false
  304.                     speed = 0.5
  305.                     break
  306.                 elseif key == keys.q then
  307.                     return
  308.                 end
  309.             end
  310.         end
  311.        
  312.         local timer = os.startTimer(speed)
  313.        
  314.         while true do
  315.             local event, p1 = os.pullEvent()
  316.            
  317.             if event == "key" then
  318.                 if p1 == keys.left then
  319.                     movePiece(-1, 0)
  320.                     draw()
  321.                 elseif p1 == keys.right then
  322.                     movePiece(1, 0)
  323.                     draw()
  324.                 elseif p1 == keys.down then
  325.                     movePiece(0, 1)
  326.                     draw()
  327.                 elseif p1 == keys.up then
  328.                     rotatePiece()
  329.                     draw()
  330.                 elseif p1 == keys.space then
  331.                     dropPiece()
  332.                     break
  333.                 elseif p1 == keys.q then
  334.                     return
  335.                 end
  336.             elseif event == "timer" and p1 == timer then
  337.                 break
  338.             end
  339.         end
  340.        
  341.         if not gameOver then
  342.             if not movePiece(0, 1) then
  343.                 lockPiece()
  344.                 clearLines()
  345.                 spawnPiece()
  346.             end
  347.         end
  348.     end
  349. end
  350.  
  351. run()
  352.  
Advertisement
Add Comment
Please, Sign In to add comment