Guest User

tetris

a guest
Apr 12th, 2026
25
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 16.93 KB | None | 0 0
  1.  
  2. --ComputerCraft
  3. --Tetris v 1.0
  4. --© dzanis 12.07.12
  5.  
  6.  
  7. local w,h = term.getSize()
  8. local sX = w / 2 - 10/2 -- X позиция стакана
  9. local sY = 1 -- Y позиция стакана
  10. local iX = 2 -- X позиция инфы
  11. local iY = 2 -- Y позиция инфы
  12.  
  13. local matrix = {} -- стакан 10x20
  14. for p = 1 ,200 do -- инициализирую 200 ячеек
  15. matrix[p] = 0
  16. end
  17.  
  18.  local figurePosX = 4 -- позиция фигуры в стакане
  19.  local figurePosY = 1 --позиция фигуры в стакане
  20.  local figureNum = 1 -- номер  Ñ„игуры
  21.  local figureNextNum = math.random(1,7) -- случайный выбор  Ñ„игуры
  22.  local figureRotateNumber = 1 --номер положения фигуры
  23.  
  24.  --координаты квадратиков фигур по осям (x,y)
  25.    local figure = {
  26.         {{0,0,1,0,0,1,1,1}},--фигура квадрат
  27.         {{0,1,1,1,2,1,1,2},{1,0,0,1,1,1,1,2},{1,0,0,1,1,1,2,1},{1,0,1,1,2,1,1,2}},--фигура по форме буквы "Т"
  28.         {{1,0,1,1,1,2,2,2},{0,1,1,1,2,1,0,2},{0,0,1,0,1,1,1,2},{2,0,0,1,1,1,2,1}},--фигура по форме буквы "L"
  29.         {{1,0,1,1,1,2,0,2},{0,0,0,1,1,1,2,1},{1,0,2,0,1,1,1,2},{0,1,1,1,2,1,2,2}},--фигура по форме буквы "L" зеркально
  30.         {{0,1,1,1,1,2,2,2},{1,0,0,1,1,1,0,2}},--фигура по форме буквы "Z"
  31.         {{1,1,2,1,0,2,1,2},{0,0,0,1,1,1,1,2}},--фигура по форме буквы "Z" зеркально
  32.         {{0,2,1,2,2,2,3,2},{1,0,1,1,1,2,1,3}} --фигура по форме буквы "I"
  33.     }
  34.    
  35. local run = true
  36. local FIRST = 1
  37. local PAUSE = 2
  38. local GAME_OVER = 3
  39. local GAME = 4
  40. local gameState = FIRST -- выключатель режимов 1 начало,2 пауза , 3 проигрыш
  41. local speed = 1.0 -- скорость игры 
  42. local SCORE = 0 --очки
  43. local LINES = 0 --счётчик линий
  44. local LEVEL = 0 --уровень игры
  45.  
  46.    
  47. --прорисовка инфы
  48. local function paintInfa()
  49.    
  50.  
  51.     y = iY
  52.    
  53.     --прорисовка информации
  54.     term.setCursorPos(iX,y)
  55.     term.write("Score : " .. SCORE)
  56.     y = y + 1
  57.     term.setCursorPos(iX,y)
  58.     term.write("Lines : " .. LINES)
  59.     y = y + 1
  60.     term.setCursorPos(iX,y)
  61.     term.write("Level : " .. LEVEL)
  62.     term.setCursorPos(iX,h - 2)
  63.     term.write("ComputerCraft")
  64.     term.setCursorPos(iX,h - 1)
  65.     term.write("Tetris")
  66.     term.setCursorPos(iX,h)
  67.     term.write("dzanis 12.07.12")
  68.    
  69. --прорисовка следуюшей фигуры
  70.  
  71.         for i = 1,8,2 do
  72.             term.setCursorPos(sX - 5 + figure[figureNextNum][1][i], iY + figure[figureNextNum][1][i + 1])
  73.             term.write("0")
  74.         end
  75.  
  76.  
  77.  return
  78. end
  79.  
  80. local helpText = {  "",
  81.                     "------HELP-----",
  82.                     "",
  83.                     "Right:  -> or D",
  84.                     "---------------",
  85.                     "Left: <- or A",
  86.                     "---------------",
  87.                     "Rotate:",
  88.                     " space or enter",
  89.                     "---------------",
  90.                     "Pause: P",
  91.                     "---------------",
  92.                     "Exit game:",
  93.                     "     back space",
  94.                     "",
  95.                     "---------------",
  96.                     }
  97.  
  98. --прорисовка хелпа управления
  99. local function paintText()
  100.    
  101.     y = 1
  102.     x = sX + 14
  103.    
  104.     --прорисовка информации
  105.     while #helpText > y - 1 do
  106.     term.setCursorPos(x,y)
  107.     term.write(helpText[y])
  108.     y = y + 1
  109.     end
  110.  return
  111. end
  112.  
  113.  
  114.    
  115. --прорисовка фигур в стакане
  116. local function paintMatrix()
  117.  
  118.  
  119. -- прорисовка фона стакана
  120. for y = 0,17 do
  121. term.setCursorPos(sX,sY + y)
  122. term.write("|..........|")
  123. end
  124.  
  125. local pos = 21 --начинаю прорисовывать с 21-го (эфект вылезания фигур из потолка)
  126.  
  127. --прорисовка стакана с кубиками
  128.     for y = sY,18 do
  129.             for x = 1 + sX , 10 + sX do
  130.                 if matrix[pos] ~= 0 then --если не пусто
  131.                 term.setCursorPos(x,y)
  132.                 term.write("0")
  133.                 end
  134.                 if  matrix[pos] == -1 then matrix[pos] = 0 end -- обнуление ячейки падаюшей фигуры              
  135.                
  136.                
  137.             pos = pos + 1
  138.         end
  139.  
  140.     end
  141.    
  142.  
  143. end
  144.  
  145.  
  146. --даём добро на передвижение-поворот фигуры если:
  147.     --1.фигура не выходит за пределы стакана
  148.     --2.фигуре не мешают кубики
  149.     --так же используется для проверки на упор фигуры в дно стакана или в замороженные кубики
  150. local function canMove()
  151.  
  152.   for i = 1,8,2 do
  153.             x = figurePosX + figure[figureNum][figureRotateNumber][i];
  154.             y = figurePosY + (figure[figureNum][figureRotateNumber][i+1] * 10);
  155.             if x < 0 or x > 9 or x+y > 200 or x+y < 1 then --не выходит ли фигура за пределы стакана
  156.                 return false
  157.             end
  158.            
  159.             if matrix[x+y] == 1 then --не мешают ли фигуре кубики
  160.                 return false;
  161.                 end
  162.         end
  163.        
  164.       return true
  165. end
  166.  
  167. local function newFigure()
  168.      
  169.     figurePosX = 4 -- позиция фигуры в стакане
  170.     figurePosY = 1 --позиция фигуры в стакане
  171.     figureRotateNumber = 1 --номер положения фигуры
  172.  
  173.     figureNum = figureNextNum
  174.     figureNextNum = math.random(1,7) -- случайный выбор следуюшей фигуры
  175.  
  176. return
  177. end
  178.  
  179.  
  180. --записываю фигуру в массив поля
  181.     --(kube = 1)- замороженная фигура(достигшая дна), (kube = -1) - падающая фигура
  182.  local function    insertFigureToMatrix()
  183.       local kube,pos, linesCount, count,len = 0
  184.       if canMove() then  
  185.         kube = -1
  186.         else --если фигура уперается то замораживаю её
  187.             figurePosY = figurePosY - 10 --позицию возврашяю для исключения выхода за пределы массива или наложения фигуры на замороженные кубики
  188.             kube = 1;
  189.        end
  190.        
  191.         --записываю фигуру в массив поля
  192.         for i = 1,8,2 do  
  193.        
  194.           pos = figurePosX + figure[figureNum][figureRotateNumber][i] + figurePosY + (figure[figureNum][figureRotateNumber][i+1] * 10)
  195.             matrix[pos] = kube
  196.             --print(pos)
  197.         end
  198.        
  199.        
  200.         pos = 21 --начинаю проверять с 21-й ячейки
  201.         linesCount = 0 -- счётчик удалённых линий
  202.         --проверка есть ли полные горизонтальные линии
  203.     for y = 1,18 do
  204.             count = 0 -- счётчик замороженных ячеек
  205.            
  206.         for x = 1 , 10  do
  207.        
  208.                 if(matrix[pos] == 1) then --если ячейка заморожена то увеличиваем счётчик
  209.                         count = count + 1
  210.                 end
  211.                
  212.                
  213.             if y == 1  and count > 0 then --если есть замороженая ячейка в самой верхней линии то игра закончена
  214.                         gameState = GAME_OVER
  215.                     end
  216.    
  217.    
  218.                         if count == 10 then  --если в линии 10-ть замороженных ячеек то она  Ð·Ð°Ð¿Ð¾Ð»Ð½ÐµÐ½Ð° и её надо удалить
  219.                             linesCount = linesCount + 1
  220.                             --удаление линии из стакана путём перезаписывания ячеек верхней линии в нижнию
  221.                             len = pos
  222.                             while len > 31 do
  223.                                 for i = len,len - 10,-1 do  matrix[i] = matrix[i - 10] end
  224.                                 len = len - 10                             
  225.                             end
  226.                                 --перерисовываю стакан с задержкой                          
  227.                                 paintMatrix()
  228.                                 sleep(0.1)
  229.                         end
  230.         pos = pos + 1
  231.            
  232.         end
  233.            
  234.        
  235.     end
  236.        
  237.        
  238.            
  239.            
  240.         -- если были стёрты линии обновляем инфу
  241.         if linesCount > 0 then
  242.             LINES = LINES + linesCount --увеличиваем счётчик линий
  243.             LEVEL = math.floor (LINES / 10) --уровень игры зависит от количества стёртых линий  ,10 линий 1 уровень ,20 линий 2й уровень и т.д.
  244.             --присуждаем очки за количество удалённых линий,и уровня
  245.             --очки за количество удалённых линий за раз,за одну 10,за две 50 и т.д
  246.                 local bonus = {10,50,100,200}
  247.                 SCORE = SCORE + bonus[linesCount]
  248.         end
  249.          
  250.         if kube == 1 then --если фигура зоморожена создаю новую
  251.                 newFigure()
  252.             end
  253.            
  254.         return
  255.     end
  256.  
  257.  
  258.    
  259.  
  260. local timer = os.startTimer(0)
  261. local event, p1, p2 = nil
  262.  
  263. local function game()
  264.  
  265.  --временно сохраняю текущую позицию фигуры
  266.          previosfigureRotateNumber = figureRotateNumber;
  267.          previosfigurePosX = figurePosX;
  268.          previosfigurePosY = figurePosY;
  269.  
  270.    
  271.    
  272.         if event == "key" then -- если нажата какая либо кнопка
  273.             local key = p1
  274.    
  275.             if key == 83 or key == 263 then -- движение фигуры влево
  276.                 figurePosX = figurePosX - 1
  277.        
  278.             elseif key == 68 or key == 262 then --движение фигуры вправо
  279.             figurePosX = figurePosX + 1
  280.        
  281.             --end  
  282.             elseif key == 32 or key == 257 then -- поворот фигуры
  283.             figureRotateNumber =  ((#figure[figureNum] > figureRotateNumber  ) and figureRotateNumber + 1) or 1 -- если массив фигур больше figureRotateNumber,то увеличеваем его на 1,если нет то сбрасываем на 1
  284.             elseif key == 87 or key == 265 then  -- вниз
  285.             figurePosY = figurePosY + 10
  286.             end
  287.            
  288.            
  289.                
  290.                
  291.         end
  292.        
  293.    
  294.    
  295.    
  296.             if canMove() ~= true then -- если двигать крутить нельзя то возврашяю прежнию позицию фигуры
  297.                 figureRotateNumber = previosfigureRotateNumber
  298.                 figurePosX = previosfigurePosX
  299.                 figurePosY = previosfigurePosY
  300.             end
  301.        
  302.        
  303.             -- 1 уровень speed = 1.0    2  speed = 0.9   чем меньше тем быстрее фигуры падают,и недаю скорости уменьшится меньше 0.3
  304.             speed =  ((speed > 0.1) and 1.0 - LEVEL/10) or 0.1
  305.            
  306.    
  307.         if event == "timer" and p1 == timer then -- здесь задаётся скорость падения фигур в зависимости от уровня
  308.             timer = os.startTimer(speed)
  309.              figurePosY = figurePosY + 10          
  310.         end    
  311.    
  312.        
  313.    
  314.     return
  315. end
  316.  
  317.  
  318.  -- новая игра
  319. local function newGame()
  320.     SCORE = 0
  321.     LINES = 0
  322.     LEVEL = 0
  323.     for p = 1 ,200 do matrix[p] = 0  end -- очистка
  324.     newFigure()
  325.     return
  326. end
  327.  
  328. -- диалог предлагаюший продолжить
  329. flashing = true
  330. local function paintDialog()
  331.     local text = { 
  332.                 {" WELKOME TETRIS",
  333.                  "   P A U S E",
  334.                 "G A M E  O V E R",
  335.                  "  PLAY TETRIS" },
  336.                  
  337.                 {"   to start",
  338.                  "   to rezume",
  339.                  "   to start",
  340.                  "" },   
  341.                
  342.             }
  343.                
  344.     term.setCursorPos(iX,h/2)
  345.     term.write(text[1][gameState])
  346.  
  347.     if flashing and gameState ~= GAME  then
  348.     term.setCursorPos(iX,h/2 + 2)
  349.     term.write(" Press any key")
  350.     term.setCursorPos(iX,h/2 + 3)
  351.     term.write(text[2][gameState])
  352.     end
  353.     if event == "timer" and p1 == timer then -- здесь задаётся скорость моргалки
  354.             timer = os.startTimer(0.5)
  355.              flashing = flashing ~= true               
  356.         end
  357.    
  358.     return
  359.     end
  360.  
  361.    
  362. -- здесь начинается игра
  363. newGame()
  364.  
  365. while run do
  366.  
  367.  
  368.     event, p1, p2 = os.pullEvent()
  369.    
  370.    
  371.     if event == "key" then -- если нажата какая либо кнопка
  372.             local key = p1     
  373.     if  key == 80 then -- кнопка P
  374.         gameState = PAUSE
  375.     elseif  key == 259 then -- кнопка back space
  376.         run = false
  377.     elseif key > 1 and gameState ~= GAME then -- если нажата любая кнопка  ÐºÑ€Ð¾Ð¼Ðµ Escape
  378.                 if gameState == GAME_OVER then newGame()  end
  379.                 gameState = GAME
  380.                 timer = os.startTimer(0)   
  381.         end
  382.     end
  383.    
  384.     if gameState == GAME then  
  385.         game()
  386.     end
  387.  
  388.     insertFigureToMatrix()
  389.     term.clear() --очистка терминала
  390.     paintMatrix()
  391.     paintInfa()
  392.     paintText()
  393.     paintDialog()
  394.    
  395.    
  396.    
  397.    
  398.        
  399.  
  400. end
  401.  
  402. term.clear() --очистка терминала
  403. term.setCursorPos(1,1)
  404.  
  405.  
  406.  
  407.  
  408.  
  409.  
  410.  
  411.  
  412.  
  413.  
  414.  
Advertisement
Add Comment
Please, Sign In to add comment