Advertisement
nonogamer9

TETRIS For ComputerCraft (Coded By me)

Sep 15th, 2024
341
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 12.66 KB | Software | 0 0
  1. local w, h = term.getSize()
  2. local boardWidth, boardHeight = 10, 20
  3. local offsetX, offsetY = math.floor((w - boardWidth) / 2), math.floor((h - boardHeight) / 2)
  4.  
  5. local settings = {
  6.   plasmaEnabled = true,
  7.   difficulty = 2
  8. }
  9.  
  10. local pieces = {
  11.   {{{0,0},{1,0},{0,1},{1,1}}},
  12.   {{{0,0},{1,0},{2,0},{3,0}}, {{0,0},{0,1},{0,2},{0,3}}},
  13.   {{{0,0},{1,0},{2,0},{2,1}}, {{1,0},{1,1},{1,2},{0,2}}, {{0,0},{0,1},{1,1},{2,1}}, {{0,0},{1,0},{0,1},{0,2}}},
  14.   {{{0,0},{1,0},{2,0},{0,1}}, {{0,0},{1,0},{1,1},{1,2}}, {{2,0},{0,1},{1,1},{2,1}}, {{0,0},{0,1},{0,2},{1,2}}},
  15.   {{{1,0},{2,0},{0,1},{1,1}}, {{0,0},{0,1},{1,1},{1,2}}},
  16.   {{{0,0},{1,0},{1,1},{2,1}}, {{1,0},{0,1},{1,1},{0,2}}},
  17.   {{{1,0},{0,1},{1,1},{2,1}}, {{0,0},{0,1},{1,1},{0,2}}, {{0,0},{1,0},{2,0},{1,1}}, {{1,0},{0,1},{1,1},{1,2}}}
  18. }
  19.  
  20. local pieceColors = {
  21.   colors.red,
  22.   colors.blue,
  23.   colors.green,
  24.   colors.yellow,
  25.   colors.magenta,
  26.   colors.cyan,
  27.   colors.white
  28. }
  29.  
  30. local plasmaColors = {
  31.   colors.red,
  32.   colors.orange,
  33.   colors.yellow,
  34.   colors.lime,
  35.   colors.green,
  36.   colors.cyan,
  37.   colors.lightBlue,
  38.   colors.blue,
  39.   colors.purple,
  40.   colors.magenta,
  41.   colors.pink,
  42.   colors.brown,
  43.   colors.white,
  44.   colors.lightGray,
  45.   colors.gray,
  46.   colors.black
  47. }
  48.  
  49. local board = {}
  50. local currentPiece = nil
  51. local currentPieceColor = 1
  52. local currentRotation = 1
  53. local currentX, currentY = 0, 0
  54. local score = 0
  55. local gameOver = false
  56. local plasmaBuffer = {}
  57.  
  58. for y = 1, boardHeight do
  59.   board[y] = {}
  60.   for x = 1, boardWidth do
  61.     board[y][x] = 0
  62.   end
  63. end
  64.  
  65. for y = 1, h do
  66.   plasmaBuffer[y] = {}
  67.   for x = 1, w do
  68.     plasmaBuffer[y][x] = colors.black
  69.   end
  70. end
  71.  
  72. local function calculatePlasma(t)
  73.   for y = 1, h do
  74.     for x = 1, w do
  75.       local v = math.sin(x/4) + math.sin(y/8) + math.sin((x+y+t)/16)
  76.       local colorIndex = math.floor((v + 3) * 8) % 16 + 1
  77.       plasmaBuffer[y][x] = plasmaColors[colorIndex]
  78.     end
  79.   end
  80. end
  81.  
  82. local function drawPiece()
  83.   if not currentPiece then return end
  84.   for _, block in ipairs(pieces[currentPiece][currentRotation]) do
  85.     local x, y = currentX + block[1], currentY + block[2]
  86.     if x > 0 and x <= boardWidth and y > 0 and y <= boardHeight then
  87.       term.setCursorPos(x + offsetX, y + offsetY)
  88.       term.setBackgroundColor(pieceColors[currentPieceColor])
  89.       term.write(" ")
  90.     end
  91.   end
  92. end
  93.  
  94. local function checkCollision(pieceType, rotation, testX, testY)
  95.   if not pieceType or not rotation then return true end
  96.   for _, block in ipairs(pieces[pieceType][rotation]) do
  97.     local x, y = (testX or 0) + block[1], (testY or 0) + block[2]
  98.     if x < 1 or x > boardWidth or y > boardHeight then
  99.       return true
  100.     end
  101.     if y > 0 and board[y] and board[y][x] and board[y][x] ~= 0 then
  102.       return true
  103.     end
  104.   end
  105.   return false
  106. end
  107.  
  108. local function lockPiece()
  109.   if not currentPiece then return end
  110.   for _, block in ipairs(pieces[currentPiece][currentRotation]) do
  111.     local x, y = currentX + block[1], currentY + block[2]
  112.     if y > 0 and y <= boardHeight and x > 0 and x <= boardWidth then
  113.       board[y][x] = currentPieceColor
  114.     end
  115.   end
  116. end
  117.  
  118. local function clearLines()
  119.   local linesCleared = 0
  120.   for y = boardHeight, 1, -1 do
  121.     local full = true
  122.     for x = 1, boardWidth do
  123.       if board[y][x] == 0 then
  124.         full = false
  125.         break
  126.       end
  127.     end
  128.     if full then
  129.       linesCleared = linesCleared + 1
  130.       table.remove(board, y)
  131.       table.insert(board, 1, {})
  132.       for x = 1, boardWidth do
  133.         board[1][x] = 0
  134.       end
  135.     end
  136.   end
  137.   score = score + linesCleared * 100
  138. end
  139.  
  140. local function drawGame()
  141.   if settings.plasmaEnabled then
  142.     for y = 1, h do
  143.       for x = 1, w do
  144.         term.setCursorPos(x, y)
  145.         term.setBackgroundColor(plasmaBuffer[y][x])
  146.         term.write(" ")
  147.       end
  148.     end
  149.   else
  150.     term.setBackgroundColor(colors.black)
  151.     term.clear()
  152.   end
  153.  
  154.   for y = offsetY - 1, offsetY + boardHeight do
  155.     term.setCursorPos(offsetX - 1, y)
  156.     term.setBackgroundColor(colors.lightGray)
  157.     term.write("█")
  158.     term.setCursorPos(offsetX + boardWidth, y)
  159.     term.write("█")
  160.   end
  161.   for x = offsetX - 1, offsetX + boardWidth do
  162.     term.setCursorPos(x, offsetY - 1)
  163.     term.setBackgroundColor(colors.lightGray)
  164.     term.write("█")
  165.     term.setCursorPos(x, offsetY + boardHeight)
  166.     term.write("█")
  167.   end
  168.  
  169.   for y = 1, boardHeight do
  170.     for x = 1, boardWidth do
  171.       term.setCursorPos(x + offsetX, y + offsetY)
  172.       if board[y][x] ~= 0 then
  173.         term.setBackgroundColor(pieceColors[board[y][x]])
  174.       else
  175.         term.setBackgroundColor(colors.black)
  176.       end
  177.       term.write(" ")
  178.     end
  179.   end
  180.  
  181.   drawPiece()
  182.  
  183.   term.setCursorPos(1, 1)
  184.   term.setBackgroundColor(colors.black)
  185.   term.setTextColor(colors.white)
  186.   term.write("Score: " .. score)
  187. end
  188.  
  189. local function plasmaProcess()
  190.   local t = 0
  191.   while not gameOver do
  192.     calculatePlasma(t)
  193.     t = t + 0.1
  194.     sleep(0.05)
  195.   end
  196. end
  197.  
  198. local function gameProcess()
  199.   local difficultySpeed = {0.8, 0.5, 0.3}
  200.   while not gameOver do
  201.     if currentPiece and not checkCollision(currentPiece, currentRotation, currentX, (currentY or 0) + 1) then
  202.       currentY = (currentY or 0) + 1
  203.     else
  204.       if currentPiece then
  205.         lockPiece()
  206.         clearLines()
  207.       end
  208.       currentPiece = math.random(1, #pieces)
  209.       currentPieceColor = math.random(1, #pieceColors)
  210.       currentRotation = 1
  211.       currentX = math.floor(boardWidth / 2) - 1
  212.       currentY = 0
  213.       if checkCollision(currentPiece, currentRotation, currentX, currentY) then
  214.         gameOver = true
  215.       end
  216.     end
  217.  
  218.     drawGame()
  219.     sleep(difficultySpeed[settings.difficulty])
  220.   end
  221. end
  222.  
  223. local function inputProcess()
  224.   while not gameOver do
  225.     local event, key = os.pullEvent("key")
  226.     if currentPiece then
  227.       if key == keys.left and not checkCollision(currentPiece, currentRotation, (currentX or 0) - 1, currentY) then
  228.         currentX = (currentX or 0) - 1
  229.       elseif key == keys.right and not checkCollision(currentPiece, currentRotation, (currentX or 0) + 1, currentY) then
  230.         currentX = (currentX or 0) + 1
  231.       elseif key == keys.up then
  232.         local newRotation = currentRotation % #pieces[currentPiece] + 1
  233.         if not checkCollision(currentPiece, newRotation, currentX, currentY) then
  234.           currentRotation = newRotation
  235.         end
  236.       elseif key == keys.down then
  237.         while not checkCollision(currentPiece, currentRotation, currentX, (currentY or 0) + 1) do
  238.           currentY = (currentY or 0) + 1
  239.         end
  240.       end
  241.       drawGame()
  242.     end
  243.   end
  244. end
  245.  
  246. local function drawTitleScreen()
  247.   term.clear()
  248.   term.setCursorPos(1, 1)
  249.   term.setBackgroundColor(colors.black)
  250.   term.setTextColor(colors.white)
  251.  
  252.   local title = {
  253.     " _____ _____ ___________ _____ _____ ",
  254.     "|_   _|  ___|_   _| ___ \\_   _/  ___|",
  255.     "  | | | |__   | | | |_/ / | | \\ `--. ",
  256.     "  | | |  __|  | | |    /  | |  `--. \\",
  257.     "  | | | |___  | | | |\\ \\ _| |_/\\__/ /",
  258.     "  \\_/ \\____/  \\_/ \\_| \\_\\___/\\____/ "
  259.   }
  260.  
  261.   local startY = math.floor((h - #title) / 2) - 5
  262.   for i, line in ipairs(title) do
  263.     term.setCursorPos(math.floor((w - #line) / 2), startY + i)
  264.     term.write(line)
  265.   end
  266.  
  267.   term.setCursorPos(math.floor(w/2) - 6, startY + #title + 3)
  268.   term.write("[ Press ENTER to Start ]")
  269.  
  270.   term.setCursorPos(math.floor(w/2) - 8, startY + #title + 5)
  271.   term.write("[ Press L for Leaderboard ]")
  272.  
  273.   term.setCursorPos(math.floor(w/2) - 7, startY + #title + 7)
  274.   term.write("[ Press S for Settings ]")
  275.  
  276.   term.setCursorPos(math.floor(w/2) - 6, startY + #title + 9)
  277.   term.write("[ Press C for Credits ]")
  278.  
  279.   term.setCursorPos(math.floor(w/2) - 5, startY + #title + 11)
  280.   term.write("[ Press Q to Quit ]")
  281. end
  282.  
  283. local leaderboard = {}
  284.  
  285. local function saveScore(name, score)
  286.   table.insert(leaderboard, {name = name or "Unknown", score = score or 0})
  287.   table.sort(leaderboard, function(a, b)
  288.     return (a.score or 0) > (b.score or 0)
  289.   end)
  290.   if #leaderboard > 10 then
  291.     table.remove(leaderboard, 11)
  292.   end
  293.  
  294.   local file = fs.open("tetris_leaderboard", "w")
  295.   if file then
  296.     for _, entry in ipairs(leaderboard) do
  297.       local entryName = entry.name or "Unknown"
  298.       local entryScore = entry.score or 0
  299.       file.writeLine(entryName .. "," .. tostring(entryScore))
  300.     end
  301.     file.close()
  302.   else
  303.     print("Error: Unable to open file for writing")
  304.   end
  305. end
  306.  
  307. local function loadLeaderboard()
  308.   if fs.exists("tetris_leaderboard") then
  309.     local file = fs.open("tetris_leaderboard", "r")
  310.     if file then
  311.       while true do
  312.         local line = file.readLine()
  313.         if not line then break end
  314.         local name, score = line:match("([^,]+),(%d+)")
  315.         table.insert(leaderboard, {name = name, score = tonumber(score)})
  316.       end
  317.       file.close()
  318.     else
  319.       print("Error: Unable to open leaderboard file for reading")
  320.     end
  321.   end
  322. end
  323.  
  324. local function drawLeaderboard()
  325.   term.clear()
  326.   term.setCursorPos(1, 1)
  327.   term.setBackgroundColor(colors.black)
  328.   term.setTextColor(colors.white)
  329.  
  330.   term.setCursorPos(math.floor(w/2) - 5, 2)
  331.   term.write("LEADERBOARD")
  332.  
  333.   for i, entry in ipairs(leaderboard) do
  334.     term.setCursorPos(math.floor(w/2) - 10, i + 4)
  335.     local name = entry.name or "Unknown"
  336.     local score = entry.score or 0
  337.     term.write(string.format("%2d. %-10s %5d", i, name, score))
  338.   end
  339.  
  340.   term.setCursorPos(math.floor(w/2) - 11, h - 2)
  341.   term.write("[ Press any key to return ]")
  342.  
  343.   os.pullEvent("key")
  344. end
  345.  
  346. local function drawSettingsMenu()
  347.   local function toggleSetting(setting)
  348.     settings[setting] = not settings[setting]
  349.   end
  350.  
  351.   local function changeDifficulty()
  352.     settings.difficulty = (settings.difficulty % 3) + 1
  353.   end
  354.  
  355.   while true do
  356.     term.clear()
  357.     term.setCursorPos(1, 1)
  358.     term.setBackgroundColor(colors.black)
  359.     term.setTextColor(colors.white)
  360.    
  361.     term.setCursorPos(math.floor(w/2) - 4, 2)
  362.     term.write("SETTINGS")
  363.    
  364.     term.setCursorPos(2, 5)
  365.     term.write("1. Plasma Effect: " .. (settings.plasmaEnabled and "ON" or "OFF"))
  366.    
  367.     term.setCursorPos(2, 7)
  368.     local difficultyText = {"Easy", "Normal", "Hard"}
  369.     term.write("2. Difficulty: " .. difficultyText[settings.difficulty])
  370.    
  371.     term.setCursorPos(2, 9)
  372.     term.write("3. Back to Main Menu")
  373.    
  374.     term.setCursorPos(2, h-1)
  375.     term.write("Enter your choice (1-3): ")
  376.    
  377.     local _, key = os.pullEvent("key")
  378.     if key == keys.one then
  379.       toggleSetting("plasmaEnabled")
  380.     elseif key == keys.two then
  381.       changeDifficulty()
  382.     elseif key == keys.three then
  383.       break
  384.     end
  385.   end
  386. end
  387.  
  388. local function drawCredits()
  389.   term.clear()
  390.   term.setCursorPos(1, 1)
  391.   term.setBackgroundColor(colors.black)
  392.   term.setTextColor(colors.white)
  393.  
  394.   term.setCursorPos(math.floor(w/2) - 3, 2)
  395.   term.write("CREDITS")
  396.  
  397.   local credits = {
  398.     "Inspired from XIXIT (effects)",
  399.     "Based on the classic Tetris game",
  400.     "For ComputerCraft",
  401.     "Special Thanks For the ComputerCraft Community",
  402.     "© 2024 nonogamer9"
  403.   }
  404.  
  405.   local startY = math.floor((h - #credits) / 2)
  406.   for i, line in ipairs(credits) do
  407.     term.setCursorPos(math.floor((w - #line) / 2), startY + i)
  408.     term.write(line)
  409.   end
  410.  
  411.   term.setCursorPos(math.floor(w/2) - 11, h - 2)
  412.   term.write("[ Press any key to return ]")
  413.  
  414.   os.pullEvent("key")
  415. end
  416.  
  417. loadLeaderboard()
  418.  
  419. local running = true
  420. while running do
  421.   drawTitleScreen()
  422.  
  423.   local event, key = os.pullEvent("key")
  424.   if key == keys.enter then
  425.     currentPiece = math.random(1, #pieces)
  426.     currentPieceColor = math.random(1, #pieceColors)
  427.     currentRotation = 1
  428.     currentX = math.floor(boardWidth / 2) - 1
  429.     currentY = 0
  430.     score = 0
  431.     gameOver = false
  432.    
  433.     for y = 1, boardHeight do
  434.       for x = 1, boardWidth do
  435.         board[y][x] = 0
  436.       end
  437.     end
  438.    
  439.     parallel.waitForAll(plasmaProcess, gameProcess, inputProcess)
  440.    
  441.     term.clear()
  442.     term.setCursorPos(1, h/2 - 1)
  443.     term.setTextColor(colors.white)
  444.     term.setBackgroundColor(colors.black)
  445.     term.write("Game Over! Final Score: " .. score)
  446.     term.setCursorPos(1, h/2 + 1)
  447.     term.write("Enter your name: ")
  448.     local name = read()
  449.     saveScore(name, score)
  450.   elseif key == keys.l then
  451.     drawLeaderboard()
  452.   elseif key == keys.s then
  453.     drawSettingsMenu()
  454.   elseif key == keys.c then
  455.     drawCredits()
  456.   elseif key == keys.q then
  457.     term.clear()
  458.     term.setCursorPos(1, h/2)
  459.     term.setTextColor(colors.white)
  460.     term.setBackgroundColor(colors.black)
  461.     term.write("Thanks for playing Tetris! Goodbye!")
  462.     sleep(2)
  463.     running = false
  464.   end
  465. end
  466.  
  467. term.clear()
  468. term.setCursorPos(1, 1)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement