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

[Lua][Question] Countdown Timer on Loop?

Started by Psychyn, 21 January 2013 - 06:27 AM
Psychyn #1
Posted 21 January 2013 - 07:27 AM
Hey there.

So I've been improving at LUA slowly and unsteadily. My recent achievement was learning how to write messages on monitors (yay!); Proud of being a newb, I'm looking into a countdown timer that loops after a small amount of time has passed. From what I understood, the sleep() function helps with that.

Now; I've browsed these forums but can't seem to find a code that makes sense to me. (They either have some output signal, lock doors or do other stuff) What I'm looking for is a timer that counts down from X amount of seconds; To pause a minute, then to start counting again with no further help needed. It just repeats itself over and over on a screen, not outputting anything, nor triggering. Just constantly repeating the message.

The idea is to sync it with the Railroad (Railcraft thing) I've been building, so that when the timer reaches 0 the train is actually on the station. Then it waits a minute, and when the train goes off it starts counting down again.

So:
Timer counts down from 3 minutes.
Reaches 0.
Waits for the train to leave again. ~Minute or so. (sleep function?)
When it's left, the counter starts at 3 again and counts down.

I'm trying to avoid hooking it up to redstone and sensors and rather time it myself with a watch as that seems much easier. xD

I'm sorry if it's been asked before, or if it's somewhere on the wiki. Either a helping hand with searching is appreciated, or insight into the code I'm looking for. =) Thanks in advance; Alternative ideas welcome if that's easier.
SuicidalSTDz #2
Posted 21 January 2013 - 07:28 AM
Hey there.

So I've been improving at LUA slowly and unsteadily. My recent achievement was learning how to write messages on monitors (yay!); Proud of being a newb, I'm looking into a countdown timer that loops after a small amount of time has passed. From what I understood, the sleep() function helps with that.

Now; I've browsed these forums but can't seem to find a code that makes sense to me. (They either have some output signal, lock doors or do other stuff) What I'm looking for is a timer that counts down from X amount of seconds; To pause a minute, then to start counting again with no further help needed. It just repeats itself over and over on a screen, not outputting anything, nor triggering. Just constantly repeating the message.

The idea is to sync it with the Railroad (Railcraft thing) I've been building, so that when the timer reaches 0 the train is actually on the station. Then it waits a minute, and when the train goes off it starts counting down again.

So:
Timer counts down from 3 minutes.
Reaches 0.
Waits for the train to leave again. ~Minute or so. (sleep function?)
When it's left, the counter starts at 3 again and counts down.

I'm trying to avoid hooking it up to redstone and sensors and rather time it myself with a watch as that seems much easier. xD

I'm sorry if it's been asked before, or if it's somewhere on the wiki. Either a helping hand with searching is appreciated, or insight into the code I'm looking for. =) Thanks in advance; Alternative ideas welcome if that's easier.

There is indeed a sleep function: sleep(amount of time in seconds) So i.e: sleep(3) would sleep for three seconds then execute the following code

So:
term.clear()
term.setCursorPos(1,1)
function seconds()
for i = 1,60 do
print(i)
sleep(1)
term.clear()
term.setCursorPos(1,1)
end
end
seconds()

You will have to come up with a way to use the redstone Api to use the timer to the fullest. If this is not what you are looking for then please state again. This is what I got from what you said
Willibilly19 #3
Posted 21 January 2013 - 07:34 AM
This doesn't seem like it would be too hard. I'm new to Lua myself, but I can give it a shot.

seconds = 180 --number of seconds in the timer
wait = 60  --time to wait
while true do
  for i = seconds,1,-1 do
    print(seconds)
    sleep(1)
   end
   sleep(wait)
end

I can't give a 100% guarantee it works, but I don't see why it wouldn't (never tried counting down, so that for loop might not have the correct syntax though.
ikke009 #4
Posted 21 January 2013 - 07:42 AM
This doesn't seem like it would be too hard. I'm new to Lua myself, but I can give it a shot. snip


seconds = 180 --number of seconds in the timer
wait = 60  --time to wait
while true do
  for i = 1,seconds do
	print(seconds-i)
	sleep(1)
   end
   sleep(wait)
end

your code would print 180 all the time xD so i fixed it.. also i like my while loops counting up
Willibilly19 #5
Posted 21 January 2013 - 07:45 AM
Oh right, I meant "print(i)", not "print(seconds)" :)/> And with that fix, the original should also work…but either way seems to be the same
Psychyn #6
Posted 22 January 2013 - 08:40 AM
Awesome! Thanks for the help so far. ^^ I'm going to fiddle around some more as the code posted by Script Kiddie seems to count up. (Am I that odd for wanting a count down? Makes more sense in my head. Seconds before the train arrives and all.) and the other code seems to erase the rest of the message off the screen but does count down! Would be awesome if I could keep the original text on the monitor above it, and a countdown in the center area under it at a fixed position. Should be doable.

So I'm going to see if I can combine the two with your examples. :)/> Sorry if I wasn't entirely clear on the matter.

Edit: Awesome! Managed to keep my text.. Now to get it to count down instead. :D/>
Edit2: More awesomeness! Thanks guys, I almost got it working. I'll copy the code writing in a bit for reference material; I'm sure there's a flaw in it somewhere but it's going in the right direction.

term.clear()
term.setCursorPos(3,2)
print("Estimated Travel Times: ETT")
term.setCursorPos(3,4)
print("Dorfanos <-> SquareSky City")
term.setCursorPos(3,5)
print("Fourty-Two Seconds")
term.setCursorPos(3,7)
print("Train arriving in..")
term.setCursorPos(5,8)
function seconds()
seconds = 42
wait = 60
for i = 1, seconds do
	   print(seconds-i)
	   sleep(1)
term.setCursorPos(5,8)
end
end
seconds()

Is what I got so far; It seems to jump up at random times, all the way to 1000 seconds to lower with 100 each tick. Tadd odd, working on it though. :3
Edited on 22 January 2013 - 08:17 AM
remiX #7
Posted 22 January 2013 - 08:54 AM
To print stuff on the monitor you need to wrap it first with the peripheral API
monitor = peripheral.wrap("left") -- where left is the side of the monitor in respect to the computer

Then to write you would use
monitor.write("hi") -- take note: there is no print function so you would need to change cursor pos all the time
Psychyn #8
Posted 22 January 2013 - 09:20 AM
Thanks for that tip. The text on the monitor itself seems to work fine (Managed to fix that earlier, see the edits); Unless you are referring to the count down timer. I got it set up as a startup program with:

shell.run("monitor", "back", "track")

(So "startup track" launches the screen with text and the timer.)

Should I edit that and change it into your suggested code? :)/> Or should I edit the timer display into the above? So far, the problem seems to be the timer that randomly adds time; Not the text. ^^

Edit: I realize it ain't a 3 minute timer, that's for the bigger track. I got tired waiting 3 minutes each time so I'm trying to configure it for the smaller, 42 second lasting track. :D/>
Edit2: Randomness stopped. It counts down from 42 to 10, hops to 100 then counts that down with 10 seconds a tick. (So it's still 10 seconds, but from 100 -> 0). Not sure what that is all about. It doesn't seem to restart itself back at 42 after a minute, the counter stays on "00" on my screen. (Which is nice, I love the 00. It just needs to start again after the wait time. xD)
Edit3; The last bit is probably because I removed the "While true do" function. I'll tinker that back in.
Edit4: Okay! It loops again. :D/>

Now I just need to figure out why it hops to 100 with the last 10 seconds. Help is very welcome and any input gains a shiny green up arrow! (For what that's worth around here. :3 )


term.clear()
term.setCursorPos(3,2)
print("Estimated Travel Times: ETT")
term.setCursorPos(3,4)
print("Dorfanos <-> SquareSky City")
term.setCursorPos(3,5)
print("Fourty-Two Seconds")
term.setCursorPos(3,7)
print("Train arriving in..")
term.setCursorPos(5,8)
seconds = 42
wait = 10 -- For testing purposes
while true do
  for i = 1, seconds do
		   print(seconds-i)
		   sleep(1)
term.setCursorPos(5,8)
end
end
seconds()
Edited on 22 January 2013 - 09:16 AM
Psychyn #9
Posted 23 January 2013 - 11:25 AM
Okay. I have it almost figured out; However, I can't seem to get it to sleep for the amount of seconds I want. It either erases the whole screen, or waits 63 seconds each time to lower the counter by 1.

It's probably something easy, but I can't see it. Help?



term.clear()
term.setCursorPos(3,2)
print("Estimated Travel Times: ETT")
term.setCursorPos(3,4)
print("Dorfanos <-> SquareSky City")
term.setCursorPos(3,5)
print("Fourty-Two Seconds")
term.setCursorPos(3,7)
print("Train arriving in..")
term.setCursorPos(5,8)
seconds = 42
wait = 63 -- Is completely ignored at the moment.
while true do
  for i = 1, seconds do
				   print(seconds-i)
				   sleep(1)
term.clear() -- Fixed the jump to 100. Thanks forum search.
term.setCursorPos(5,8)
end
end
seconds()

Where would I add the sleep(wait) line for it to work? (Or should I use something else?) I want to keep the text on the screen and the number at 0 till the wait time expires; For it to start at 42 again.
Edited on 23 January 2013 - 10:36 AM
ikke009 #10
Posted 23 January 2013 - 09:15 PM
Add sleep(wait) just above the last end (that is inside the while true loop and outside the for i-1,seconds loop)
Psychyn #11
Posted 24 January 2013 - 11:00 AM
I tried that, unfortunately; It makes the entire monitor black out except for the number bit. (It erases all text.) Once the timer hits 0 it just goes back to 42 instantly and repeats.

Does that mean I got a spacing issue somewhere as it responds to the wrong line or?

Here's the one I tried (along with other sleep(wait) positions but no luck:


term.clear()
term.setCursorPos(3,2)
print("Estimated Travel Times: ETT")
term.setCursorPos(3,4)
print("Dorfanos <-> SquareSky City")
term.setCursorPos(3,5)
print("Fourty-Two Seconds")
term.setCursorPos(3,7)
print("Train arriving in..")
term.setCursorPos(5,8)
seconds = 42
wait = 63 -- Is completely ignored at the moment.
while true do
  for i = 1, seconds do
							print(seconds-i)
							sleep(1)
term.clear() -- Fixed the jump to 100. Thanks forum search.
term.setCursorPos(5,8)
end
sleep(wait)
end
seconds()

Also tried:

end
end
sleep(wait)
seconds()

And:

sleep(wait)
end
end
seconds()

And so forth. =\ By now I'm starting to believe it's some dumb bug with the Tekkit pack but that'd be incredibly odd. Would affect everyone then who's on 1.2.5.

Edit: Well.. Removing the earlier term.clear() fixed that one but now it jumps back to 100. Retarded. I don't see the logic in this code any more. Seems it's an or/or choice.

Either a constantly repeating timer that doesn't wait.
Or a timer that jumps to 100 for the last 10 seconds, for no reason.
Edit2: Also got no clue why this silly code function spaces my print(seconds)/sleep(1) bit so far out. Heh. It ain't that far out on my console in-game if that makes a difference.
Edited on 24 January 2013 - 10:17 AM
Willibilly19 #12
Posted 24 January 2013 - 11:40 AM
<p>The problem was the line not clearing before it printed the single digit numbers. The 0 you were seeing was actually the 0 from the 10. Here is a working code for ya.(There might be a better way to do it….but this works.)




function info()
  term.clear()

  term.setCursorPos(3,2)
  print("Estimated Travel Times: ETT")

  term.setCursorPos(3,4)
  print("Dorfanos <-> SquareSky City")

  term.setCursorPos(3,5)
  print("Fourty-Two Seconds")

  term.setCursorPos(3,7)
  print("Train arriving in..")

  term.setCursorPos(5,8)
end

seconds = 42
wait = 63 

i = seconds

while true do
  while i <= seconds and i > 0 do
	i = i - 1
	info()
	print(i)
	sleep (1)
  end
  if i == 0 then
    i = seconds
    info()
    print("Arrived")
  end
  sleep(wait)
end

Psychyn #13
Posted 24 January 2013 - 12:05 PM
Thanks for the explanation, that at least answered as to why it was being a pain in the rear. Upon typing your code over however, I get this:

bios:206: [string "track":1: '<name>' expected

Really beginning to believe that this coding language ain't my cup of tea. Triple checked for any typo's but I'm 100% sure I copied it correctly. (Also tried it without all the enters in between) Man, if this ever decides to work I'm taking a break from Computercraft.


Edit: Oh and thanks for the "Arrived" print, that's a neat little touch there. ^^

Edit- FFFFFFFFFF- got it. I managed to place a dot in the first sentence somehow. Testing it out now.
Edit2: Seems we are editing at the same time! Your code worked before you removed it from the post. Man. If I could give you a hundred up arrows for the post then I would do so. Thanks, you really made the last touch to the station possible and that means incredibly much to me. :)/>

Just in case you don't put it back in; Here it is for people wondering. All credit to Willibilly19


function info()
  term.clear()

  term.setCursorPos(3,2)
  print("Estimated Travel Times: ETT")

  term.setCursorPos(3,4)
  print("Dorfanos <-> SquareSky City")

  term.setCursorPos(3,5)
  print("Fourty-Two Seconds")

  term.setCursorPos(3,7)
  print("Train arriving in..")

  term.setCursorPos(5,8)
end

seconds = 42
wait = 63

i = seconds

while true do
  while i <= seconds and i > 0 do
		i = i - 1
		info()
		print(i)
		sleep (1)
  end
  if i == 0 then
	i = seconds
	info()
	print("Arrived")
  end
  sleep(wait)
end
Edited on 24 January 2013 - 12:00 PM
Willibilly19 #14
Posted 24 January 2013 - 12:38 PM
Oh wow, My internet was bugging out for a while….don't know how that happened lol but I fixed my post as well.

And You are quite welcome. Glad I could help out.
NeverCast #15
Posted 24 January 2013 - 12:40 PM
You could also use os.clock()



local arriveTime = os.clock() + 42

while os.clock() < arriveTime do
   info()
   print(arriveTime - os.clock())
   sleep(1)
end

info()
print"Arrived"