Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- You Can't ComputerCraft, Under Pressure, by Symmetryc
- local max_x, max_y = term.getSize()
- -- Mah API
- local function copy(_t)
- local t = {}
- for k, v in pairs(_t) do
- t[k] = type(v) == "table" and copy(v) or v
- end
- return t
- end
- local ibuffer = {
- buffer = function()
- return {
- act = {};
- pos_x = 1;
- pos_y = 1;
- shift_x = 0;
- shift_y = 0;
- back = colors.white;
- text = colors.lightGray;
- blink = false;
- write = function(self, _str)
- local act = self.act
- local append = true
- if self.pos_x ~= act.pos_y or self.pos_x ~= act.pos_y then
- act[#act + 1] = {term.setCursorPos, self.pos_x, self.pos_y}
- append = false
- end
- if self.back ~= act.back then
- act[#act + 1] = {term.setBackgroundColor, self.back}
- act.back = self.back
- append = false
- end
- if self.text ~= act.text then
- act[#act + 1] = {term.setTextColor, self.text}
- act.text = self.text
- append = false
- end
- for line, nl in _str:gmatch("([^\n]*)(\n?)") do
- if append then
- act[#act][2] = act[#act][2]..line
- append = false
- else
- act[#act + 1] = {term.write, line}
- end
- if nl == "\n" then
- self.pos_y = self.pos_y + 1
- act[#act + 1] = {term.setCursorPos, self.pos_x, self.pos_y}
- else
- self.pos_x = self.pos_x + #line
- end
- end
- act.pos_x, act.pos_y = self.pos_x, self.pox_y
- return self
- end;
- clear = function(self)
- self.act = {
- {term.setBackgroundColor, self.back};
- {term.clear};
- }
- return self
- end;
- draw = function(self)
- for i, v in ipairs(self.act) do
- if v[3] then
- v[1](v[2] + self.shift_x, v[3] + self.shift_y)
- else
- v[1](v[2])
- end
- end
- term.setCursorBlink(self.blink)
- return self
- end;
- }
- end;
- new = function()
- return {
- add = function(self, _buffer, _n)
- self[_n or #self + 1] = copy(_buffer)
- return self
- end;
- run = function(self)
- for k, v in pairs(self) do
- if type(v) == "table" and v.draw then
- v:draw()
- end
- end
- local r = {}
- while not r[1] do
- local event = {os.pullEvent()}
- for k, v in pairs(self) do
- if type(v) == "table" and v.fn then
- r = {v:fn(self, event)}
- if #r > 0 then
- break
- end
- end
- end
- end
- return unpack(r)
- end;
- }
- end;
- }
- local time = 0
- term.setBackgroundColor(colors.white)
- term.setTextColor(colors.lime)
- local txt = "You Can't ComputerCraft, Under Pressure!"
- term.setCursorPos(max_x / 2 - #txt / 2 + 1, 2)
- term.clear()
- term.write(txt)
- term.setBackgroundColor(colors.lime)
- term.setTextColor(colors.white)
- for i = -1, 1 do
- term.setCursorPos(math.ceil(max_x / 4), math.floor(max_y / 2) + i)
- term.write((" "):rep(math.ceil(max_x / 2 + 1)))
- end
- local txt = "Begin!"
- term.setCursorPos(math.ceil(max_x / 2 - #txt / 2), math.floor(max_y / 2))
- term.write(txt)
- while true do
- local _, _, p3, p4 = os.pullEvent("mouse_click")
- 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
- break
- end
- end
- -- Challenges
- local mt = {{}, {}}
- local challenges = {
- {"Return whether x is even or not", {}, {5, false}, {8, true}, {-3, false}};
- {"Return the type of x", {type = type}, {{}, "table"}, {7, "number"}, {"Hello", "string"}};
- {"Return the length of x", {string = {len = string.len}}, {"Hello", 5}, {{1, 2, 3}, 3}};
- {"Return the y-axis cursor position", {term = {getCursorPos = function() return 5, 7 end}}, {nil, 7}};
- {"Return the metatable of x", {getmetatable = getmetatable}, {setmetatable({}, mt[1]), mt[1]}, setmetatable({}, mt[2]), mt[2]};
- {"Return the largest number index of x", {table = {maxn = table.maxn}}, {{1, 2, 3}, 3}, {{1, 2, nil, 3}, 4}};
- {"Return x factorial", {}, {5, 120}, {1, 1}, {8, 40320}};
- {"Return x (base 8) in base 10", {}, {10, 8}, {120, 80}, {0, 0}};
- {"Return false (global value, not 'not true')", {_G = {["false"] = 11}}, {nil, 11}};
- }
- -- Typing GUI
- local gui = ibuffer.buffer()
- gui.back, gui.text = colors.white, colors.black
- gui:clear()
- gui.pos_x, gui.pos_y = 2, 3
- gui:write("Use Ctrl to enter your answer\nError/Bad Return: \n")
- gui:write((" "):rep(max_x).."\n")
- for i = 6, max_y - 1 do
- gui.pos_x, gui.pos_y = 1, i
- gui.back = colors.white
- gui:write(" ")
- gui.back = colors.lime
- gui:write((" "):rep(max_x - 4))
- gui.back = colors.white
- gui:write(" ")
- end
- gui:write("\n"..(" "):rep(max_x))
- gui.code, gui.cur = "", 0
- gui.pos_x, gui.pos_y = 4, 7
- gui.text = colors.white
- gui.blink = true
- local m4 = max_x - 6
- gui.fn = function(self, obj, event)
- if event[1] == "char" and #self.code < m4 * (max_y - 8) then
- self.code = self.code:sub(1, self.cur)..event[2]..self.code:sub(self.cur + 1)
- self.cur = self.cur + 1
- elseif event[2] == keys.backspace and self.cur > 0 then
- self.code = self.code:sub(1, self.cur - 1)..self.code:sub(self.cur + 1)
- self.cur = self.cur - 1
- term.setCursorPos(4 + #self.code % m4, 6 + math.ceil(#self.code / m4 + 0.01))
- term.write(" ")
- elseif event[2] == keys.left and self.cur > 0 or event[2] == keys.right and self.cur < #self.code then
- self.cur = self.cur + (event[2] == keys.left and -1 or 1)
- elseif event[2] == keys.enter and #self.code < m4 * (max_y - 9) then
- self.code = self.code:sub(1, self.cur)..(" "):rep(m4 - #self.code % m4)..self.code:sub(self.cur + 1)
- self.cur = self.cur + m4 - (self.cur % m4)
- elseif event[2] == keys.down or event[2] == keys.up then
- self.cur = self.cur + (event[2] == keys.down and m4 or -m4)
- self.cur = self.cur < 0 and 0 or self.cur > #self.code and #self.code or self.cur
- elseif event[2] == keys.leftCtrl or event[2] == keys.rightCtrl then
- local env, err, pass, f = obj.challenge[2]
- for i = 3, #obj.challenge do
- env.x = obj.challenge[i][1]
- f, err = loadstring(self.code)
- if not f then break end
- f, err = pcall(setfenv(f, env))
- if not f or err ~= obj.challenge[i][2] then break end
- if i == #obj.challenge then pass = true end
- end
- if not pass then
- term.setCursorPos(19, 4)
- term.setBackgroundColor(colors.white)
- term.setTextColor(colors.red)
- term.write(tostring(err)..(" "):rep(#tostring(err) < (max_x - 8) and max_x - 8 - #tostring(err) or 0))
- else
- os.pullEvent("timer")
- time = time + 1
- return pass
- end
- elseif event[1] == "timer" then
- time = time + 1
- local stime = tostring(time):match("[^%.]*")
- term.setCursorPos(max_x - 1 - #stime, 2)
- term.setTextColor(colors.lime)
- term.setBackgroundColor(colors.white)
- term.write(stime)
- os.startTimer(1)
- end
- term.setBackgroundColor(colors.lime)
- term.setTextColor(colors.white)
- for i = 1, math.ceil(#self.code / m4) do
- term.setCursorPos(4, i + 6)
- term.write(self.code:sub((i - 1) * m4 + 1 , i * m4))
- end
- term.setCursorPos(4 + self.cur % m4, 6 + math.ceil(self.cur / m4 + 0.01))
- end
- -- Tasks
- local tasks = {math.random(1, 3), math.random(4, 6), math.random(7, 9)}
- -- Program
- for k, v in pairs(tasks) do
- local q = ibuffer.buffer()
- q.text, q.pos_x, q.pos_y = colors.black, 2, 2
- q:write(challenges[v][1]).blink = true
- q.text, q.pos_x, q.pos_y = colors.white, 4, 7
- q:write("")
- local t = ibuffer.new():add(gui):add(q)
- t.challenge = challenges[v]
- os.startTimer(1)
- t:run()
- end
- term.setBackgroundColor(colors.black)
- term.setTextColor(colors.white)
- term.setCursorPos(1, 1)
- term.clear()
- print("Your time was "..time..", congratz!")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement