This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
campicus's profile picture

Advanced Redpulse (Working But Could Have Been Written Better?)

Started by campicus, 26 July 2013 - 02:04 AM
campicus #1
Posted 26 July 2013 - 04:04 AM
An advanced than you to all the helpful lua geniuses out there for taking the time to help us noobs!

Basically, I modified redpulse so that you can select multiple sides to pulse. Also gives an option to loop forever.

It works perfectly but I can't help but thinking there was a much easier way to do this. Anyone have any ideas? I'm fairly new to lua.


local tArgs = { ... }
local nSides = tonumber(tArgs[1])
if not nSides then
  print("Usage: pulser <number of sides> <count> <period>")
  return
end
local nCount = tonumber(tArgs[2]) or 1
local nPeriod = tonumber(tArgs[3]) or 1
function sSides()
  if nSides == 1 then
    term.clear()
    term.setCursorPos(1,1)
    print("What side?")
    sSide1 = io.read()
    sSide2 = sSide1
    sSide3 = sSide1
    sSide4 = sSide1
    sSide5 = sSide1
    sSide6 = sSide1
    sSide7 = sSide1
    sSide8 = sSide1
  elseif nSides == 2 then
    term.clear()
    term.setCursorPos(1,1)
    term.clear()
    print("What side?")
    sSide1 = io.read()
    term.clear()
    term.setCursorPos(1,1)
    print("What side?")
    sSide2 = io.read()
    sSide3 = sSide1
    sSide4 = sSide1
    sSide5 = sSide1
    sSide6 = sSide1
    sSide7 = sSide1
    sSide8 = sSide1
  elseif nSides == 3 then
    term.clear()
    term.setCursorPos(1,1)
    print("What side?")
    sSide1 = io.read()
    term.clear()
    term.setCursorPos(1,1)
    print("What side?")
    sSide2 = io.read()
    term.clear()
    term.setCursorPos(1,1)
    print("What side?")
    sSide3 = io.read()
    sSide4 = sSide1
    sSide5 = sSide1
    sSide6 = sSide1
    sSide7 = sSide1
    sSide8 = sSide1
  elseif nSides == 4 then
    term.clear()
    term.setCursorPos(1,1)
    print("What side?")
    sSide1 = io.read()
    term.clear()
    term.setCursorPos(1,1)
    print("What side?")
    sSide2 = io.read()
    term.clear()
    term.setCursorPos(1,1)
    print("What side?")
    sSide3 = io.read()
    term.clear()
    term.setCursorPos(1,1)
    print("What side?")
    sSide4 = io.read()
    sSide5 = sSide1
    sSide6 = sSide1
    sSide7 = sSide1
    sSide8 = sSide1
  elseif nSides == 5 then
    term.clear()
term.setCursorPos(1,1)
print("What side?")
sSide1 = io.read()
term.clear()
term.setCursorPos(1,1)
print("What side?")
sSide2 = io.read()
term.clear()
term.setCursorPos(1,1)
print("What side?")
sSide3 = io.read()
term.clear()
term.setCursorPos(1,1)
print("What side?")
sSide4 = io.read()
term.clear()
term.setCursorPos(1,1)
print("What side?")
sSide5 = io.read()
sSide6 = sSide1
sSide7 = sSide1
sSide8 = sSide1
  elseif nSides == 6 then
term.setCursorPos(1,1)
print("What side?")
sSide1 = io.read()
term.clear()
term.setCursorPos(1,1)
print("What side?")
sSide2 = io.read()
term.clear()
term.setCursorPos(1,1)
print("What side?")
sSide3 = io.read()
term.clear()
term.setCursorPos(1,1)
print("What side?")
sSide4 = io.read()
term.clear()
term.setCursorPos(1,1)
print("What side?")
sSide5 = io.read()
term.clear()
term.setCursorPos(1,1)
print("What side?")
sSide6 = io.read()
sSide7 = sSide1
sSide8 = sSide1
  elseif nSides == 7 then
term.setCursorPos(1,1)
print("What side?")
sSide1 = io.read()
term.clear()
term.setCursorPos(1,1)
print("What side?")
sSide2 = io.read()
term.clear()
term.setCursorPos(1,1)
print("What side?")
sSide3 = io.read()
term.clear()
term.setCursorPos(1,1)
print("What side?")
sSide4 = io.read()
term.clear()
term.setCursorPos(1,1)
print("What side?")
sSide5 = io.read()
term.clear()
term.setCursorPos(1,1)
print("What side?")
sSide6 = io.read()
term.clear()
term.setCursorPos(1,1)
print("What side?")
sSide7 = io.read()
sSide8 = sSide1
  elseif nSides == 8 then
term.setCursorPos(1,1)
print("What side?")
sSide1 = io.read()
term.clear()
term.setCursorPos(1,1)
print("What side?")
sSide2 = io.read()
term.clear()
term.setCursorPos(1,1)
print("What side?")
sSide3 = io.read()
term.clear()
term.setCursorPos(1,1)
print("What side?")
sSide4 = io.read()
term.clear()
term.setCursorPos(1,1)
print("What side?")
sSide5 = io.read()
term.clear()
term.setCursorPos(1,1)
print("What side?")
sSide6 = io.read()
term.clear()
term.setCursorPos(1,1)
print("What side?")
sSide7 = io.read()
term.clear()
term.setCursorPos(1,1)
print("What side?")
sSide8 = io.read()
  elseif nSides > 8 then
term.clear()
term.setCursorPos("Invalid number of sides!")
sleep(0.5)
os.reboot()
  end
end
function pulser()
  redstone.setOutput( sSide1, true )
  redstone.setOutput( sSide2, true )
  redstone.setOutput( sSide3, true )
  redstone.setOutput( sSide4, true )
  redstone.setOutput( sSide5, true )
  redstone.setOutput( sSide6, true )
  redstone.setOutput( sSide7, true )
  redstone.setOutput( sSide8, true )
  sleep( nPeriod / 2 )
  redstone.setOutput( sSide1, false )
  redstone.setOutput( sSide2, false )
  redstone.setOutput( sSide3, false )
  redstone.setOutput( sSide4, false )
  redstone.setOutput( sSide5, false )
  redstone.setOutput( sSide6, false )
  redstone.setOutput( sSide7, false )
  redstone.setOutput( sSide8, false )
  sleep( nPeriod / 2 )
end
sSides()
if nCount == 0  then
  while true do
    pulser()
  end
else
  for x = 1,nCount do
    pulser()
  end
end
LBPHacker #2
Posted 26 July 2013 - 05:06 AM
local args = {...}
local count, period, sides
if not args[1] then or args[1] == "?" then
    print("usage: pulser <count> <period> [side1 ... sideN]")
    print(" pulse endlessly by setting count to 0")
    print(" pass multiple sides delimited by spaces:")
    print("   eg. pulser 10 1 left right top")
    return
else
    count = tonumber(args[1])
    period = tonumber(args[2])
    sides = unpack(args, 3)
end
if not count then error("invalid count") end
if not period then error("invalid period") end
local availableSides = rs.getSides()
local associatedSides = {}
for ixSide = 1, #availableSides do associatedSides[availableSides[ixSide]] = true end
for ixSide = 1, #sides do if not associatedSides[sides[ixSide]] then error("invalid side" .. tostring(ixSide) .. ": " .. sides[ixSide]) end end
local pulse = function()
    for ixSide = 1, #sides do rs.setOutput(sides[ixSide], true) end
    sleep(period / 2)
    for ixSide = 1, #sides do rs.setOutput(sides[ixSide], false) end
    sleep(period / 2)
end
if count == 0 then while true do pulse() end else for ixPulse = 1, count do pulse() end end
WARNING: Not tested.

Tell me if you want me to explain.
campicus #3
Posted 26 July 2013 - 05:16 AM
I have no idea what these lines mean. I don't know anything about tables so… that might be why? lol


local associatedSides = {}
for ixSide = 1, #availableSides do
  associatedSides[availableSides[ixSide]] = true
end
for ixSide = 1, #sides do
  if not associatedSides[sides[ixSide]] then
    error("invalid side" .. tostring(ixSide) .. ": " .. sides[ixSide])
  end
end
LBPHacker #4
Posted 26 July 2013 - 05:32 AM
That part checks if every side is valid. rs.getSides() returns a table that contains all the sides of the computer. Something like {"top", "bottom", "front", "back", "left", "right"}. If I wanted to check the sides given by the user using only that, I'd have to use two cycles:
local availableSides = rs.getSides()
local sides = {} -- whatevery given by the user
for ixSides = 1, #sides do
    local valid = false
    for ixRSSides = 1, #availableSides do
        valid = availableSides[ixRSSides] == sides[ixSides] or valid
    end
    if not valid then error("...") end
end
Thing is, I don't like doing that. Let's inspect the table returned by rs.getSides() It has 6 indexes, every one of them is numeric. That means:
local sides = rs.getSides()
print(sides[1]) -- will print "top"
print(sides[5]) -- will print "left"
So the table could be declared like this as well:
sides = {
    [1] = "top",
    [2] = "bottom",
    ... etc.
BUT - and here comes the magic - tables don't only have numeric indexes. Actually, every kind of variable can make an index in a table - as well as a string:
local a = {["z"] = 8, ["y"] = 7}
print(a["z"]) -- will print 8
By the way, if the index is a string, and it is a plain one like "z" which could easily be a real variable name, we can use it without the brackets:
print(a.z) -- will print 8 as well
That doesn't work if the string index has eg. a space in it.
Again, by the way, the good old APIs work like that as well. term.write is the same as term["write"].

So, what I did there with the sides. If you look over the code with this new knowledge, you may realise that associatedSides is a table, and it's something like this:
local associatedSides = {

    ["top"] = true,
    ["bottom"] = true,
    ["front"] = true,
    ["back"] = true,
    ["left"] = true,
    ["right"] = true
}
If the user gave a valid side, then if I use that side to index associatedSides, eg. associatedSides["top"], I'll get true. Otherwise I'll get nil, and then the program errors out.
campicus #5
Posted 26 July 2013 - 07:38 AM
Thanks for that :)/> Making more sense now!
Zudo #6
Posted 26 July 2013 - 09:12 AM
Please use pastebin :)/>

There is a whole forum for programs and you put this in Ask a pro :D/>
campicus #7
Posted 28 July 2013 - 10:18 PM
I put it here because I didn't want to showcase my code, I was more asking how I 'should' have written it haha

Will use pastebin from now on, sorry :)/>