AnonymusHochgenuss

tetris

Apr 12th, 2026
26
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.33 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 == 30 or key == 203 then -- движение фигуры влево
  276. figurePosX = figurePosX - 1
  277.  
  278. elseif key == 32 or key == 205 then --движение фигуры вправо
  279. figurePosX = figurePosX + 1
  280.  
  281. --end
  282. elseif key == 57 or key == 28 or key == 200 then -- поворот фигуры
  283. figureRotateNumber = ((#figure[figureNum] > figureRotateNumber ) and figureRotateNumber + 1) or 1 -- если массив фигур больше figureRotateNumber,то увеличеваем его на 1,если нет то сбрасываем на 1
  284. elseif key == 31 or key == 208 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 == 25 then -- кнопка P
  374. gameState = PAUSE
  375. elseif key == 14 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.  
Add Comment
Please, Sign In to add comment