Kingdaro

Bejeweled in ComputerCraft

Mar 31st, 2013
673
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 6.62 KB | None | 0 0
  1. local board = {}
  2. local score = 0
  3. local time = 600
  4.  
  5. local gems = {
  6.     {'%.', '%%', color = colors.yellow},
  7.     {'$.', '$$', color = colors.lime},
  8. --  {'&.', '&&', color = colors.orange},
  9.     {'#.', '##', color = colors.red},
  10.     {'@a', '@@', color = colors.magenta},
  11.     {'/\\','\\/', color = colors.lightBlue}
  12. }
  13.  
  14. local selection
  15. local draw, drawGem, drawScore, drawTime, animSwap
  16.  
  17. local running = true
  18.  
  19. local function fillBoard(width, height)
  20.     for y = 1, height do
  21.         board[y] = {}
  22.         for x = 1, width do
  23.             board[y][x] = math.random(#gems)
  24.         end
  25.     end
  26.    
  27.     setmetatable(board, {__call = function(self, x, y, value)
  28.         if not self[y] then return end
  29.         if not self[y][x] then return end
  30.         self[y][x] = value or self[y][x]
  31.         return self[y][x]
  32.     end})
  33.    
  34.     board.width = width
  35.     board.height = height
  36. end
  37.  
  38. local function gemArea(x, y)
  39.     return x*3 - 1, y*3 - 1, 2, 2
  40. end
  41.  
  42. local function checkArea(x, y, ax, ay, aw, ah)
  43.     return
  44.         x >= ax and
  45.         x < ax + aw and
  46.         y >= ay and
  47.         y < ay + ah
  48. end
  49.  
  50. local function findMatch(ox, oy)
  51.     local value = board(ox, oy)
  52.     if value == 0 then return end
  53.     local rowTotal = 0
  54.     local colTotal = 0
  55.     local rowMatches = {}
  56.     local colMatches = {}
  57.    
  58.     local function checkSpace(x, y, isRow)
  59.         if board(x, y) == value then
  60.             if isRow then
  61.                 rowTotal = rowTotal + 1
  62.                 table.insert(rowMatches, {x=x, y=y})
  63.             else
  64.                 colTotal = colTotal + 1
  65.                 table.insert(colMatches, {x=x, y=y})
  66.             end
  67.             return true
  68.         end
  69.     end
  70.    
  71.     for x=ox, 1, -1 do
  72.         if not checkSpace(x, oy, true) then break end
  73.     end
  74.     for x=ox + 1, board.width, 1 do
  75.         if not checkSpace(x, oy, true) then break end
  76.     end
  77.     for y=oy, 1, -1 do
  78.         if not checkSpace(ox, y) then break end
  79.     end
  80.     for y=oy + 1, board.height, 1 do
  81.         if not checkSpace(ox, y) then break end
  82.     end
  83.    
  84.     local matches = {}
  85.     local function addFrom(tab, cond)
  86.         if cond then
  87.             for i=1, #tab do
  88.                 table.insert(matches, tab[i])
  89.             end
  90.         end
  91.     end
  92.     addFrom(rowMatches, rowTotal >= 3)
  93.     addFrom(colMatches, colTotal >= 3)
  94.    
  95.     if #matches >= 3 then
  96.         return matches
  97.     end
  98. end
  99.  
  100. local function replaceGems()
  101.     local blanks
  102.     repeat
  103.         blanks = false
  104.         for bx=1, board.width do
  105.             for by=1, board.height do
  106.                 if board(bx, by) == 0 then
  107.                     for y=by - 1, 0, -1 do
  108.                         if y > 0 then
  109.                             board(bx, y + 1, board(bx, y))
  110.                         else
  111.                             board(bx, y + 1, math.random(#gems))
  112.                         end
  113.                         drawGem(bx*3-1, (y+1)*3-1, gems[board(bx, y + 1)])
  114.                     end
  115.                     sleep(0.05)
  116.                     blanks = true
  117.                 end
  118.             end
  119.         end
  120.     until not blanks
  121. end
  122.  
  123. local function clearMatches()
  124.     draw()
  125.    
  126.     local redo = true
  127.     local scoreInc = 1
  128.    
  129.     while redo do
  130.         redo = false
  131.         local totalMatches = {}
  132.         for bx=1, board.width do
  133.             for by=1, board.height do
  134.                 local matches = findMatch(bx, by)
  135.                
  136.                 if matches then
  137.                     for i=1, #matches do
  138.                         local m = matches[i]
  139.                         totalMatches[m.x..','..m.y] = board(m.x, m.y)
  140.                         drawGem(m.x*3 - 1, m.y*3 - 1, gems[board(m.x, m.y)], colors.white)
  141.                     end
  142.                 end
  143.             end
  144.         end
  145.         sleep(0.2)
  146.         for pos, id in pairs(totalMatches) do
  147.             local x,y = pos:match('(%d+),(%d+)')
  148.             board(tonumber(x), tonumber(y), 0)
  149.             redo = true
  150.             score = score + scoreInc
  151.             scoreInc = scoreInc + 1
  152.            
  153.             drawGem(x*3 - 1, y*3 - 1)
  154.             drawScore()
  155.             sleep(0.1)
  156.         end
  157.        
  158.         if redo then
  159.             replaceGems()
  160.         end
  161.     end
  162. end
  163.  
  164. local function update(ev, p1, p2, p3)
  165.     if ev == 'mouse_click' or ev == 'mouse_drag' then
  166.         local b, mx, my = p1, p2, p3
  167.        
  168.         -- it's like the brooklyn bridge up in this yo
  169.         ;(function()
  170.             for bx=1, board.width do
  171.                 for by=1, board.height do
  172.                     if checkArea(mx, my, gemArea(bx, by)) then
  173.                         if ev == 'mouse_click' then
  174.                             selection = {bx, by}
  175.                             return
  176.                         elseif ev == 'mouse_drag' and selection then
  177.                             local s = selection
  178.                             local dist = ((bx - s[1])^2 + (by - s[2])^2)^.5
  179.                             if dist == 1 then
  180.                                 local cur = board(bx, by)
  181.                                 animSwap(bx*3-1, by*3-1, s[1]*3-1, s[2]*3-1, cur, board(unpack(s)))
  182.                                
  183.                                 board(bx, by, board(unpack(s)))
  184.                                 board(s[1], s[2], cur)
  185.                                
  186.                                 clearMatches()
  187.                                
  188.                                 selection = nil
  189.                                 return
  190.                             end
  191.                         end
  192.                     end
  193.                 end
  194.             end
  195.         end)()
  196.     elseif ev == 'key' and p1 == keys.backspace then
  197.         running = false
  198.     end
  199. end
  200.  
  201. local function updateTime()
  202.     while time > 0 do
  203.         time = time - 1
  204.         drawTime()
  205.         sleep(0.1)
  206.     end
  207. end
  208.  
  209. function drawScore()
  210.     local t = term
  211.     local score = tostring(score)
  212.    
  213.     t.setCursorPos(30, 2)
  214.     t.setTextColor(colors.yellow)
  215.     t.write('SCORE: '..score)
  216. end
  217.  
  218. function drawTime()
  219.     local t = term
  220.    
  221.     t.setCursorPos(30, 4)
  222.     t.setTextColor(colors.yellow)
  223.     t.write('TIME:  '..time..'     ')
  224. end
  225.  
  226. function drawGem(x, y, gem, color)
  227.     local t = term
  228.     if t.isColor() and gem then
  229.         t.setTextColor(color or gem.color)
  230.     end
  231.     t.setCursorPos(x, y)
  232.     t.write(gem and gem[1] or '  ')
  233.     t.setCursorPos(x, y + 1)
  234.     t.write(gem and gem[2] or '  ')
  235. end
  236.  
  237. function animSwap(x1, y1, x2, y2, v1, v2)
  238.     for x=x1, x2, x1 < x2 and 1 or -1 do
  239.         for y=y1, y2, y1 < y2 and 1 or -1 do
  240.             local ox, oy = x2 - x + x1, y2 - y + y1
  241.             drawGem(x, y, gems[v1])
  242.             drawGem(ox, oy, gems[v2])
  243.             sleep(0.05)
  244.             drawGem(x, y)
  245.             drawGem(ox, oy)
  246.         end
  247.     end
  248. end
  249.  
  250. function draw()
  251.     local t = term
  252.    
  253.     t.setBackgroundColor(colors.black)
  254.     t.clear()
  255.    
  256.     for x=1, board.width do
  257.         for y=1, board.height do
  258.             drawGem(x*3 - 1, y*3 - 1, gems[board(x, y)])
  259.         end
  260.     end
  261.    
  262.     drawScore()
  263. end
  264.  
  265. local function pregame()
  266.     draw()
  267.     drawTime()
  268.    
  269.     local t = term
  270.    
  271.     local function sw(y, text)
  272.         t.setCursorPos(30, y)
  273.         textutils.slowWrite(text)
  274.     end
  275.    
  276.     t.setTextColor(colors.yellow)
  277.     t.setCursorPos(30, 6)
  278.     sw(6, 'PRESS ANY KEY')
  279.     sw(7, 'WHEN READY')
  280.    
  281.     repeat
  282.         local ev = os.pullEvent()
  283.     until ev == 'key' or ev == 'mouse_click'
  284.    
  285.     sw(7, '          ')
  286.     sw(6, 'READY        ')
  287.     sleep(0.1)
  288.     sw(6, '             ')
  289.     sw(6, 'SET          ')
  290.     sw(6, '             ')
  291.     sleep(math.random()*1.5 + 0.5)
  292.    
  293.     t.setCursorPos(30, 6)
  294.     t.write('GO')
  295.     sleep(0.2)
  296.     sw(6, '  ')
  297. end
  298.  
  299. local function gameOver()
  300.     local t = term
  301.     t.setTextColor(colors.yellow)
  302.    
  303.     local function sw(y, text)
  304.         t.setCursorPos(30, y)
  305.         textutils.slowWrite(text)
  306.     end
  307.    
  308.     sw(6, 'PRESS ANY KEY')
  309.     sw(7, 'TO CONTINUE')
  310.    
  311.     repeat
  312.         local ev = os.pullEvent()
  313.     until ev == 'key' or ev == 'mouse_click'
  314.    
  315.     t.setBackgroundColor(colors.black)
  316.     t.setCursorPos(1,1)
  317.     t.clear()
  318. end
  319.  
  320. local function main()
  321.     while running do
  322.         local events = {os.pullEvent()}
  323.         if events[1] ~= 'timer' then
  324.             draw()
  325.         end
  326.         update(unpack(events))
  327.     end
  328. end
  329.  
  330. fillBoard(8, 6)
  331. pregame()
  332.  
  333. parallel.waitForAny(main, updateTime)
  334.  
  335. gameOver()
Advertisement
Add Comment
Please, Sign In to add comment