Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[Smart Calculator by Cranium]]--
- local tX, tY = term.getSize()
- local calc = {}
- --equation states
- calc.mode = false
- calc.inverse = false
- calc.hyp = false
- calc.sqrt = false
- calc.exp = false
- calc.asin = false
- calc.sin = false
- calc.sinh = false
- calc.atan = false
- calc.tan = false
- calc.tanh = false
- calc.acos = false
- calc.cos = false
- calc.cosh = false
- calc.log = false
- calc.pos = false
- -- characters
- local charList = {
- ["0"] = {
- ".-.",
- "| |",
- "'-'"
- },
- ["1"] = {
- " . ",
- "'| ",
- "---"
- },
- ["2"] = {
- ".-.",
- ".-'",
- "'- "
- },
- ["3"] = {
- " -.",
- " -|",
- " -'"
- },
- ["4"] = {
- ". .",
- "'-|",
- " '"
- },
- ["5"] = {
- ".- ",
- "'-.",
- " -'"
- },
- ["6"] = {
- ".-.",
- "|-.",
- "'-'"
- },
- ["7"] = {
- ".-.",
- " |",
- " '"
- },
- ["8"] = {
- ".-.",
- "|-|",
- "'-'"
- },
- ["9"] = {
- ".-.",
- "'-|",
- " -'"
- },
- ["."] = {
- " ",
- " ",
- " . "
- },
- ["-"] = {
- " ",
- " --",
- " "
- },
- }
- -- lay out the button labels
- local labels = {
- ' + ', ' 1 ', ' 2 ', ' 3 ', '<--', 'sin', 'x^y', 'DEG', 'OFF',
- ' - ', ' 4 ', ' 5 ', ' 6 ', 'CLR', 'cos', 'srt', 'RAD', ' ',
- ' x ', ' 7 ', ' 8 ', ' 9 ', ' ', 'tan', 'Pi ', 'inv', ' ',
- ' / ', ' 0 ', '-/+', ' . ', ' = ', 'log', 'exp', 'hyp', ' '
- }
- -- generate the objects
- local function objGen()
- local _objects = {}
- local width = 9
- for i=1, #labels do
- table.insert(_objects, {
- x = (((i - 1)%width + 1)*5) - 1;
- y = (math.ceil(i/width) * 3) + 4;
- label = labels[i];
- -- make operators different colors
- color =
- i == 1 and colors.blue or
- i == 5 and colors.red or
- i == 6 and colors.yellow or
- i == 7 and colors.orange or
- i == 8 and colors.white or
- i == 9 and colors.red or
- i == 10 and colors.blue or
- i == 14 and colors.red or
- i == 15 and colors.yellow or
- i == 16 and colors.orange or
- i == 17 and colors.white or
- i == 18 and colors.white or
- i == 19 and colors.blue or
- i == 24 and colors.yellow or
- i == 25 and colors.orange or
- i == 26 and colors.white or
- i == 27 and colors.white or
- i == 28 and colors.blue or
- i == 30 and colors.red or
- i == 32 and colors.white or
- i == 33 and colors.yellow or
- i == 34 and colors.orange or
- i == 35 and colors.white or
- i == 36 and colors.white or
- colors.lightGray;
- -- controls the highlight colors for operators
- back =
- i == 6 and
- calc.sin == true and colors.red or
- calc.asin == true and colors.red or
- calc.sinh == true and colors.red or
- i == 8 and calc.mode == "deg" and colors.blue or
- i == 15 and
- calc.cos == true and colors.red or
- calc.acos == true and colors.red or
- calc.cosh == true and colors.red or
- i == 16 and calc.sqrt == true and colors.lightBlue or
- i == 17 and calc.mode == "rad" and colors.blue or
- i == 24 and
- calc.tan == true and colors.red or
- calc.atan == true and colors.red or
- calc.tanh == true and colors.red or
- i == 26 and calc.inverse == true and colors.blue or
- i == 30 and calc.pos == true and colors.white or
- i == 33 and calc.log == true and colors.red or
- i == 34 and calc.exp == true and colors.lightBlue or
- i == 35 and calc.hyp == true and colors.blue or
- colors.black;
- })
- end
- return _objects
- end
- local function draw()
- term.setBackgroundColor(colors.black)
- term.clear()
- local objects = objGen()
- for i=1, #objects do
- local obj = objects[i]
- term.setTextColor(colors.gray)
- term.setBackgroundColor(colors.black)
- --draw the grid
- for num, line in pairs{'+---+','| |','+---+'} do
- term.setCursorPos(obj.x, obj.y + num - 1)
- write(line)
- end
- --draw the button text and colors
- term.setCursorPos(obj.x+1, obj.y+1)
- term.setTextColor(obj.color)
- term.setBackgroundColor(obj.back)
- write(obj.label)
- end
- end
- --draw border and screen
- local function display()
- term.setBackgroundColor(colors.black)
- term.setTextColor(colors.gray)
- term.setCursorPos(2,1)
- write("+"..string.rep("-", tX - 4).."+")
- for i = 2, tY - 1 do
- term.setCursorPos(2,i)
- write("|")
- term.setCursorPos(tX - 1,i)
- write("|")
- end
- term.setCursorPos(2,tY)
- write("+"..string.rep("-", tX - 4).."+")
- term.setBackgroundColor(colors.lightGray)
- for i = 2, 6 do
- term.setCursorPos(4,i)
- write(string.rep(" ", tX - 6))
- end
- end
- --run the equation passed by the user.
- local function calculate(eq)
- if table.concat(eq) == "()" then
- eq = {"0"}
- elseif table.concat(eq) == "(.)" then
- eq = {"0"}
- end
- local sExpr = table.concat(eq)
- local fnMath, sErr = loadstring("return "..sExpr)
- if not fnMath then
- return "ERROR! Check syntax!"
- end
- --setfenv(fnMath, math)
- local bSucc, vRes = pcall(fnMath)
- if not bSucc then
- return "ERROR! Check syntax!"
- else
- return vRes
- end
- end
- -- function loop
- local equation = {"(", ")"}
- local result = "0"
- while true do
- local rLen = 0
- draw()
- display()
- term.setBackgroundColor(colors.lightGray)
- term.setTextColor(colors.white)
- term.setCursorPos(4,2)
- --write the equation
- write(table.concat(equation))
- --write the result
- if tonumber(result) ~= inf then
- if string.len(result) >= 15 then
- term.setCursorPos(5, 4)
- term.setTextColor(colors.black)
- write("= ")
- for num in string.gmatch(result, ".") do
- rLen = rLen + 1
- local pX,pY = term.getCursorPos()
- if pX >= 4 and pX <= 48 then
- term.setCursorPos(rLen + 5, 4)
- write(num)
- else
- term.setCursorPos(rLen + 5 - 48, 5)
- write(num)
- end
- end
- else
- for num in string.gmatch(result, ".") do
- rLen = rLen + 1
- for i = 1, #charList[num] do
- term.setTextColor(colors.black)
- term.setCursorPos((rLen * 3) + 1, i + 3)
- write(charList[num][i])
- end
- end
- end
- else
- term.setCursorPos(5, 4)
- term.setTextColor(colors.black)
- write("= INFINITY")
- end
- local events = {os.pullEvent()}
- --mouse click filter
- if events[1] == "mouse_click" and events[2] == 1 then
- if events[3] >= 44 and events[3] <= 48 then
- if events[4] >= 7 and events[4] <= 9 then
- os.shutdown()
- end
- elseif events[3] >= 39 and events[3] <= 43 then
- if events[4] >= 7 and events[4] <= 9 then
- if calc.mode == false then
- table.remove(equation, 1)
- calc.mode = "deg"
- table.insert(equation, 1, "math.deg(")
- elseif calc.mode == "deg" then
- table.remove(equation, 1)
- calc.mode = false
- elseif calc.mode == "rad" then
- table.remove(equation, 1)
- calc.mode = "deg"
- table.insert(equation, 1, "math.deg(")
- end
- elseif events[4] >= 10 and events[4] <= 12 then
- if calc.mode == false then
- table.remove(equation, 1)
- calc.mode = "rad"
- table.insert(equation, 1, "math.rad(")
- elseif calc.mode == "rad" then
- table.remove(equation, 1)
- calc.mode = false
- elseif calc.mode == "deg" then
- table.remove(equation, 1)
- calc.mode = "rad"
- table.insert(equation, 1, "math.rad(")
- end
- elseif events[4] >= 13 and events[4] <= 15 then
- if calc.inverse == true and calc.hyp == false then
- calc.inverse = false
- elseif calc.inverse == false and calc.hyp == true then
- calc.inverse = true
- calc.hyp = false
- elseif calc.inverse == false and calc.hyp == false then
- calc.inverse = true
- end
- elseif events[4] >= 16 and events[4] <= 18 then
- if calc.hyp == true and calc.inverse == false then
- calc.hyp = false
- elseif calc.hyp == false and calc.inverse == true then
- calc.hyp = true
- calc.inverse = false
- elseif calc.hyp == false and calc.inverse == false then
- calc.hyp = true
- end
- end
- elseif events[3] >= 34 and events[3] <= 38 then
- if events[4] >= 7 and events[4] <= 9 then
- table.insert(equation, #equation, "^")
- elseif events[4] >= 10 and events[4] <= 12 then
- if calc.sqrt == false then
- table.insert(equation, #equation, "math.sqrt(")
- calc.sqrt = true
- elseif calc.sqrt == true then
- table.insert(equation, #equation, ")")
- calc.sqrt = false
- end
- elseif events[4] >= 13 and events[4] <= 15 then
- table.insert(equation, #equation, "math.pi")
- elseif events[4] >= 16 and events[4] <= 18 then
- if calc.exp == false then
- table.insert(equation, #equation, "math.exp(")
- calc.exp = true
- elseif calc.exp == true then
- table.insert(equation, #equation, ")")
- calc.exp = false
- end
- end
- elseif events[3] >= 29 and events[3] <= 33 then
- if events[4] >= 7 and events[4] <= 9 then
- if calc.inverse == true and calc.asin == false then
- table.insert(equation, #equation, "math.asin(")
- calc.asin = true
- elseif calc.inverse == false and calc.hyp == false and calc.sin == false then
- table.insert(equation, #equation, "math.sin(")
- calc.sin = true
- elseif calc.hyp == true and calc.sinh == false then
- table.insert(equation, #equation, "math.sinh(")
- calc.sinh = true
- elseif calc.asin == true then
- table.insert(equation, #equation, ")")
- calc.asin = false
- elseif calc.sin == true then
- table.insert(equation, #equation, ")")
- calc.sin = false
- elseif calc.sinh == true then
- table.insert(equation, #equation, ")")
- calc.sinh = false
- end
- elseif events[4] >= 10 and events[4] <= 12 then
- if calc.inverse == true and calc.acos == false then
- table.insert(equation, #equation, "math.acos(")
- calc.acos = true
- elseif calc.inverse == false and calc.hyp == false and calc.cos == false then
- table.insert(equation, #equation, "math.cos(")
- calc.cos = true
- elseif calc.hyp == true and calc.cosh == false then
- table.insert(equation, #equation, "math.cosh(")
- calc.cosh = true
- elseif calc.acos == true then
- table.insert(equation, #equation, ")")
- calc.acos = false
- elseif calc.cos == true then
- table.insert(equation, #equation, ")")
- calc.cos = false
- elseif calc.cosh == true then
- table.insert(equation, #equation, ")")
- calc.cosh = false
- end
- elseif events[4] >= 13 and events[4] <= 15 then
- if calc.inverse == true and calc.atan == false then
- table.insert(equation, #equation, "math.atan(")
- calc.atan = true
- elseif calc.inverse == false and calc.hyp == false and calc.tan == false then
- table.insert(equation, #equation, "math.tan(")
- calc.tan = true
- elseif calc.hyp == true and calc.tanh == false then
- table.insert(equation, #equation, "math.tanh(")
- calc.tanh = true
- elseif calc.atan == true then
- table.insert(equation, #equation, ")")
- calc.atan = false
- elseif calc.tan == true then
- table.insert(equation, #equation, ")")
- calc.tan = false
- elseif calc.tanh == true then
- table.insert(equation, #equation, ")")
- calc.tanh = false
- end
- elseif events[4] >= 16 and events[4] <= 18 then
- if calc.log == false then
- table.insert(equation, #equation, "math.log10(")
- calc.log = true
- elseif calc.log == true then
- table.insert(equation, ")")
- calc.log = false
- end
- end
- -- backspace, clear, equals
- elseif events[3] >= 24 and events[3] <= 28 then
- if events[4] >= 7 and events[4] <= 9 then
- if table.concat(equation) ~= "()" then
- table.remove(equation, #equation - 1)
- end
- elseif events[4] >= 10 and events[4] <= 12 then
- calc.mode = false
- calc.inverse = false
- calc.hyp = false
- calc.sqrt = false
- calc.exp = false
- calc.asin = false
- calc.sin = false
- calc.sinh = false
- calc.atan = false
- calc.tan = false
- calc.tanh = false
- calc.acos = false
- calc.cos = false
- calc.cosh = false
- calc.log = false
- calc.pos = false
- equation = {"(", ")"}
- result = "0"
- elseif events[4] >= 16 and events[4] <= 18 then
- if equation[#equation-1] == "+" or
- equation[#equation-1] == "-" or
- equation[#equation-1] == "*" or
- equation[#equation-1] == "/" then
- table.insert(equation, #equation, "0")
- elseif equation[#equation-1] == "^" then
- table.insert(equation, #equation, "1")
- end
- for i, v in pairs(calc) do
- if calc[i] == true then
- table.insert(equation, #equation, ")")
- calc[i] = false
- end
- end
- result = tostring(calculate(equation))
- end
- -- 3, 6, 9, decimal
- elseif events[3] >= 19 and events[3] <= 23 then
- if events[4] >= 7 and events[4] <= 9 then
- table.insert(equation, #equation, "3")
- elseif events[4] >= 10 and events[4] <= 12 then
- table.insert(equation, #equation, "6")
- elseif events[4] >= 13 and events[4] <= 15 then
- table.insert(equation, #equation, "9")
- elseif events[4] >= 16 and events[4] <= 18 then
- table.insert(equation, #equation, ".")
- end
- -- 2, 5, 8, positive/negative
- elseif events[3] >= 14 and events[3] <= 18 then
- if events[4] >= 7 and events[4] <= 9 then
- table.insert(equation, #equation, "2")
- elseif events[4] >= 10 and events[4] <= 12 then
- table.insert(equation, #equation, "5")
- elseif events[4] >= 13 and events[4] <= 15 then
- table.insert(equation, #equation, "8")
- elseif events[4] >= 16 and events[4] <= 18 then
- if calc.pos == false then
- table.insert(equation, #equation, "(-")
- calc.pos = true
- elseif calc.pos == true then
- table.insert(equation, #equation, ")")
- calc.pos = false
- end
- end
- -- 1, 4, 7, 0
- elseif events[3] >= 9 and events[3] <= 13 then
- if events[4] >= 7 and events[4] <= 9 then
- table.insert(equation, #equation, "1")
- elseif events[4] >= 10 and events[4] <= 12 then
- table.insert(equation, #equation, "4")
- elseif events[4] >= 13 and events[4] <= 15 then
- table.insert(equation, #equation, "7")
- elseif events[4] >= 16 and events[4] <= 18 then
- table.insert(equation, #equation, "0")
- end
- -- add, subtract, multiply, divide
- elseif events[3] >= 4 and events[3] <= 8 then
- if events[4] >= 7 and events[4] <= 9 then
- table.insert(equation, #equation, "+")
- elseif events[4] >= 10 and events[4] <= 12 then
- table.insert(equation, #equation, "-")
- elseif events[4] >= 13 and events[4] <= 15 then
- table.insert(equation, #equation, "*")
- elseif events[4] >= 16 and events[4] <= 18 then
- table.insert(equation, #equation, "/")
- end
- end
- -- filter for keyboard presses
- elseif events[1] == "key" then
- if events[2] == 79 then
- table.insert(equation, #equation, "1")
- elseif events[2] == 80 then
- table.insert(equation, #equation, "2")
- elseif events[2] == 81 then
- table.insert(equation, #equation, "3")
- elseif events[2] == 75 then
- table.insert(equation, #equation, "4")
- elseif events[2] == 76 then
- table.insert(equation, #equation, "5")
- elseif events[2] == 77 then
- table.insert(equation, #equation, "6")
- elseif events[2] == 71 then
- table.insert(equation, #equation, "7")
- elseif events[2] == 72 then
- table.insert(equation, #equation, "8")
- elseif events[2] == 73 then
- table.insert(equation, #equation, "9")
- elseif events[2] == 82 then
- table.insert(equation, #equation, "0")
- elseif events[2] == 83 then
- table.insert(equation, #equation, ".")
- elseif events[2] == 78 then
- table.insert(equation, #equation, "+")
- elseif events[2] == 74 then
- table.insert(equation, #equation, "-")
- elseif events[2] == 55 then
- table.insert(equation, #equation, "*")
- elseif events[2] == 181 then
- table.insert(equation, #equation, "/")
- elseif events[2] == 14 then
- if table.concat(equation) ~= "()" then
- table.remove(equation, #equation - 1)
- end
- elseif events[2] == 28 or events[2] == 156 then
- if equation[#equation-1] == "+" or
- equation[#equation-1] == "-" or
- equation[#equation-1] == "*" or
- equation[#equation-1] == "/" then
- table.insert(equation, #equation, "0")
- elseif equation[#equation-1] == "^" then
- table.insert(equation, #equation, "1")
- end
- for i, v in pairs(calc) do
- if calc[i] == true then
- table.insert(equation, #equation, ")")
- calc[i] = false
- end
- end
- result = tostring(calculate(equation))
- end
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment