Advertisement
Symmetryc

You Can't ComputerCraft, Under Pressure

Dec 24th, 2013
243
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.43 KB | None | 0 0
  1. -- You Can't ComputerCraft, Under Pressure, by Symmetryc
  2. local max_x, max_y = term.getSize()
  3.  
  4. -- Mah API
  5. local function copy(_t)
  6.     local t = {}
  7.     for k, v in pairs(_t) do
  8.         t[k] = type(v) == "table" and copy(v) or v
  9.     end
  10.     return t
  11. end
  12. local ibuffer = {
  13.     buffer = function()
  14.         return {
  15.             act = {};
  16.             pos_x = 1;
  17.             pos_y = 1;
  18.             shift_x = 0;
  19.             shift_y = 0;
  20.             back = colors.white;
  21.             text = colors.lightGray;
  22.             blink = false;
  23.             write = function(self, _str)
  24.                 local act = self.act
  25.                 local append = true
  26.                 if self.pos_x ~= act.pos_y or self.pos_x ~= act.pos_y then
  27.                     act[#act + 1] = {term.setCursorPos, self.pos_x, self.pos_y}
  28.                     append = false
  29.                 end
  30.                 if self.back ~= act.back then
  31.                     act[#act + 1] = {term.setBackgroundColor, self.back}
  32.                     act.back = self.back
  33.                     append = false
  34.                 end
  35.                 if self.text ~= act.text then
  36.                     act[#act + 1] = {term.setTextColor, self.text}
  37.                     act.text = self.text
  38.                     append = false
  39.                 end
  40.                 for line, nl in _str:gmatch("([^\n]*)(\n?)") do
  41.                     if append then
  42.                         act[#act][2] = act[#act][2]..line
  43.                         append = false
  44.                     else
  45.                         act[#act + 1] = {term.write, line}
  46.                     end
  47.                     if nl == "\n" then
  48.                         self.pos_y = self.pos_y + 1
  49.                         act[#act + 1] = {term.setCursorPos, self.pos_x, self.pos_y}
  50.                     else
  51.                         self.pos_x = self.pos_x + #line
  52.                     end
  53.                 end
  54.                 act.pos_x, act.pos_y = self.pos_x, self.pox_y
  55.                 return self
  56.             end;
  57.             clear = function(self)
  58.                 self.act = {
  59.                     {term.setBackgroundColor, self.back};
  60.                     {term.clear};
  61.                 }
  62.                 return self
  63.             end;
  64.             draw = function(self)
  65.                 for i, v in ipairs(self.act) do
  66.                     if v[3] then
  67.                         v[1](v[2] + self.shift_x, v[3] + self.shift_y)
  68.                     else
  69.                         v[1](v[2])
  70.                     end
  71.                 end
  72.                 term.setCursorBlink(self.blink)
  73.                 return self
  74.             end;
  75.         }
  76.     end;
  77.     new = function()
  78.         return {
  79.             add = function(self, _buffer, _n)
  80.                 self[_n or #self + 1] = copy(_buffer)
  81.                 return self
  82.             end;
  83.             run = function(self)
  84.                 for k, v in pairs(self) do
  85.                     if type(v) == "table" and v.draw then
  86.                         v:draw()
  87.                     end
  88.                 end
  89.                 local r = {}
  90.                 while not r[1] do
  91.                     local event = {os.pullEvent()}
  92.                     for k, v in pairs(self) do
  93.                         if type(v) == "table" and v.fn then
  94.                             r = {v:fn(self, event)}
  95.                             if #r > 0 then
  96.                                 break
  97.                             end
  98.                         end
  99.                     end
  100.                 end
  101.                 return unpack(r)
  102.             end;
  103.         }
  104.     end;
  105. }
  106.  
  107. local time = 0
  108. term.setBackgroundColor(colors.white)
  109. term.setTextColor(colors.lime)
  110. local txt = "You Can't ComputerCraft, Under Pressure!"
  111. term.setCursorPos(max_x / 2 - #txt / 2 + 1, 2)
  112. term.clear()
  113. term.write(txt)
  114. term.setBackgroundColor(colors.lime)
  115. term.setTextColor(colors.white)
  116. for i = -1, 1 do
  117.     term.setCursorPos(math.ceil(max_x / 4), math.floor(max_y / 2) + i)
  118.     term.write((" "):rep(math.ceil(max_x / 2 + 1)))
  119. end
  120. local txt = "Begin!"
  121. term.setCursorPos(math.ceil(max_x / 2 - #txt / 2), math.floor(max_y / 2))
  122. term.write(txt)
  123. while true do
  124.     local _, _, p3, p4 = os.pullEvent("mouse_click")
  125.     if p3 >= math.ceil(max_x / 4) and p3 <= math.ceil(max_x - max_x / 4) and p4 >= math.floor(max_y / 2) - 1 and p4 <= math.floor(max_y / 2) + 1 then
  126.         break
  127.     end
  128. end
  129.  
  130. -- Challenges
  131. local mt = {{}, {}}
  132. local challenges = {
  133.     {"Return whether x is even or not", {}, {5, false}, {8, true}, {-3, false}};
  134.     {"Return the type of x", {type = type}, {{}, "table"}, {7, "number"}, {"Hello", "string"}};
  135.     {"Return the length of x", {string = {len = string.len}}, {"Hello", 5}, {{1, 2, 3}, 3}};
  136.     {"Return the y-axis cursor position", {term = {getCursorPos = function() return 5, 7 end}}, {nil, 7}};
  137.     {"Return the metatable of x", {getmetatable = getmetatable}, {setmetatable({}, mt[1]), mt[1]}, setmetatable({}, mt[2]), mt[2]};
  138.     {"Return the largest number index of x", {table = {maxn = table.maxn}}, {{1, 2, 3}, 3}, {{1, 2, nil, 3}, 4}};
  139.     {"Return x factorial", {}, {5, 120}, {1, 1}, {8, 40320}};
  140.     {"Return x (base 8) in base 10", {}, {10, 8}, {120, 80}, {0, 0}};
  141.     {"Return false (global value, not 'not true')", {_G = {["false"] = 11}}, {nil, 11}};
  142. }
  143.  
  144. -- Typing GUI
  145. local gui = ibuffer.buffer()
  146. gui.back, gui.text = colors.white, colors.black
  147. gui:clear()
  148. gui.pos_x, gui.pos_y = 2, 3
  149. gui:write("Use Ctrl to enter your answer\nError/Bad Return: \n")
  150. gui:write((" "):rep(max_x).."\n")
  151. for i = 6, max_y - 1 do
  152.     gui.pos_x, gui.pos_y = 1, i
  153.     gui.back = colors.white
  154.     gui:write("  ")
  155.     gui.back = colors.lime
  156.     gui:write((" "):rep(max_x - 4))
  157.     gui.back = colors.white
  158.     gui:write("  ")
  159. end
  160. gui:write("\n"..(" "):rep(max_x))
  161. gui.code, gui.cur = "", 0
  162. gui.pos_x, gui.pos_y = 4, 7
  163. gui.text = colors.white
  164. gui.blink = true
  165. local m4 = max_x - 6
  166. gui.fn = function(self, obj, event)
  167.     if event[1] == "char" and #self.code < m4 * (max_y - 8) then
  168.         self.code = self.code:sub(1, self.cur)..event[2]..self.code:sub(self.cur + 1)
  169.         self.cur = self.cur + 1
  170.     elseif event[2] == keys.backspace and self.cur > 0 then
  171.         self.code = self.code:sub(1, self.cur - 1)..self.code:sub(self.cur + 1)
  172.         self.cur = self.cur - 1
  173.         term.setCursorPos(4 + #self.code % m4, 6 + math.ceil(#self.code / m4 + 0.01))
  174.         term.write(" ")
  175.     elseif event[2] == keys.left and self.cur > 0 or event[2] == keys.right and self.cur < #self.code then
  176.         self.cur = self.cur + (event[2] == keys.left and -1 or 1)
  177.     elseif event[2] == keys.enter and #self.code < m4 * (max_y - 9) then
  178.         self.code = self.code:sub(1, self.cur)..(" "):rep(m4 - #self.code % m4)..self.code:sub(self.cur + 1)
  179.         self.cur = self.cur + m4 - (self.cur % m4)
  180.     elseif event[2] == keys.down or event[2] == keys.up then
  181.         self.cur = self.cur + (event[2] == keys.down and m4 or -m4)
  182.         self.cur = self.cur < 0 and 0 or self.cur > #self.code and #self.code or self.cur
  183.     elseif event[2] == keys.leftCtrl or event[2] == keys.rightCtrl then
  184.         local env, err, pass, f = obj.challenge[2]
  185.         for i = 3, #obj.challenge do
  186.             env.x = obj.challenge[i][1]
  187.             f, err = loadstring(self.code)
  188.             if not f then break end
  189.             f, err = pcall(setfenv(f, env))
  190.             if not f or err ~= obj.challenge[i][2] then break end
  191.             if i == #obj.challenge then pass = true end
  192.         end
  193.         if not pass then
  194.             term.setCursorPos(19, 4)
  195.             term.setBackgroundColor(colors.white)
  196.             term.setTextColor(colors.red)
  197.             term.write(tostring(err)..(" "):rep(#tostring(err) < (max_x - 8) and max_x - 8 - #tostring(err) or 0))
  198.         else
  199.             os.pullEvent("timer")
  200.             time = time + 1
  201.             return pass
  202.         end
  203.     elseif event[1] == "timer" then
  204.         time = time + 1
  205.         local stime = tostring(time):match("[^%.]*")
  206.         term.setCursorPos(max_x - 1 - #stime, 2)
  207.         term.setTextColor(colors.lime)
  208.         term.setBackgroundColor(colors.white)
  209.         term.write(stime)
  210.         os.startTimer(1)
  211.     end
  212.     term.setBackgroundColor(colors.lime)
  213.     term.setTextColor(colors.white)
  214.     for i = 1, math.ceil(#self.code / m4) do
  215.         term.setCursorPos(4, i + 6)
  216.         term.write(self.code:sub((i - 1) * m4 + 1 , i * m4))
  217.     end
  218.     term.setCursorPos(4 + self.cur % m4, 6 + math.ceil(self.cur / m4 + 0.01))
  219. end
  220.  
  221. -- Tasks
  222. local tasks = {math.random(1, 3), math.random(4, 6), math.random(7, 9)}
  223.  
  224. -- Program
  225. for k, v in pairs(tasks) do
  226.     local q = ibuffer.buffer()
  227.     q.text, q.pos_x, q.pos_y = colors.black, 2, 2
  228.     q:write(challenges[v][1]).blink = true
  229.     q.text, q.pos_x, q.pos_y = colors.white, 4, 7
  230.     q:write("")
  231.     local t = ibuffer.new():add(gui):add(q)
  232.     t.challenge = challenges[v]
  233.     os.startTimer(1)
  234.     t:run()
  235. end
  236. term.setBackgroundColor(colors.black)
  237. term.setTextColor(colors.white)
  238. term.setCursorPos(1, 1)
  239. term.clear()
  240. print("Your time was "..time..", congratz!")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement