Jump to content




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


  • You cannot reply to this topic
6 replies to this topic

#1 campicus

  • Members
  • 164 posts

Posted 26 July 2013 - 03: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


#2 LBPHacker

  • Members
  • 766 posts
  • LocationBudapest, Hungary

Posted 26 July 2013 - 04: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.

#3 campicus

  • Members
  • 164 posts

Posted 26 July 2013 - 04: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


#4 LBPHacker

  • Members
  • 766 posts
  • LocationBudapest, Hungary

Posted 26 July 2013 - 04: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.

#5 campicus

  • Members
  • 164 posts

Posted 26 July 2013 - 06:38 AM

Thanks for that :) Making more sense now!

#6 Zudo

  • Members
  • 800 posts
  • LocationUK

Posted 26 July 2013 - 08:12 AM

Please use pastebin :)

There is a whole forum for programs and you put this in Ask a pro :D

#7 campicus

  • Members
  • 164 posts

Posted 28 July 2013 - 09: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 :)





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users