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

Whats the easiest way to pull a random function from a supplied list?

Started by welwyn, 21 June 2012 - 12:49 PM
welwyn #1
Posted 21 June 2012 - 02:49 PM
Whats the easiest way to pull a random function from a supplied list?

I'm trying to get a random function to run, out of a list of a few.

so far the thought plan has been..

function L01()
rs.setBundledOutput("back",0)
sleep(0.5)
end
function L02()
rs.setBundledOutput("back",colors.red)
sleep(0.5)
end
function L03()
rs.setBundledOutput("back",colors.blue)
sleep(0.5)
end
function L04()
rs.setBundledOutput("back",colors.yellow)
sleep(0.5)
end


And so on, for all possible colours attatched. I'm also looking to add in multiples, but thats for later :P/>/>

From here I'd like to be able to do a

random(L01(),L02(),L03(),L04())

and have it run the function it picks at random.
Now, after looking fairly hard, all I can find is math.random() – which for my example would be math.random(1,4)
But to use this I'd need to have it as something like…

x = math.random(1,4)
function runrandom()
if x = 1 then
L01()
elseif x = 2 then
L02()
elseif x =3 then
L03()
elseif x=4 then
Lo4()
else os.shutdown
end
end


Then to call a random function out of L01 through to L04 I would just do a

runrandom()


Now, would this work? if not, can you give me any pointers or hints on how to do so?
If this does work, any way I can tidy it up? XD

Thanks a bunch, and thanks to the creators, this is good fun to mess with :)/>/>
tfoote #2
Posted 21 June 2012 - 02:55 PM
Try This:

while true do -- I don't know if you want a loop but here it is... If you don't want it remove this line and the last line. Or you could make it conditional.
function L01()
rs.setBundledOutput("back",0)
sleep(0.5)
end
function L02()
rs.setBundledOutput("back",colors.red)
sleep(0.5)
end
function L03()
rs.setBundledOutput("back",colors.blue)
sleep(0.5)
end
function L04()
rs.setBundledOutput("back",colors.yellow)
sleep(0.5)
end
function runrandom()
x = math.random(1,4)
if x = 1 then
L01()
elseif x = 2 then
L02()
elseif x = 3 then
L03()
elseif x = 4 then
Lo4()
end
-- You had a few typos. Also i removed the os.shutdown(). While in the loop if it doesn't pick one it will restart and pick a different one.
runrandom()
end
kazagistar #3
Posted 21 June 2012 - 03:17 PM

function runrandom()
  local colorlist = {0, colors.red, colors.yellow, colors.blue}
  rs.setBundledOutput("back",colorlist[math.random(4)])
  sleep(0.5)
end

I made you a code. math.random(4) generates a number from 1 to 4, and list is automatically numbered 1 to 4. If you really really want to select functions for some reason you can put functions into a similar list, and use the same kind of random table selector.
welwyn #4
Posted 21 June 2012 - 03:26 PM
bios:206: [string "randomizer"]:23: 'then'
expected


This error came up when running yours tfoote. Looking it over it looks sound, but I just cant get it to work!

Btw, I'm new to LUA, and coding in general, I know a little javascript but thats very basic carients of it..
tfoote #5
Posted 21 June 2012 - 03:32 PM
1 sec… It looks like it has a problem with line 23 as said in the error. when you look at it is states L02()… When you go to the rs.API program I find that there is a typo i missed. Try this.
Spoiler

while true do -- I don't know if you want a loop but here it is... If you don't want it remove this line and the last line. Or you could make it conditional.
function L01()
rs.setBundledOutput("back", 0)
sleep(0.5)
end
function L02()
rs.setBundledOutput("back", colors.red)
sleep(0.5)
end
function L03()
rs.setBundledOutput("back", colors.blue)
sleep(0.5)
end
function L04()
rs.setBundledOutput("back", colors.yellow)
sleep(0.5)
end
function runrandom()
x = math.random(1,4)
if x = 1 then
L01()
elseif x = 2 then
L02()
elseif x = 3 then
L03()
elseif x = 4 then
Lo4()
end
-- You had a few typos. Also i removed the os.shutdown(). While in the loop if it doesn't pick one it will restart and pick a different one.
runrandom()
end
welwyn #6
Posted 21 June 2012 - 03:41 PM
Same error again only now its :24:

Bit more background info : Running on a tekkit server, I have no access to config files or the like, only a player not admin.

Also I wanted the os.shutdown() in there, so it shut the system down if there was ever an error. with the system shut down all redstone output ceases, and other systems shut down :P/>/> Its part of my nuclear reactor monitering thats why!
kazagistar #7
Posted 21 June 2012 - 03:50 PM
If you call a function using pcall() you can catch errors, and then just shutdown. Really though, what exactly is wrong with my code? If you really want something that will run a random function given as a param…

function randomFunction(...)
  arg[math.random(#arg)]()
end
Using … lets you pass in a list of parameters which is stored in "arg", and # gets the length of a numbered list.
tfoote #8
Posted 21 June 2012 - 03:55 PM
Same error again only now its :24:

Bit more background info : Running on a tekkit server, I have no access to config files or the like, only a player not admin.

Also I wanted the os.shutdown() in there, so it shut the system down if there was ever an error. with the system shut down all redstone output ceases, and other systems shut down :P/>/> Its part of my nuclear reactor monitering thats why!

1) It won't startup if there is an error in the code… but you can have it do this

while true do
local event, param1, param2, param3 = os.pullEvent()
if event == redstone then -- im not sure if redstone is the right word. Check the wiki
-- have if statements that can find where (if any) a problem is. Once you find it you can shutdown.
2) The problem with my code
Spoiler

while true do -- I don't know if you want a loop but here it is... If you don't want it remove this line and the last line. Or you could make it conditional.
function L01()
rs.setBundledOutput("back", 0)
sleep(0.5)
end
function L02()
rs.setBundledOutput("back", colors.red)
sleep(0.5)
end
function L03()
rs.setBundledOutput("back", colors.blue)
sleep(0.5)
end
function L04()
rs.setBundledOutput("back", colors.yellow)
sleep(0.5)
end
function runrandom()
x = math.random(1,4)
if x = 1 then
L01()
elseif x = 2 then
L02()
elseif x = 3 then
L03()
elseif x = 4 then
L04()
end
runrandom()
end
This time you had replaced an o when it needed to be 0.
welwyn #9
Posted 21 June 2012 - 03:59 PM
I fixed it, Rather than if x = 1 then its if x == 1 then. And so on for all numbers!
BigSHinyToys #10
Posted 21 June 2012 - 04:01 PM
why exactly do you want a random function. for a reactor it would make more scene to be following a strict order to function call's to lessen the chance of a catastrophic meltdown. just curious doesn't really need an answer
welwyn #11
Posted 21 June 2012 - 04:10 PM
its for a warning siren actually. I think a random cataphony of noise would alert me more than a constant siren.
welwyn #12
Posted 21 June 2012 - 04:13 PM
Ok new error popped up.

bios:15: vm error:
java.lang.ArrayIndexOutOfBoundsException: 256
tfoote #13
Posted 21 June 2012 - 04:13 PM
oh… that makes sense. you could use a os.pullEvent type of thing
welwyn #14
Posted 21 June 2012 - 04:45 PM
Ok I fixed the error, here is what I beleive to be finished code for the current functions needed.


function L01()
rs.setBundledOutput("back", 0)
sleep(0.5)
end
function L02()
rs.setBundledOutput("back", colors.red)
sleep(0.5)
end
function L03()
rs.setBundledOutput("back", colors.blue)
sleep(0.5)
end
function L04()
rs.setBundledOutput("back", colors.yellow)
sleep(0.5)
end
function runrandom()
x = math.random(1,4)
if x = 1 then
L01()
elseif x = 2 then
L02()
elseif x = 3 then
L03()
elseif x = 4 then
L04()
end
end
while true do
runrandom()
end
tfoote #15
Posted 21 June 2012 - 04:53 PM
no… sorry you are missing the ==

function L01()
rs.setBundledOutput("back", 0)
sleep(0.5)
end
function L02()
rs.setBundledOutput("back", colors.red)
sleep(0.5)
end
function L03()
rs.setBundledOutput("back", colors.blue)
sleep(0.5)
end
function L04()
rs.setBundledOutput("back", colors.yellow)
sleep(0.5)
end
function runrandom()
x = math.random(1,4)
if x == 1 then
L01()
elseif x == 2 then
L02()
elseif x == 3 then
L03()
elseif x == 4 then
L04()
end
end
while true do
runrandom()
end
EXAMPLE {
you had if x = 4 then…
it needs to be
if x == 4 then…
}
I fixed that… you should be good.
welwyn #16
Posted 21 June 2012 - 05:21 PM
no… sorry you are missing the ==

function L01()
rs.setBundledOutput("back", 0)
sleep(0.5)
end
function L02()
rs.setBundledOutput("back", colors.red)
sleep(0.5)
end
function L03()
rs.setBundledOutput("back", colors.blue)
sleep(0.5)
end
function L04()
rs.setBundledOutput("back", colors.yellow)
sleep(0.5)
end
function runrandom()
x = math.random(1,4)
if x == 1 then
L01()
elseif x == 2 then
L02()
elseif x == 3 then
L03()
elseif x == 4 then
L04()
end
end
while true do
runrandom()
end
EXAMPLE {
you had if x = 4 then…
it needs to be
if x == 4 then…
}
I fixed that… you should be good.

bugger, yes! i wrote == ingame, but typing it out here I forgot.
MysticT #17
Posted 21 June 2012 - 05:50 PM
Well, I don't think that's the best way to do it. It's better to do what kazagistar said, just that CC uses lua 5.1, not 5.2, so you need to store the arguments in a table:

local function runrandom(...)
  local tArgs = { ... }
  tArgs[math.random(#tArgs)]()
end
The complete code would be:

local function L01()
  rs.setBundledOutput("back", 0)
  sleep(0.5)
end

local function L02()
  rs.setBundledOutput("back", colors.red)
  sleep(0.5)
end

local function L03()
  rs.setBundledOutput("back", colors.blue)
  sleep(0.5)
end

local function L04()
  rs.setBundledOutput("back", colors.yellow)
  sleep(0.5)
end

local function runrandom(...)
  local tArgs = { ... }
  tArgs[math.random(#tArgs)]()
end

while true do
  runrandom(L01, L02, L03, L04)
end