Advertisement
cragrim

GateSim - Logical Gate Simulator

Jul 26th, 2013
170
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 11.07 KB | None | 0 0
  1. -----------------------------------------------
  2. --LOGICAL GATE/FLIP-FLOP SIMULATOR BY CRAGRIM--
  3. -----------------------------------------------
  4. --INSTRUCTIONS--
  5. --http://www.promethea-ftb.com/index.php?threads/cragrims-computercraft-thread.639/#post-2881
  6. ----------------
  7. --DECLARATIONS--
  8. ----------------
  9.  
  10. --version
  11. local strVersion = "0.2"
  12.  
  13. --get command line arguments in a table
  14. local tblArgs = { ... }
  15.  
  16. --count number of elements in the argument table
  17. local intArgsCount = 0 --declare it empty
  18. if next(tblArgs) == nil then
  19.    --check if table is empty (do nothing)
  20. else
  21.     --for each element add 1
  22.     for _ in pairs(tblArgs) do
  23.         intArgsCount = intArgsCount + 1
  24.     end
  25. end
  26.  
  27. --has an error occured?
  28. local bolErr = false
  29.  
  30. --get the name of the program if named other than "gatesim"
  31. local GATESIM = shell.getRunningProgram()
  32.  
  33. --default latch state off
  34. local latch_memory = "0"
  35.  
  36. --declare special characters to avoid misshaps
  37. strLP = [[(]] --left parentheses
  38. strRP = [[)]] --right parentheses
  39. strQ = [["]] --doublequote
  40.  
  41. -------------
  42. --FUNCTIONS--
  43. -------------
  44.  
  45.     -------------------
  46.     --STRING HANDLING--
  47.     -------------------
  48.  
  49. --Put quotes around this
  50. function strQuote(this)
  51.     return strQ..this..strQ
  52. end
  53.  
  54.  
  55. --Put parentheses around that
  56. function strParen(that)
  57.     return strLP..that..strRP
  58. end
  59.    
  60.     ----------------------
  61.     --COSMETIC FUNCTIONS--
  62.     ----------------------
  63.  
  64. function ClearScreen()
  65.     term.clear()
  66.     term.setCursorPos(1,1)
  67. end
  68.  
  69. function Pause()
  70.     write("Press any key to continue...")
  71.     read()
  72. end
  73.  
  74.     ---------------------------------
  75.     --STARTUP INFORMATIVE FUNCTIONS--
  76.     ---------------------------------
  77.  
  78. --Print information about current gate
  79. function StartInfo(gateType,gateDescription)
  80.     ClearScreen()
  81.     print("LOGICAL GATE/FLIP-FLOP SIMULATOR BY CRAGRIM")
  82.     print("Program Version: "..strVersion)
  83.     print("Computer Label: "..ComputerLabel())
  84.     print("")
  85.     print("CURRENTLY SIMULATING: "..gateType)
  86.     print(gateDescription)
  87.     print("")
  88.     print("InputA: "..strInputA)
  89.     print("InputB: "..strInputB)
  90.     print("OutputA: "..strOutputA)
  91.     print("OutputB: "..strOutputB)
  92.     print("Variable: "..strVariable1)
  93.     print("")
  94.     SaveGateSetting(gateType)
  95.     if bolErr == false then
  96.         print("")
  97.         print("Program is now running! Hold CTRL+T to abort...")
  98.     end
  99. end
  100.  
  101. --Print information if no gate was entered
  102. function PrintDescription()
  103.     ClearScreen()
  104.     print("LOGICAL GATE/FLIP-FLOP SIMULATOR BY CRAGRIM")
  105.     print("Program Version: "..strVersion)
  106.     print("Computer Label: "..ComputerLabel())
  107.     print("")
  108.     print("AVAILABLE GATE FUNCTIONS:")
  109.     print("not, and, nand, or, nor, xor, xnor, rslatch, tflipflop, timer")
  110.     print("")
  111.     print("SYNTAX:")
  112.     print(GATESIM.." [Gate] [InpA] [InpB] [OutA] [OutB] [Var]")
  113.     print(strParen("Saves the setting after reboot"))
  114.     print("")
  115.     print("EXAMPLES:")
  116.     print(GATESIM.." AND")
  117.     print(GATESIM.." XOR left front back")
  118.     print(GATESIM.." RSLATCH left right back front")
  119.     print(GATESIM.." TIMER left right back front 2")
  120. end
  121.  
  122.  
  123.     -------------
  124.     --FUNCTIONS--
  125.     -------------
  126.  
  127. function SaveGateSetting(fnName)
  128.     --Declare startup string to automatically launch gate program with side arguments on computer reboot
  129.     local strStartup = "shell.run"..strParen(strQuote(GATESIM)..","..strQuote(fnName)..","..strQuote(strInputA)..","..strQuote(strInputB)..","..strQuote(strOutputA)..","..strQuote(strOutputB)..","..strQuote(strVariable1))
  130.    
  131.     --Write to startup program
  132.     local fileWrite = fs.open ("startup", "w")
  133.     fileWrite.write(strStartup)
  134.     fileWrite.close()
  135.     write("Saving settings to startup...")
  136.    
  137.     --Read the startup program to make sure it was actually saved, this is sometimes skipped on servers
  138.     local fileRead=fs.open("startup", "r")
  139.     if fileRead.readAll() == strStartup then
  140.         print(" success!")
  141.     else
  142.         print(" writing error!")
  143.         bolErr = true
  144.     end
  145.     fileRead.close()
  146. end
  147.  
  148. --Save latch memory
  149. function SaveState(num)
  150.     if num == "1" then
  151.         local fileWrite = fs.open ("latch_memory", "w")
  152.         fileWrite.write("1")
  153.         fileWrite.close()
  154.     else
  155.         local fileWrite = fs.open ("latch_memory", "w")
  156.         fileWrite.write("0")
  157.         fileWrite.close()
  158.     end
  159. end
  160.  
  161. --Load latch memory
  162. function LoadState()
  163.     if fs.exists("latch_memory") then
  164.         local fileRead=fs.open("latch_memory", "r")
  165.         temp_mem = fileRead.readAll()
  166.        
  167.         if temp_mem == "1" then
  168.             return "1"
  169.         else
  170.             return "0"
  171.         end
  172.         fileRead.close()
  173.     else
  174.         SaveState("0")
  175.     end
  176. end
  177.  
  178.     ----------------------------
  179.     --ERROR CHECKING FUNCTIONS--
  180.     ----------------------------
  181.  
  182. --Wait for this to happen before updating in order to avoid lag
  183. --Add more pullevents to reduce lag even more (I can't think of any more though)
  184. function WaitForMe()
  185.     os.pullEvent("redstone") --wait for a "redstone" event
  186. end
  187.  
  188. --Check if the argument for side is valid or not
  189. function CheckValidSide(mySide, defaultSide)
  190.     if mySide ~= "" then
  191.         count = 0
  192.         --Go through the list of valid sides
  193.         for k,v in pairs(rs.getSides()) do
  194.             if mySide == v then
  195.                 count = count + 1
  196.             end
  197.         end
  198.        
  199.         if count > 0 then
  200.             --The side is OK
  201.             return mySide
  202.         else
  203.             --The side is not OK, use default instead
  204.             return defaultSide
  205.         end
  206.     end
  207.     --No argument added, use default
  208.     return defaultSide
  209. end
  210.  
  211.  
  212. --Make sure you have set a computer label.. if not then automatically assign a random label
  213. function ComputerLabel()
  214.     if os.getComputerLabel() == nil then
  215.         os.setComputerLabel("SomeComputer"..math.random(0,99999))
  216.         return os.getComputerLabel()
  217.     else
  218.         return os.getComputerLabel()
  219.     end
  220. end
  221.  
  222. --Make sure that the entered value is an integer
  223. function TypeCheck(number)
  224.     number = tonumber(number)
  225.     if type(number) ~= "number" then
  226.         return 2
  227.     else
  228.         return number
  229.     end
  230. end
  231.  
  232.  
  233. ---------------------------
  234. --INPUT/OUTPUT ASSIGNMENT--
  235. ---------------------------
  236.  
  237. --Assign input/output sides so that you can easily change this if you want
  238. --Available: left/right/back/front/bottom/top
  239. --I plan to maybe make configurable with additional input/outputs in the future, for now this will have to do
  240.  
  241. --gatesim [GateType]  [InputA]    [InputB]    [OutputA]    [OutputB]
  242. --        tblArgs[1]  tblArgs[2]  tblArgs[3]  tblArgs[4]   tblArgs[5]
  243. --                    "left"      "right"     "back"       "front"
  244.  
  245. --Make sure the sides are valid
  246. strInputA = CheckValidSide(tblArgs[2], "left")
  247. strInputB = CheckValidSide(tblArgs[3], "right")
  248. strOutputA = CheckValidSide(tblArgs[4], "back")
  249. strOutputB = CheckValidSide(tblArgs[5], "front")
  250. strVariable1 = TypeCheck(tblArgs[6])
  251.  
  252. function InputA()
  253.     return rs.getInput(strInputA)
  254. end
  255.  
  256. function InputB()
  257.     return rs.getInput(strInputB)
  258. end
  259.  
  260. function OutputA(set)
  261.     return rs.setOutput(strOutputA, set)
  262. end
  263.  
  264. --This is not always used
  265. function OutputB(set)
  266.     return rs.setOutput(strOutputB, set)
  267. end
  268.  
  269.  
  270. ----------------------------
  271. --GATE SIMULATION PROGRAMS--
  272. ----------------------------
  273.  
  274.  
  275. if tblArgs[1] == "AND" or tblArgs[1] == "and" then
  276.     --Program AND
  277.     StartInfo("AND","[OutA] is ON when [InpA] AND [InpB] is ON")
  278.     while bolErr == false do
  279.         WaitForMe()
  280.         if InputA() == true and InputB() == true then
  281.             OutputA(true)
  282.         else
  283.             OutputA(false)
  284.         end
  285.     end
  286.  
  287. elseif tblArgs[1] == "NAND" or tblArgs[1] == "nand" then
  288.     --Program NAND
  289.     StartInfo("NAND","[OutA] is OFF when [InpA] AND [InpB] is ON")
  290.     while bolErr == false do
  291.         WaitForMe()
  292.         if InputA() == true and InputB() == true then
  293.             OutputA(false)
  294.         else
  295.             OutputA(true)
  296.         end
  297.     end
  298.  
  299. elseif tblArgs[1] == "OR" or tblArgs[1] == "or" then
  300.     --Program OR
  301.     StartInfo("OR","[OutA] is ON when [InpA] OR [InpB] is ON")
  302.     while bolErr == false do
  303.         WaitForMe()
  304.         if InputA() == true or InputB() == true then
  305.             OutputA(true)
  306.         else
  307.             OutputA(false)
  308.         end
  309.     end
  310.    
  311. elseif tblArgs[1] == "NOR" or tblArgs[1] == "nor" then
  312.     --Program OR
  313.     StartInfo("NOR","[OutA] is OFF when [InpA] OR [InpB] is ON")
  314.     while bolErr == false do
  315.         WaitForMe()
  316.         if InputA() == true or InputB() == true then
  317.             OutputA(false)
  318.         else
  319.             OutputA(true)
  320.         end
  321.     end
  322.    
  323. elseif tblArgs[1] == "XOR" or tblArgs[1] == "xor" then
  324.     --Program XOR
  325.     StartInfo("XOR","[OutA] is ON when [InpA] and [InpB] is odd")
  326.     while bolErr == false do
  327.         WaitForMe()
  328.         if InputA() == false and InputB() == false then
  329.             OutputA(false)
  330.         elseif InputA() == true and InputB() == true then
  331.             OutputA(false)
  332.         else
  333.             OutputA(true)
  334.         end
  335.     end
  336.    
  337. elseif tblArgs[1] == "XNOR" or tblArgs[1] == "xnor" then
  338.     --Program XNOR
  339.     StartInfo("XNOR","[OutA] is OFF when [InpA] and [InpB] is odd")
  340.     while bolErr == false do
  341.         WaitForMe()
  342.         if InputA() == false and InputB() == false then
  343.             OutputA(true)
  344.         elseif InputA() == true and InputB() == true then
  345.             OutputA(true)
  346.         else
  347.             OutputA(false)
  348.         end
  349.     end
  350.    
  351. elseif tblArgs[1] == "TIMER" or tblArgs[1] == "timer" then
  352.     --Program NOT
  353.     StartInfo("TIMER","Pulses with [Var] delay when [InpA] is OFF")
  354.     while bolErr == false do
  355.         if InputA() == false then
  356.             OutputA(true)
  357.             sleep(strVariable1)
  358.             OutputA(false)
  359.             sleep(strVariable1)
  360.         else
  361.             OutputA(false)
  362.             WaitForMe()
  363.         end
  364.     end
  365.    
  366. elseif tblArgs[1] == "NTIMER" or tblArgs[1] == "ntimer" then
  367.     --Program NOT
  368.     StartInfo("NTIMER","Pulses with [Var] delay when [InpA] is ON")
  369.     while bolErr == false do
  370.         if InputA() == false then
  371.             OutputA(false)
  372.             WaitForMe()
  373.         else
  374.             OutputA(true)
  375.             sleep(strVariable1)
  376.             OutputA(false)
  377.             sleep(strVariable1)
  378.         end
  379.     end
  380.    
  381. elseif tblArgs[1] == "NOT" or tblArgs[1] == "not" then
  382.     --Program NOT
  383.     StartInfo("NOT","[OutA] is ON when [InpA] is OFF")
  384.     while bolErr == false do
  385.         WaitForMe()
  386.         if InputA() == false then
  387.             OutputA(true)
  388.         else
  389.             OutputA(false)
  390.         end
  391.     end
  392.  
  393. elseif tblArgs[1] == "RSLATCH" or tblArgs[1] == "rslatch" or tblArgs[1] == "rsnorlatch" or tblArgs[1] == "RSNORLATCH" then
  394.     --Program RS Latch
  395.     StartInfo("RSLATCH","[OutA] is STORED as ON when [InpA] is ON or STORED as OFF when [InptB] is ON. [OutB] is odd to [OutA]")
  396.     while bolErr == false do
  397.         --Load previous memory
  398.         if LoadState() == "1" then
  399.             OutputA(true)
  400.             OutputB(false)
  401.         else
  402.             OutputA(false)
  403.             OutputB(true)
  404.         end
  405.        
  406.         WaitForMe()
  407.        
  408.         if InputA() == true then
  409.             SaveState("1")
  410.         elseif InputB() == true then
  411.             SaveState("0")
  412.         end
  413.     end
  414.    
  415. elseif tblArgs[1] == "FLIPFLOP" or tblArgs[1] == "flipflop" or tblArgs[1] == "TFLIPFLOP" or tblArgs[1] == "tflipflop" then
  416.     --Program RS Latch
  417.     StartInfo("TFLIPFLOP","[OutA] toggles ON/OFF when [InpA] or [InpB] pulses. [OutB] is odd to [OutA]")
  418.     while bolErr == false do
  419.         --Load previous memory
  420.         if LoadState() == "1" then
  421.             OutputA(true)
  422.             OutputB(false)
  423.         else
  424.             OutputA(false)
  425.             OutputB(true)
  426.         end
  427.        
  428.         while InputA() or InputB()  == true do
  429.             sleep(1.0) --sleep 1 tick
  430.         end
  431.        
  432.         WaitForMe()
  433.        
  434.         if InputA() == true or InputB() == true then
  435.             if LoadState() == "1" then
  436.                 SaveState("0")
  437.                 --WaitForMe()
  438.             else
  439.                 SaveState("1")
  440.                 --WaitForMe()
  441.             end
  442.         end
  443.        
  444.         --os.sleep(1)
  445.        
  446.     end
  447.  
  448. else
  449.     --Print instructions
  450.     PrintDescription()
  451. end
  452.  
  453. --Some kind of error occured
  454. if bolErr == true then
  455.     print("An error occurred... program failed.")
  456.     print("Please check your server settings or try again.")
  457. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement