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

My First Program Won't Work:(

Started by ivos97, 23 July 2013 - 05:28 AM
ivos97 #1
Posted 23 July 2013 - 07:28 AM
Im with friends on a server and we want an 30 minute countdown.

The code I got

x = 30

while rs.getInput("left") == true do
x = x - 1
print(x.. " till countdown")
sleep(60)
end

if x == 0 do
rs.setOutput("right", true)
sleep(4)
rs.setOutput("right", false)
end

else
shell.restart()

I havent got alot of expiriance with lua coding so i dont even know if it's supposed to work.

Can any1 help/redo my code?:)/>

Thanks in advance
H4X0RZ #2
Posted 23 July 2013 - 07:39 AM
First of all please use [Code] [/Code] tags.

To your code, the last if needs an end. f statements are constructed like this:

if condition then
  -Do something
elseif anotherCondition then
  --Do something else 
else 
  --Do some other tasks
end --close the statement
albrat #3
Posted 23 July 2013 - 07:41 AM

x = 30
while rs.getInput("left") == true do
  x = x - 1
  print(x.. " till countdown")
  sleep(60)

  if x == 0 do
    rs.setOutput("right", true)
    sleep(4)
    rs.setOutput("right", false)
  end
end

os.restart()

though it is better to do this


while true do
x = 30
while rs.getInput("left") == true do
  x = x - 1
  print(x.. " till countdown")
  sleep(60)
  if x == 0 do
    rs.setOutput("right", true)
    sleep(4)
    rs.setOutput("right", false)
  end
end
end
ivos97 #4
Posted 23 July 2013 - 09:36 AM
K I've edited the code, but it still wont work…


while rs.getInput("left") == true do
  x = x - 1
  print (x.. " Till countdown")
  sleep(60)
  if x == 0 then do
    rs.setOutput("right", true)
    sleep(4)
    rs.setOutput("right", false)
  end
end
end
end

the error it gives me says: "prog:3: Too long without yielding"

help?!? :D/>
KaoS #5
Posted 23 July 2013 - 10:11 AM
why an extra 2 ends? also you need to define x before the loop starts or it won't know what to subtract from. In the code given above you should not get a too long without yielding error. Are you sure you have the sleep(60) entered correctly in your code? also try restarting the terminal every time you test your code
ivos97 #6
Posted 23 July 2013 - 02:50 PM
I defined the "x" before the loop starts but it still won't work.
those 2 extra ends are needed for the code, tried with less but got the "expected "end" line 15" error
Kilobyte #7
Posted 23 July 2013 - 02:51 PM
why even

if x == 0 then do
if needs no do. you basicly made an infinite loop. let me restructure and fix it:


while rs.getInput("left") do -- you can pretty much always leave out == true.
  x = x - 1
  print (x.. " Till countdown")
  sleep(60)
  if x == 0 then -- here was a 'do' too much
	rs.setOutput("right", true)
	sleep(4)
	rs.setOutput("right", false)
  end
end
-- cut off 2 ends whch were too much

EDIT:
Also, i assume you defined x as local :P/> (you don't need to, but it makes your code look better and its better coding style.
Also, you should always make sure your code you post it a valid extract or, better, post your entire code. if its a large chunk use Gist or pastebin. Gist has the advantage of allowing you to have multiple files on one URL
ivos97 #8
Posted 23 July 2013 - 04:11 PM
'k so i've edited my code again and it still wont work.
The code I got so far .


x = 30

while rs.getInput("left") do
x = x - 1
print (x.. "Till countdown")
sleep(60)
if x == 0 then
   rs.setOutput("right", true)
   sleep(4)
   rs.setOutput("right", false)
   end
end

the code doesn't give me an error, it just won't do a thing..
albrat #9
Posted 23 July 2013 - 04:15 PM
I know why you get the too long without yielding… you are starting the terminal without a redstone signal.. which just starts the while true do x = 30 end… repeatedly.


while true do
  x = 30
  while rs.getinput("left") == false do
    sleep (1)
  end
  while rs.getInput("left") == true do
	x = x - 1
    term.setCursorPos(3,5) -- Always print on the same line
    term.clearLine() -- clear old items on the line
	print(x.. " till countdown") -- print our countdown timer time. every minute.
	sleep(60)
  end
	rs.setOutput("right", true)
	sleep(4)
	rs.setOutput("right", false)
end

This should catch both states of the RS input and do a timer for both, averting the "too long without yielding" error.

btw this script will sit there for 1 minute when the signal is active and do nothing other than 1 output to the screen.
ivos97 #10
Posted 23 July 2013 - 05:15 PM
We are almost there :)/>


while true do
x = 30
while rs.getInput("left") == false do
  term.setCursorPos(3,5)
  term.clearLine()
   print("Timer state = Off")
  sleep(1)
end
while rs.getInput("left") == true do
   x = x - 1
   term.setCursorPos(3,5)
   term.clearLine()
	 print(x.. " till countdown")
	 sleep(60)
   end
if x == 0 then
   rs.setOutput("right", true)
   sleep(4)
   rs.setOutput("right", false)
end
end

the thing is: at 30 minutes the redstone on the right side wont switch on.
and another thing is : the timer just counts further,,,
is there a way to shutdown the computer when the countdown reaches it max??

thanks !!
MR_nesquick #11
Posted 23 July 2013 - 05:51 PM
to shutdown the computer after it reached max add
'os.shutdown()' in the bottom of your 'if x == 0 then' statement

but if you want to start over again add
'x = 30' in your 'if x == 0 then' statement
albrat #12
Posted 24 July 2013 - 03:35 AM
to shutdown the computer after it reached max add
'os.shutdown()' in the bottom of your 'if x == 0 then' statement

but if you want to start over again add
'x = 30' in your 'if x == 0 then' statement
we have a loop around the entire script that already does that


while true do
x=30
-- program with if x == 0 then ...
end

Btw ivos97 we forgot to make an exit when x == 0 lol.

also we have no need to wrap the redstone signals inside a if x==0.


while true do
  x = 30
  while rs.getinput("left") == false do
    sleep (1)
  end
  while rs.getInput("left") == true do
	    x = x - 1
    term.setCursorPos(3,5) -- Always print on the same line
    term.clearLine() -- clear old items on the line
	    print(x.. " till countdown") -- print our countdown timer time. every minute.
	    sleep(60)
	    if x <= 0 then break end -- escape our loop and run the rs.setOutput()'s
  end
	    rs.setOutput("right", true)
	    sleep(4)
	    rs.setOutput("right", false)
end
MR_nesquick #13
Posted 24 July 2013 - 03:41 AM
no it didn't have a loop around the x= 30 if the redstone signal was on

and you put the 'end' in the wrong place.
should be in the inside the if statement…

			rs.setOutput("right", true)
			sleep(4)
			rs.setOutput("right", false)
albrat #14
Posted 24 July 2013 - 07:42 AM
please read the entire program.

The end is the end of the while rs.getInput("left") == true do

if we remove that end the lights will flash on and off every 60 seconds.

look up at the posts before.

while true do
x = 30
while rs.getInput("left") == false do
– stuff
end – end the while rs.getInput .. false
while rs.getInput("left") == true do
– stuff
end – end the while rs.getInput("left") true …
if x == 0 then
– stuff
end – end if
end – ends main loop and returns to the x = 30

The thing we forgot there was an exit to the redstone is on loop. It would never finish. untill the redstone was turned off. Hence now the if x== 0 is nested inside of our loop for counting. (if the if statement triggers it exits the loop. which triggers the redstone signal, sleep, redstone off and then Return to the start of the loop at x = 30. So no misplaced ends or forgotten if's this time. The program was re-structured away from a 30 minute loop that could on chance trigger the end result and now instead after 30 loops of 1 minute it Exits and always triggers the end event / resets.
apemanzilla #15
Posted 24 July 2013 - 01:36 PM
Here; try this code:

while true do
  local x = 30
  if rs.getInput("left") and not x ==0 then
    while rs.getInput("left") do
      print(x.." Minutes until something happens!")
      sleep(60)
      x=x-1
    end
    if x == 0 then
      print("Something is happening!")
      rs.setOutput("right",true)
      sleep(4)
      rs.setOutput("right",false)
    else
      print("Countdown terminated!")
    end
    --Uncomment the lines below this to make it require the redstone to be flicked off and then back on instead of instantly starting the countdown again.
    --while rs.getInput("left") do
      --os.pullEvent("redstone")
    --end
end
Should work but there may be some errors, wrote this on my phone.