Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local tArgs = {...}
- local function val(a)
- local result = 0
- if a == true then
- result = 1
- elseif a == false then
- result = 0
- elseif a == "1" then
- result = true
- elseif a == "0" then
- result = false
- end
- return result
- end
- local function txt(x,y,t,c)
- if c then term.setTextColour(c) end
- term.setCursorPos(x,y)
- if type(t) == "string" or type(t) =="number" then
- write(t)
- else
- write(textutils.serialise(t))
- end
- term.setTextColour(colors.white)
- end
- local function debug(x,y,str)
- if not str then
- str = ""
- else
- str = str..", "
- end
- txt(x,y,"Debug: "..str,colors.red)
- read()
- return var
- end
- --[[
- UTF8
- 65 - 90 Capital letters
- 97 - 122 Lowercase letters
- 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26
- a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z
- ]]
- local function makeBooleanTables(tArgs)
- local list = {}
- if #tArgs > 1 then
- for i = 2, #tArgs do
- list[i-1] = {val(tArgs[i])}
- end
- return list
- end
- local inputs = tonumber(tArgs[1])
- local length = 2^inputs
- for i = 1, inputs do
- local counter = 2^(i-1)
- local listIndex = inputs+1-i
- list[listIndex] = {}
- while #list[listIndex] < length do
- for j = 1, counter do
- list[listIndex][#list[listIndex]+1] = false
- end
- for j = 1, counter do
- list[listIndex][#list[listIndex]+1] = true
- end
- end
- end
- return list
- end
- local gates = {
- gand = function(...)
- for i = 1, #arg do
- if arg[i] == false then
- return false
- end
- end
- return true
- end,
- gor = function(...)
- for i = 1, #arg do
- if arg[i] == true then
- return true
- end
- end
- return false
- end,
- gxor = function(...)
- for i = 1, #arg do
- if arg[i] == true then
- for j = 1, #arg do
- if arg[j] == true and j ~= i then
- return false
- elseif j == #arg then
- return true
- end
- end
- end
- end
- return false
- end,
- gxand = function(...)
- for i = 1, #arg do
- if arg[1] ~= arg[i] then
- return false
- end
- end
- return true
- end,
- ginv = function(a)
- if a == true then
- return false
- else
- return true
- end
- end,
- }
- local ic = {
- test = function(a,b)
- local result = gates.gor(
- gates.gand(gates.ginv(b),a),
- gates.gand(gates.ginv(a),b)
- )
- return result
- end,
- c74181_1 = function(a,b,s0,s1,s2,s3)
- local ia = gates.ginv(a)
- local ib = gates.ginv(b)
- local r1 = gates.ginv(gates.gor(
- gates.gand(s3,ia,b),
- gates.gand(s2,ia,b)
- ))
- local r2 = gates.ginv(gates.gor(
- gates.gand(s1,b),
- gates.gand(s0,ib),
- a
- ))
- return r1, r2
- end,
- c74181_2 = function()
- end,
- fadd = function(a,b,cin)
- local xorab = gates.gxor(a,b)
- local sum = gates.gxor(xorab,cin)
- local cout = gates.gor(
- gates.gand(cin,xorab),
- gates.gand(a,b)
- )
- return sum,cout
- end,
- decoder = function(a,b,e)
- local ia = gates.ginv(a)
- local ib = gates.ginv(b)
- local q1,q2,q3,q4 = gates.gand(ia,ib,e),gates.gand(ia,b,e),gates.gand(a,ib,e),gates.gand(a,b,e)
- return q1,q2,q3,q4
- end,
- encoder = function(a,b,c,d)
- local ia,ib,ic,id = gates.ginv(a),gates.ginv(b),gates.ginv(c),gates.ginv(d)
- local x1 = gates.ginv(gates.gor(a,b))
- local x2 = gates.ginv(gates.gor(ia,b))
- local x3 = gates.ginv(gates.gor(a,ib))
- local x4 = gates.ginv(gates.gor(ia,ib))
- local x5 = gates.ginv(gates.gor(c,d))
- local x6 = gates.ginv(gates.gor(ic,d))
- local x7 = gates.ginv(gates.gor(c,id))
- local r0 = gates.ginv(gates.gand(x1,x5))
- local r1 = gates.ginv(gates.gand(x2,x5))
- local r2 = gates.ginv(gates.gand(x3,x5))
- local r3 = gates.ginv(gates.gand(x4,x5))
- local r4 = gates.ginv(gates.gand(x5,x6))
- local r5 = gates.ginv(gates.gand(x2,x6))
- local r6 = gates.ginv(gates.gand(x3,x6))
- local r7 = gates.ginv(gates.gand(x4,x6))
- local r8 = gates.ginv(gates.gand(x1,x7))
- local r9 = gates.ginv(gates.gand(x2,x7))
- return r0,r1,r2,r3,r4,r5,r6,r7,r8,r9
- end,
- }
- local ic2 = {
- fadd4 = function(cin,a1,a2,a3,a4,b1,b2,b3,b4)
- --If subtracting, cin is 1. if adding, cin is 0. Cout is disregarded, the result is (16-|result|)
- --If adding, Cout == 16. So result is (result + Cout)
- --A's are one number, B's are the other number.
- local x1,x2,x3,x4 = gates.gxor(b1,cin),gates.gxor(b2,cin),gates.gxor(b3,cin),gates.gxor(b4,cin)
- local sum1,cout1 = ic.fadd(a1, x1, cin)
- local sum2,cout2 = ic.fadd(a2, x2, cout1)
- local sum3,cout3 = ic.fadd(a3, x3, cout2)
- local sum4,cout4 = ic.fadd(a4, x4, cout3)
- return sum1,sum2,sum3,sum4,cout4
- end,
- c74181 = function(c,m,a0,a1,a2,a3,b0,b1,b2,b3,s0,s1,s2,s3)
- local r1,r2 = ic.c74181_1(a3,b3,s0,s1,s2,s3)
- local r3,r4 = ic.c74181_1(a3,b3,s0,s1,s2,s3)
- local r5,r6 = ic.c74181_1(a3,b3,s0,s1,s2,s3)
- local r7,r8 = ic.c74181_1(a3,b3,s0,s1,s2,s3)
- end
- }
- local function processLogicResults(...)
- return arg
- end
- local function doLogic(b,g1,g2,g3) --b for boolean, g for logic gate list, c for circuits list, n for 2nd generation circuits
- local result = processLogicResults(
- --g3.fadd4(b.a, b.b, b.c, b.d, b.e, b.f, b.g, b.h, b.i)
- g2.fadd(b.a,b.b,b.c)
- --gates.ginv(g2.test(b.a,b.b))
- )
- return result
- end
- local function processBooleanTables(blist,gates,ic)
- local results = {}
- local inputs = #blist
- local length = #blist[1]
- for i = 1, length do
- local tl = {}
- for j = 1, inputs do
- tl[utf8.char(96+j)] = blist[j][i]
- end
- results[#results+1] = doLogic(tl,gates,ic,ic2)
- end
- return results
- end
- local function drawKarnaugh(x,y,results,tArgs)
- local inputs = tonumber(tArgs[1])
- if inputs <= 1 or inputs > 4 or #tArgs > 1 then
- return
- end
- local il = { --index list From left to right on output table
- {
- 1,3,
- 2,4
- },
- {
- 1,3,7,5,
- 2,4,8,6
- },
- {
- 1,5,13,9,
- 2,6,14,10,
- 4,8,16,12,
- 3,7,15,11
- },
- }
- local labels = {
- two = {"0","1"},
- four = {"00","01","11","10"}
- }
- local tbl = {
- top = "A",
- bottom = "B",
- col = 2,
- row = 2
- }
- local xspace = 2
- local yspace = 2
- local indexTable = il[1]
- if inputs == 2 then
- xspace = 2
- elseif inputs == 3 then
- indexTable = il[2]
- xspace = 3
- tbl.top = "AB"
- tbl.bottom = "C"
- tbl.col = 4
- elseif inputs == 4 then
- indexTable = il[3]
- xspace = 3
- tbl.top = "AB"
- tbl.bottom = "CD"
- tbl.col = 4
- tbl.row = 4
- end
- for k = 1, #results[1] do
- local y = y + (k-1)*tbl.row*3 + (k-1)*2
- txt(x+4,y-2,tbl.top,colors.green)
- txt(x,y-2,k..":",colors.orange)
- txt(x+2,y-1,"\\",colors.green)
- txt(x+3,y,"\\",colors.green)
- txt(x,y,tbl.bottom,colors.green)
- for i = 1, tbl.col do
- local toplabel
- if inputs == 2 then
- toplabel = labels.two[i]
- elseif inputs == 3 or inputs == 4 then
- toplabel = labels.four[i]
- end
- txt(x+2+i*xspace,y,toplabel,colors.lime)
- end
- for i = 1, tbl.row do
- local sidelabel
- if inputs == 2 or inputs == 3 then
- sidelabel = labels.two[i]
- elseif inputs == 4 then
- sidelabel = labels.four[i]
- end
- txt(x+2,y+i*yspace,sidelabel,colors.lime)
- end
- for i = 1, tbl.row do
- local offset = (i-1)*tbl.col
- for h = 1, tbl.col do
- local index = offset+h
- txt( x+2+h*xspace, y+i*yspace, val(results[indexTable[index]][k]) )
- end
- end
- end
- end
- local function binaryToTen(list,s,length)
- if not s then s = 1 end
- if not length then length = 4 end
- local result = 0
- if list[s] == true or list[s] == 1 or list[s] == "1" then
- result = result + 1
- end
- if list[s+1] == true or list[s+1] == 1 or list[s+1] == "1" then
- result = result + 2
- end
- if list[s+2] == true or list[s+2] == 1 or list[s+2] == "1" then
- result = result + 4
- end
- if list[s+3] == true or list[s+3] == 1 or list[s+3] == "1" then
- result = result + 8
- end
- if length == 5 then
- if list[s+4] then
- if list[s+4] == 1 or list[s+4] == "1" or list[s+4] == true then
- result = result + 16
- end
- end
- end
- return result
- end
- local function drawTruthTable(x,y,results,tArgs,btable)
- local inputs = tonumber(tArgs[1])
- local length = #results
- --Draw input labels
- for i = 1, inputs do
- txt(x-2+i*2,y,utf8.char(96+i))
- end
- --Draw inputs
- if #tArgs == 1 then
- for i = 1, inputs do
- for j = 1, length do
- txt(x-2+i*2,y+j+1,val(btable[i][j]))
- end
- end
- end
- --Not sure tbh
- for i = 1, length do
- txt(inputs*2+x-1,y+i+1,":",colors.green)
- end
- --Draw results and result labels
- for i = 1, #results[1] do
- local x = x+(i-1)*2
- txt(inputs*2 + (i)*2,y,i,colors.orange)
- for k = 1, length do
- txt(x+inputs*2+1,y+k+1,val(results[k][i]),colors.green)
- end
- end
- end
- local function updateCursor(list,cursor)
- local _, key = os.pullEvent("key")
- local choice = false
- if key == keys.left then
- if cursor > 1 then
- cursor = cursor - 1
- end
- elseif key == keys.right then
- if cursor < #list then
- cursor = cursor + 1
- end
- elseif key == keys.up or key == keys.down then
- choice = tonumber(cursor)
- end
- return cursor,choice
- end
- local function drawOptionsList(x,y,cursor,list)
- for i = 1, #list do
- local j = i-1
- local cursCol = colors.white
- local ctop = " "
- local cbot = " "
- if i == cursor then
- ctop,cbot = "v","^"
- cursCol = colors.lime
- end
- txt(x+(j*2),y-1,ctop,cursCol)
- txt(x+(j*2),y+1,cbot,cursCol)
- txt(x+(j*2),y,val(list[i][1]),colors.white)
- end
- end
- local function makeNode(x,y,logic,count)
- return {
- id = count + 1,
- x,
- y,
- inputs = {},
- outputs = {},
- logic = logic,
- }, count + 1
- end
- local function getMouseEvent()
- local eventData = {}
- while eventData[1] ~= "mouse_click" and eventData[1] ~= "mouse_drag" and eventData[1] ~= "mouse_up" do
- eventData = {os.pullEvent()}
- end
- return eventData
- end
- local function makeButton(x,y,name,logic,logicList)
- return {
- x = x,
- y = y,
- name = name,
- logic = logicList[logic]
- }
- end
- local function drawNode(x,y,b,col,col2)
- txt(x,y,"[",col2)
- txt(x+#b.name+1,y,"]",col2)
- txt(x+1,y,b.name,col)
- end
- local function mouseDebug(x,y,active,ml,cursx,cursy)
- for i = 1, #ml do
- local drawColor = colors.white
- if active == i then
- drawColor = colors.green
- end
- txt(x,y+i-1,ml[i],drawColor)
- end
- local drawString = "X: "..cursx..", Y: "..cursy
- local clearString = ""
- for i = 1, #drawString+5 do
- clearString = clearString.." "
- end
- txt(x,y+#ml,clearString)
- txt(x,y+#ml,drawString)
- end
- term.clear()
- local btable = makeBooleanTables(tArgs)
- local results = processBooleanTables(btable, gates, ic)
- drawKarnaugh(17,3,results,tArgs)
- drawTruthTable(1,1,results,tArgs,btable)
- local adderCircuit = false --Set to true to show the binary --> decimal conversions
- if #tArgs > 1 then
- local cursor = 1
- while true do
- local choice = false
- while choice == false do
- drawOptionsList(1,3,cursor,btable)
- cursor,choice = updateCursor(btable,cursor)
- end
- if btable[cursor][1] == true then
- btable[cursor][1] = false
- else
- btable[cursor][1] = true
- end
- local results = processBooleanTables(btable, gates, ic)
- drawTruthTable(1,1,results,tArgs,btable)
- if adderCircuit == true then
- local boolList = {}
- for i = 1, #btable do
- boolList[i] = btable[i][1]
- end
- txt(1,20,textutils.serialise(results))
- txt(27,5, binaryToTen(results[1],1,5).." ", colors.orange)
- local result4 = binaryToTen(results[1],1,4)
- txt(23,6, result4.." ", colors.yellow)
- txt(23,7, "16-"..result4.." = "..(16-result4).." ", colors.yellow)
- txt(4,5, binaryToTen(boolList,2,4).." ", colors.green)
- txt(16,5, binaryToTen(boolList,6,4).." ", colors.green)
- end
- end
- end
- --[[
- local nodeList = {}
- local w,h = term.getSize()
- local buttonY = 12
- local buttonList = {
- makeButton(1,buttonY,"AND","gand",gates),
- makeButton(1,buttonY+2,"OR","gor",gates),
- makeButton(1,buttonY+4,"XOR","gxor",gates),
- makeButton(1,buttonY+6,"INV","ginv",gates),
- makeButton(1,buttonY+8,"FADD","fadd",ic),
- }
- local buttonPosList = {}
- for i = 1, #buttonList do
- local b = buttonList[i]
- drawNode(b.x,b.y,b,colors.white,colors.orange)
- buttonPosList[i] = {
- x1 = b.x,
- x2 = b.x+#b.name+1,
- y = b.y,
- }
- end
- local mouseDebugList = {
- "Waiting",
- "Click",
- "Pressed",
- "Release"
- }
- local mdx = 1
- local mdy = 31
- local active = 1
- while true do
- for i = 1, #buttonList do
- local b = buttonList[i]
- drawNode(b.x,b.y,b,colors.white,colors.orange)
- end
- active = 1
- mouseDebug(mdx,mdy,active,mouseDebugList,"..","..")
- local eventData = getMouseEvent()
- local event,type,x,y = eventData[1],eventData[2],eventData[3],eventData[4]
- local bChoice
- if type == 1 then
- if event == "mouse_click" then
- active = 2
- mouseDebug(mdx,mdy,active,mouseDebugList,x,y)
- for i = 1, #buttonPosList do
- local b = buttonPosList[i]
- txt(1,27,"Checking button: "..i.." ")
- txt(1,28,"Cursor pos @ click: "..x..", "..y.." ")
- txt(1,29,"Button coords: "..b.x1..", "..b.x2..", "..b.y.." ")
- if x >= b.x1 and x <= b.x2 and y == b.y then
- bChoice = i
- txt(1,27,"Picked button: "..i.." ",colors.orange)
- local b = buttonList[i]
- drawNode(b.x,b.y,b,colors.green,colors.orange)
- break
- end
- end
- for i = 1, #buttonList do
- end
- local eventData = {}
- while eventData[1] ~= "mouse_up" do
- eventData = getMouseEvent()
- local event,type,x,y = eventData[1],eventData[2],eventData[3],eventData[4]
- if event == "mouse_drag" then
- active = 3
- mouseDebug(mdx,mdy,active,mouseDebugList,x,y)
- end
- end
- active = 4
- mouseDebug(mdx,mdy,active,mouseDebugList,x,y)
- sleep(0.1)
- end
- end
- end
- ]]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement