Creeper9207

tetrisPORTALS

Feb 7th, 2015
290
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 14.97 KB | None | 0 0
  1. --[[
  2. Falling - Based on Tetris by Alexey Pajitnov
  3. This version written by Gopher, at the request of Dan200, for
  4. ComputerCraft v1.6. No particular rights are reserved.
  5. --]]
  6.  
  7. local function colorass(c,bw)
  8.   return term.isColor() and c or bw
  9. end
  10.  
  11. local block_s1= {
  12.     {
  13.       { 1,0,0,0, },
  14.       { 1,1,0,0, },
  15.       { 0,1,0,0, },
  16.       { 0,0,0,0, },
  17.     },
  18.     {
  19.       { 0,0,0,0, },
  20.       { 0,1,1,0, },
  21.       { 1,1,0,0, },
  22.       { 0,0,0,0, },
  23.     },
  24.     ch=colorass("  ","{}"),
  25.     fg=colorass(colors.blue,colors.black),
  26.     bg=colorass(colors.cyan,colors.white),
  27.   }
  28. local block_s2= {
  29.     {
  30.       { 0,1,0,0, },
  31.       { 1,1,0,0, },
  32.       { 1,0,0,0, },
  33.       { 0,0,0,0, },
  34.     },
  35.     {
  36.       { 0,0,0,0, },
  37.       { 1,1,0,0, },
  38.       { 0,1,1,0, },
  39.       { 0,0,0,0, },
  40.     },
  41.     ch=colorass("  ","{}"),
  42.     fg=colorass(colors.green,colors.black),
  43.     bg=colorass(colors.lime,colors.white),
  44.   }
  45. local block_line = {
  46.     {
  47.       { 0,1,0,0, },
  48.       { 0,1,0,0, },
  49.       { 0,1,0,0, },
  50.       { 0,1,0,0, },
  51.     },
  52.     {
  53.       { 0,0,0,0, },
  54.       { 1,1,1,1, },
  55.       { 0,0,0,0, },
  56.       { 0,0,0,0, },
  57.     },
  58.     ch=colorass("  ","[]"),
  59.     fg=colorass(colors.pink,colors.black),
  60.     bg=colorass(colors.red,colors.white),
  61.   }
  62. local block_square = {
  63.     {
  64.       { 1,1,0,0, },
  65.       { 1,1,0,0, },
  66.       { 0,0,0,0, },
  67.       { 0,0,0,0, },
  68.     },
  69.     ch=colorass("  ","[]"),
  70.     fg=colorass(colors.lightBlue,colors.black),
  71.     bg=colorass(colors.blue,colors.white),
  72.   }
  73. local block_L1 = {
  74.     {
  75.       { 1,1,0,0, },
  76.       { 0,1,0,0, },
  77.       { 0,1,0,0, },
  78.       { 0,0,0,0, },
  79.     },
  80.     {
  81.       { 0,0,0,0, },
  82.       { 1,1,1,0, },
  83.       { 1,0,0,0, },
  84.       { 0,0,0,0, },
  85.     },
  86.     {
  87.       { 0,1,0,0, },
  88.       { 0,1,0,0, },
  89.       { 0,1,1,0, },
  90.       { 0,0,0,0, },
  91.     },
  92.     {
  93.       { 0,0,1,0, },
  94.       { 1,1,1,0, },
  95.       { 0,0,0,0, },
  96.       { 0,0,0,0, },
  97.     },
  98.     ch=colorass("  ","()"),
  99.     fg=colorass(colors.orange,colors.black),
  100.     bg=colorass(colors.yellow,colors.white),
  101.   }
  102. local block_L2 = {
  103.     {
  104.       { 0,1,0,0, },
  105.       { 0,1,0,0, },
  106.       { 1,1,0,0, },
  107.       { 0,0,0,0, },
  108.     },
  109.     {
  110.       { 0,0,0,0, },
  111.       { 1,1,1,0, },
  112.       { 0,0,1,0, },
  113.       { 0,0,0,0, },
  114.     },
  115.     {
  116.       { 0,1,1,0, },
  117.       { 0,1,0,0, },
  118.       { 0,1,0,0, },
  119.       { 0,0,0,0, },
  120.     },
  121.     {
  122.       { 1,0,0,0, },
  123.       { 1,1,1,0, },
  124.       { 0,0,0,0, },
  125.       { 0,0,0,0, },
  126.     },
  127.     ch=colorass("  ","()"),
  128.     fg=colorass(colors.brown,colors.black),
  129.     bg=colorass(colors.orange,colors.white),
  130.   }
  131. local block_T = {
  132.     {
  133.       { 0,1,0,0, },
  134.       { 1,1,0,0, },
  135.       { 0,1,0,0, },
  136.       { 0,0,0,0, },
  137.     },
  138.     {
  139.       { 0,0,0,0, },
  140.       { 1,1,1,0, },
  141.       { 0,1,0,0, },
  142.       { 0,0,0,0, },
  143.     },
  144.     {
  145.       { 0,1,0,0, },
  146.       { 0,1,1,0, },
  147.       { 0,1,0,0, },
  148.       { 0,0,0,0, },
  149.     },
  150.     {
  151.       { 0,1,0,0, },
  152.       { 1,1,1,0, },
  153.       { 0,0,0,0, },
  154.       { 0,0,0,0, },
  155.     },
  156.     ch=colorass("  ","<>"),
  157.     fg=colorass(colors.cyan,colors.black),
  158.     bg=colorass(colors.purple,colors.white),
  159.   }
  160.  
  161. local blocks={ block_line, block_square, block_s1, block_s2, block_L1, block_L2, block_T}
  162.  
  163. local points={4,10,30,120}
  164.  
  165. local function lpad(text,amt)
  166.   text=tostring(text)
  167.   return string.rep(" ",amt-#text)..text
  168. end
  169.  
  170. local width,height=term.getSize()
  171.  
  172. if height<19 or width<26 then
  173.   print("Your screen is too small to play :(")
  174.   return
  175. end
  176.  
  177.  
  178. local speedsByLevel={
  179.   1.2,
  180.   1.0,
  181.    .8,
  182.    .65,
  183.    .5,
  184.    .4,
  185.    .3,
  186.    .25,
  187.    .2,
  188.    .15,
  189.    .1,
  190.    .05,}
  191.  
  192. local level=1
  193.  
  194. local function playGame()
  195.   local score=0
  196.   local lines=0
  197.   local initialLevel=level
  198.   local next=blocks[math.random(1,#blocks)]
  199.  
  200.   local pit={}
  201.  
  202.  
  203.   local heightAdjust=0
  204.  
  205.   if height<=19 then
  206.     heightAdjust=1
  207.   end
  208.  
  209.  
  210.  
  211.   local function drawScreen()
  212.     term.setTextColor(colors.white)
  213.     term.setBackgroundColor(colors.black)
  214.     term.clear()
  215.  
  216.     term.setTextColor(colors.black)
  217.     term.setBackgroundColor(colorass(colors.lightGray, colors.white))
  218.     term.setCursorPos(22,2)
  219.     term.write("Score") --score
  220.     term.setCursorPos(22,5)
  221.     term.write("Level")  --level
  222.     term.setCursorPos(22,8)
  223.     term.write("Lines")  --lines
  224.     term.setCursorPos(22,12)
  225.     term.write("Next") --next
  226.  
  227.     term.setCursorPos(21,1)
  228.     term.write("      ")
  229.     term.setCursorPos(21,2)
  230.     term.write(" ") --score
  231.     term.setCursorPos(21,3)
  232.     term.write(" ")
  233.     term.setCursorPos(21,4)
  234.     term.write("      ")
  235.     term.setCursorPos(21,5)
  236.     term.write(" ")  --level
  237.     term.setCursorPos(21,6)
  238.     term.write(" ")
  239.     term.setCursorPos(21,7)
  240.     term.write("      ")
  241.     term.setCursorPos(21,8)
  242.     term.write(" ")  --lines
  243.     term.setCursorPos(21,9)
  244.     term.write(" ")
  245.     term.setCursorPos(21,10)
  246.     term.write("      ")
  247.     term.setCursorPos(21,11)
  248.     term.write("      ")
  249.     term.setCursorPos(21,12)
  250.     term.write(" ") --next
  251.     term.setCursorPos(26,12)
  252.     term.write(" ") --next
  253.     term.setCursorPos(21,13)
  254.     term.write("      ")
  255.     term.setCursorPos(21,14)
  256.     term.write(" ")
  257.     term.setCursorPos(21,15)
  258.     term.write(" ")
  259.     term.setCursorPos(21,16)
  260.     term.write(" ")
  261.     term.setCursorPos(21,17)
  262.     term.write(" ")
  263.     term.setCursorPos(21,18)
  264.     term.write(" ")
  265.     term.setCursorPos(21,19)
  266.     term.write("      ")
  267.     term.setCursorPos(21,20)
  268.     term.write("      ")
  269.   end
  270.  
  271.   local function updateNumbers()
  272.     term.setTextColor(colors.white)
  273.     term.setBackgroundColor(colors.black)
  274.  
  275.     term.setCursorPos(22,3)
  276.     term.write(lpad(score,5)) --score
  277.     term.setCursorPos(22,6)
  278.     term.write(lpad(level,5))  --level
  279.     term.setCursorPos(22,9)
  280.     term.write(lpad(lines,5))  --lines
  281.   end
  282.  
  283.   local function drawBlockAt(block,xp,yp,rot)
  284.     term.setTextColor(block.fg)
  285.     term.setBackgroundColor(block.bg)
  286.     for y=1,4 do
  287.       for x=1,4 do
  288.         if block[rot][y][x]==1 then
  289.           term.setCursorPos((xp+x)*2-3,yp+y-1-heightAdjust)
  290.           term.write(block.ch)
  291.         end
  292.       end
  293.     end
  294.   end
  295.  
  296.   local function eraseBlockAt(block,xp,yp,rot)
  297.     term.setTextColor(colors.white)
  298.     term.setBackgroundColor(colors.black)
  299.     for y=1,4 do
  300.       for x=1,4 do
  301.         if block[rot][y][x]==1 then
  302.           term.setCursorPos((xp+x)*2-3,yp+y-1-heightAdjust)
  303.           term.write("  ")
  304.         end
  305.       end
  306.     end
  307.   end
  308.  
  309.   local function testBlockAt(block,xp,yp,rot)
  310.     for y=1,4 do
  311.       local ty=yp+y-1
  312.       for x=1,4 do
  313.         local tx=xp+x-1
  314.         if block[rot][y][x]==1 then
  315.           if tx>10 or tx<1 or ty>20 or pit[ty][tx]~=0 then
  316.             return true
  317.           end
  318.         end
  319.       end
  320.     end
  321.   end
  322.  
  323.   local function pitBlock(block,xp,yp,rot)
  324.     for y=1,4 do
  325.       for x=1,4 do
  326.         if block[rot][y][x]==1 then
  327.           pit[yp+y-1][xp+x-1]=block
  328.         end
  329.       end
  330.     end
  331.   end
  332.  
  333.  
  334.   local function clearPit()
  335.     for row=1,20 do
  336.       pit[row]={}
  337.       for col=1,10 do
  338.         pit[row][col]=0
  339.       end
  340.     end
  341.   end
  342.  
  343.  
  344.  
  345.   drawScreen()
  346.   updateNumbers()
  347.  
  348.   --declare & init the pit
  349.   clearPit()
  350.  
  351.  
  352.  
  353.   local halt=false
  354.   local dropSpeed=speedsByLevel[math.min(level,12)]
  355.  
  356.  
  357.   local curBlock=next
  358.   next=blocks[math.random(1,7)]
  359.  
  360.   local curX, curY, curRot=4, 1, 1
  361.   local dropTimer=os.startTimer(dropSpeed)
  362.  
  363.   drawBlockAt(next,11.5,15+heightAdjust,1)
  364.   drawBlockAt(curBlock,curX,curY,curRot)
  365.  
  366.   local function redrawPit()
  367.     for r=1+heightAdjust,20 do
  368.       term.setCursorPos(1,r-heightAdjust)
  369.       for c=1,10 do
  370.         if pit[r][c]==0 then
  371.           term.setTextColor(colors.black)
  372.           term.setBackgroundColor(colors.black)
  373.           term.write("  ")
  374.         else
  375.           term.setTextColor(pit[r][c].fg)
  376.           term.setBackgroundColor(pit[r][c].bg)
  377.           term.write(pit[r][c].ch)
  378.         end
  379.       end
  380.     end
  381.   end
  382.  
  383.   local function hidePit()
  384.     for r=1+heightAdjust,20 do
  385.       term.setCursorPos(1,r-heightAdjust)
  386.       term.setTextColor(colors.black)
  387.       term.setBackgroundColor(colors.black)
  388.       term.write("                    ")
  389.     end
  390.   end
  391.  
  392.   local function msgBox(message)
  393.     local x=math.floor((17-#message)/2)
  394.     term.setBackgroundColor(colorass(colors.lightGray,colors.white))
  395.     term.setTextColor(colors.black)
  396.     term.setCursorPos(x,9)
  397.     term.write("+"..string.rep("-",#message+2).."+")
  398.     term.setCursorPos(x,10)
  399.     term.write("|")
  400.     term.setCursorPos(x+#message+3,10)
  401.     term.write("|")
  402.     term.setCursorPos(x,11)
  403.     term.write("+"..string.rep("-",#message+2).."+")
  404.     term.setTextColor(colors.white)
  405.     term.setBackgroundColor(colors.black)
  406.     term.setCursorPos(x+1,10)
  407.     term.write(" "..message.." ")
  408.   end
  409.  
  410.   local function clearRows()
  411.     local rows={}
  412.     for r=1,20 do
  413.       local count=0
  414.       for c=1,10 do
  415.         if pit[r][c]~=0 then
  416.           count=count+1
  417.         else
  418.           break
  419.         end
  420.       end
  421.       if count==10 then
  422.         rows[#rows+1]=r
  423.       end
  424.     end
  425.  
  426.     if #rows>0 then
  427.       for i=1,4 do
  428.         sleep(.1)
  429.         for r=1,#rows do
  430.           r=rows[r]
  431.           term.setCursorPos(1,r-heightAdjust)
  432.           for c=1,10 do
  433.             term.setTextColor(pit[r][c].bg)
  434.             term.setBackgroundColor(pit[r][c].fg)
  435.             term.write(pit[r][c].ch)
  436.           end
  437.         end
  438.         sleep(.1)
  439.         for r=1,#rows do
  440.           r=rows[r]
  441.           term.setCursorPos(1,r-heightAdjust)
  442.           for c=1,10 do
  443.             term.setTextColor(pit[r][c].fg)
  444.             term.setBackgroundColor(pit[r][c].bg)
  445.             term.write(pit[r][c].ch)
  446.           end
  447.         end
  448.       end
  449.       --now remove the rows and drop everythign else
  450.       term.setBackgroundColor(colors.black)
  451.       for r=1,#rows do
  452.         r=rows[r]
  453.         term.setCursorPos(1,r-heightAdjust)
  454.         term.write("                    ")
  455.       end
  456.       sleep(.25)
  457.       for r=1,#rows do
  458.         table.remove(pit,rows[r])
  459.         table.insert(pit,1,{0,0,0,0,0,0,0,0,0,0})
  460.       end
  461.       redrawPit()
  462.       lines=lines+#rows
  463.       score=score+points[#rows]*math.min(level,20)
  464.       level=math.floor(lines/10)+initialLevel
  465.       dropSpeed=speedsByLevel[math.min(level,12)]
  466.       updateNumbers()
  467.     end
  468.     sleep(.25)
  469.   end
  470.  
  471.   local function blockFall()
  472.     local result = false
  473.     if testBlockAt(curBlock,curX,curY+1,curRot) then
  474.       pitBlock(curBlock,curX,curY,curRot)
  475.       --detect rows that clear
  476.       clearRows(rows)
  477.  
  478.       curBlock=next
  479.       curX=4
  480.       curY=1
  481.       curRot=1
  482.       if testBlockAt(curBlock,curX,curY,curRot) then
  483.         halt=true
  484.       end
  485.       drawBlockAt(curBlock,curX,curY,curRot)
  486.       eraseBlockAt(next,11.5,15+heightAdjust,1)
  487.       next=blocks[math.random(1,7)]
  488.       drawBlockAt(next,11.5,15+heightAdjust,1)
  489.       return true
  490.     else
  491.       eraseBlockAt(curBlock,curX,curY,curRot)
  492.       curY=curY+1
  493.       drawBlockAt(curBlock,curX,curY,curRot)
  494.       return false
  495.     end
  496.   end
  497.  
  498.  
  499.   while not halt do
  500.     local e={os.pullEvent()}
  501.     if e[1]=="timer" then
  502.       if e[2]==dropTimer then
  503.         blockFall()
  504.         dropTimer=os.startTimer(dropSpeed)
  505.       end
  506.     elseif e[1]=="key" then
  507.       local key=e[2]
  508.       local dx,dy,dr=0,0,0
  509.       if key==keys.left or key==keys.a then
  510.         dx=-1
  511.       elseif key==keys.right or key==keys.d then
  512.         dx=1
  513.       elseif key==keys.up or key==keys.w then
  514.         dr=1
  515.       elseif key==keys.down or key==keys.s then
  516.         while not blockFall() do end
  517.         dropTimer=os.startTimer(dropSpeed)
  518.       elseif key==keys.space then
  519.         hidePit()
  520.         msgBox("Paused")
  521.         while ({os.pullEvent("key")})[2]~=keys.space do end
  522.         redrawPit()
  523.         drawBlockAt(curBlock,curX,curY,curRot)
  524.         dropTimer=os.startTimer(dropSpeed)
  525.       end
  526.       if dx+dr~=0 then
  527.         if not testBlockAt(curBlock,curX+dx,curY+dy,(dr>0 and curRot%#curBlock+dr or curRot)) then
  528.           eraseBlockAt(curBlock,curX,curY,curRot)
  529.           curX=curX+dx
  530.           curY=curY+dy
  531.           curRot=dr==0 and curRot or (curRot%#curBlock+dr)
  532.           drawBlockAt(curBlock,curX,curY,curRot)
  533.         end
  534.       end
  535.     elseif e[1]=="term_resize" then
  536.       local w,h=term.getSize()
  537.       if h==20 then
  538.         heightAdjust=0
  539.       else
  540.         heightAdjust=1
  541.       end
  542.       redrawPit()
  543.       drawBlockAt(curBlock,curX,curY,curRot)
  544.     end
  545.   end
  546.  
  547.   msgBox("Game Over!")
  548.   while true do
  549.     local _,k=os.pullEvent("key")
  550.     if k==keys.space or k==keys.enter then
  551.       break
  552.     end
  553.   end
  554.  
  555.   level = math.min(level,9)
  556. end
  557.  
  558.  
  559. local selected=1
  560. local playersDetected=false
  561.  
  562. local function drawMenu()
  563.   term.setBackgroundColor(colors.black)
  564.   term.setTextColor(colorass(colors.red,colors.white))
  565.   term.clear()
  566.  
  567.   local cx,cy=math.floor(width/2),math.floor(height/2)
  568.  
  569.   term.setCursorPos(cx-6,cy-2)
  570.   term.write("F A L L I N G")
  571.  
  572.   if playersDetected then
  573.     if selected==0 then
  574.       term.setTextColor(colorass(colors.blue,colors.black))
  575.       term.setBackgroundColor(colorass(colors.gray,colors.white))
  576.     else
  577.       term.setTextColor(colorass(colors.lightBlue,colors.white))
  578.       term.setBackgroundColor(colors.black)
  579.     end
  580.     term.setCursorPos(cx-12,cy)
  581.     term.write(" Play head-to-head game! ")
  582.   end
  583.  
  584.   term.setCursorPos(cx-10,cy+1)
  585.   if selected==1 then
  586.     term.setTextColor(colorass(colors.blue,colors.black))
  587.     term.setBackgroundColor(colorass(colors.lightGray,colors.white))
  588.   else
  589.     term.setTextColor(colorass(colors.lightBlue,colors.white))
  590.     term.setBackgroundColor(colors.black)
  591.   end
  592.   term.write(" Play from level: <" .. level .. "> ")
  593.  
  594.   term.setCursorPos(cx-3,cy+3)
  595.   if selected==2 then
  596.     term.setTextColor(colorass(colors.blue,colors.black))
  597.     term.setBackgroundColor(colorass(colors.lightGray,colors.white))
  598.   else
  599.     term.setTextColor(colorass(colors.lightBlue,colors.white))
  600.     term.setBackgroundColor(colors.black)
  601.   end
  602.   term.write(" Quit ")
  603. end
  604.  
  605.  
  606. local function runMenu()
  607.   drawMenu()
  608.  
  609.   while true do
  610.     local event={os.pullEvent()}
  611.     if event[1]=="key" then
  612.       local key=event[2]
  613.       if key==keys.right or key==keys.d and selected==1 then
  614.         level=math.min(level+1,9)
  615.         drawMenu()
  616.       elseif key==keys.left or key==keys.a and selected==1 then
  617.         level=math.max(level-1,1)
  618.         drawMenu()
  619.       elseif key>=keys.one and key<=keys.nine and selected==1 then
  620.         level=(key-keys.one) + 1
  621.         drawMenu()
  622.       elseif key==keys.up or key==keys.w then
  623.         selected=selected-1
  624.         if selected==0 then
  625.           selected=2
  626.         end
  627.         drawMenu()
  628.       elseif key==keys.down or key==keys.s then
  629.         selected=selected%2+1
  630.         drawMenu()
  631.       elseif key==keys.enter or key==keys.space then
  632.         break --begin play!
  633.       end
  634.     end
  635.   end
  636. end
  637.  
  638. while true do
  639.   runMenu()
  640.   if selected==2 then
  641.     break
  642.   end
  643.  
  644.   playGame()
  645. end
  646.  
  647.  
  648. term.setTextColor(colors.white)
  649. term.setBackgroundColor(colors.black)
  650. term.clear()
  651. term.setCursorPos(1,1)
Advertisement
Add Comment
Please, Sign In to add comment