Spinning rod animation/Text: Difference between revisions
→{{header|Ruby}}: Make sure cursor is restored |
Ada version |
||
Line 12: | Line 12: | ||
A version that loops and/or a version that doesn't loop can be made. |
A version that loops and/or a version that doesn't loop can be made. |
||
<br><br> |
<br><br> |
||
=={{header|Ada}}== |
|||
{{trans|Go}} |
|||
<lang Ada>with Ada.Text_IO; |
|||
procedure Spinning_Rod is |
|||
use Ada.Text_IO; |
|||
type Index_Type is mod 4; |
|||
Rod : constant array (Index_Type) of Character := ('|', '/', '-', '\'); |
|||
Index : Index_Type := 0; |
|||
Char : Character; |
|||
Avail : Boolean; |
|||
begin |
|||
Put (ASCII.ESC & "[?25l"); -- Hide the cursor |
|||
loop |
|||
Put (ASCII.ESC & "[2J"); -- Clear Terminal |
|||
Put (ASCII.ESC & "[0;0H"); -- Place Cursor at Top Left Corner |
|||
Get_Immediate (Char, Avail); |
|||
exit when Avail; |
|||
Put (Rod (Index)); |
|||
Index := Index_Type'Succ (Index); |
|||
delay 0.250; |
|||
end loop; |
|||
Put (ASCII.ESC & "[?25h"); -- Restore the cursor |
|||
end Spinning_Rod;</lang> |
|||
=={{header|AWK}}== |
=={{header|AWK}}== |
Revision as of 13:29, 12 November 2019
![Task](http://static.miraheze.org/rosettacodewiki/thumb/b/ba/Rcode-button-task-crushed.png/64px-Rcode-button-task-crushed.png)
You are encouraged to solve this task according to the task description, using any language you may know.
- Task
An animation with the following frames in the following order must animate with a delay of 0.25 seconds between each frame, with the previous frame being cleared before the next frame appears:
- |
- /
- -
- \
A version that loops and/or a version that doesn't loop can be made.
Ada
<lang Ada>with Ada.Text_IO;
procedure Spinning_Rod is
use Ada.Text_IO;
type Index_Type is mod 4; Rod : constant array (Index_Type) of Character := ('|', '/', '-', '\'); Index : Index_Type := 0; Char : Character; Avail : Boolean;
begin
Put (ASCII.ESC & "[?25l"); -- Hide the cursor loop Put (ASCII.ESC & "[2J"); -- Clear Terminal Put (ASCII.ESC & "[0;0H"); -- Place Cursor at Top Left Corner Get_Immediate (Char, Avail); exit when Avail; Put (Rod (Index)); Index := Index_Type'Succ (Index); delay 0.250; end loop; Put (ASCII.ESC & "[?25h"); -- Restore the cursor
end Spinning_Rod;</lang>
AWK
<lang AWK>
- syntax: GAWK -f SPINNING_ROD_ANIMATION_TEXT.AWK
@load "time" BEGIN {
while (1) { printf(" %s\r",substr("|/-\\",x++%4+1,1)) sleep(.25) } exit(0)
} </lang>
Bash
<lang bash>while : ; do
for rod in \| / - \\ ; do printf ' %s\r' $rod; sleep 0.25; done
done</lang> (Added an indent in the printf to better see the spinning rod).
C
<lang c>#include <stdio.h>
- include <time.h>
int main() {
int i, j, ms = 250; const char *a = "|/-\\"; time_t start, now; struct timespec delay; delay.tv_sec = 0; delay.tv_nsec = ms * 1000000L; printf("\033[?25l"); // hide the cursor time(&start); while(1) { for (i = 0; i < 4; i++) { printf("\033[2J"); // clear terminal printf("\033[0;0H"); // place cursor at top left corner for (j = 0; j < 80; j++) { // 80 character terminal width, say printf("%c", a[i]); } fflush(stdout); nanosleep(&delay, NULL); } // stop after 20 seconds, say time(&now); if (difftime(now, start) >= 20) break; } printf("\033[?25h"); // restore the cursor return 0;
}</lang>
C Shell
<lang csh>while 1
foreach rod ('|' '/' '-' '\') printf ' %s\r' $rod; sleep 0.25 end
end</lang> (Added an indent in the printf to better see the spinning rod).
Caché ObjectScript
<lang Caché ObjectScript>SPINROD
; spin 10 times with quarter-second wait for i = 1:1:10 { for j = 1:1:4 { set x = $case(j,1:"|",2:"/",3:"-",:"\") ; $char(8) backspaces on the terminal write $char(8)_x hang 0.25 } } quit</lang>
Emacs Lisp
<lang Lisp> (while t
(mapcar (lambda(n)(princ n)(sit-for 0.25) (backward-delete-char 1)) (list "\\" "|" "-" "/") ) )
</lang>
Factor
<lang factor>USING: calendar combinators.extras formatting io sequences threads ;
[
"\\|/-" [ "%c\r" printf flush 1/4 seconds sleep ] each
] forever</lang>
FreeBASIC
<lang freebasic>' version 13-07-2018 ' compile with: fbc -s console
Dim As String spinning_rod = "|/-\" Dim As UInteger c
While InKey <> "" : Wend
While InKey = ""
Cls Print Print " hit any key to end program "; Chr(spinning_rod[c And 3]) c += 1 Sleep(250) ' in milliseconds
Wend
End</lang>
Forth
Tested in gforth 0.7.9 <lang forth>
- rod
cr begin [char] \\ emit 250 ms 13 emit [char] | emit 250 ms 13 emit [char] - emit 250 ms 13 emit [char] / emit 250 ms again
rod </lang>
GlovePIE
Because GlovePIE is a looping programming language, which means the script is ran over and over again in a looping fashion, this code loops again and again until it's stopped. <lang glovepie>debug="|" wait 250 ms debug="/" wait 250 ms debug="-" wait 250 ms debug="\" wait 250 ms</lang>
Go
<lang go>package main
import (
"fmt" "time"
)
func main() {
a := `|/-\` fmt.Printf("\033[?25l") // hide the cursor start := time.Now() for { for i := 0; i < 4; i++ { fmt.Print("\033[2J") // clear terminal fmt.Printf("\033[0;0H") // place cursor at top left corner for j := 0; j < 80; j++ { // 80 character terminal width, say fmt.Printf("%c", a[i]) } time.Sleep(250 * time.Millisecond) } if time.Since(start).Seconds() >= 20.0 { // stop after 20 seconds, say break } } fmt.Print("\033[?25h") // restore the cursor
}</lang>
Haskell
Uses the terminfo library to make the cursor invisible, if possible. <lang haskell>import Control.Concurrent (threadDelay) import Control.Exception (bracket_) import Control.Monad (forM_) import System.Console.Terminfo import System.IO (hFlush, stdout)
-- Use the terminfo database to write the terminal-specific characters -- for the given capability. runCapability :: Terminal -> String -> IO () runCapability term cap =
forM_ (getCapability term (tiGetOutput1 cap)) (runTermOutput term)
-- Control the visibility of the cursor. cursorOff, cursorOn :: Terminal -> IO () cursorOff term = runCapability term "civis" cursorOn term = runCapability term "cnorm"
-- Print the spinning cursor. spin :: IO () spin = forM_ (cycle "|/-\\") $ \c ->
putChar c >> putChar '\r' >> hFlush stdout >> threadDelay 250000
main :: IO () main = do
putStrLn "Spinning rod demo. Hit ^C to stop it.\n" term <- setupTermFromEnv bracket_ (cursorOff term) (cursorOn term) spin</lang>
Java
<lang java>public class SpinningRod {
public static void main(String[] args) throws InterruptedException { String a = "|/-\\"; System.out.print("\033[2J"); // hide the cursor long start = System.currentTimeMillis(); while (true) { for (int i = 0; i < 4; i++) { System.out.print("\033[2J"); // clear terminal System.out.print("\033[0;0H"); // place cursor at top left corner for (int j = 0; j < 80; j++) { // 80 character terminal width, say System.out.print(a.charAt(i)); } Thread.sleep(250); } long now = System.currentTimeMillis(); // stop after 20 seconds, say if (now - start >= 20000) break; } System.out.print("\033[?25h"); // restore the cursor }
}</lang>
JavaScript
Node JS: <lang javascript> const rod = (function rod() {
const chars = "|/-\\"; let i=0; return function() { i= (i+1) % 4; // We need to use process.stdout.write since console.log automatically adds a \n to the end of lines process.stdout.write(` ${chars[i]}\r`); }
})(); setInterval(rod, 250); </lang>
Julia
<lang julia>while true
for rod in "\|/-" # this needs to be a string, a char literal cannot be iterated over print(rod,'\r') sleep(0.25) end
end </lang>
Kotlin
<lang scala>// Version 1.2.50
const val ESC = "\u001b"
fun main(args: Array<String>) {
val a = "|/-\\" print("$ESC[?25l") // hide the cursor val start = System.currentTimeMillis() while (true) { for (i in 0..3) { print("$ESC[2J") // clear terminal print("$ESC[0;0H") // place cursor at top left corner for (j in 0..79) { // 80 character terminal width, say print(a[i]) } Thread.sleep(250) } val now = System.currentTimeMillis() // stop after 20 seconds, say if (now - start >= 20000) break } print("$ESC[?25h") // restore the cursor
}</lang>
M2000 Interpreter
<lang M2000 Interpreter> Module Checkit {
n$=lambda$ n=1, a$="|/-\" -> { =mid$(a$, n, 1) n++ if n>4 then n=1 } \\ 1000 is 1 second Every 250 { \\ Print Over: erase line before print. No new line append. Print Over n$() }
} CheckIt
</lang>
<lang M2000 Interpreter> Module Checkit {
n=1 a$="|/-\" Every 250 { Print Over mid$(a$, n, 1) n++ if n>4 then n=1 }
} CheckIt
</lang>
Microsoft Small Basic
<lang microsoftsmallbasic>a[1]="|" a[2]="/" a[3]="-" a[4]="\" b=0 While b=0
For c=1 To 4 TextWindow.Clear() TextWindow.WriteLine(a[c]) Program.Delay(250) EndFor
EndWhile</lang>
MiniScript
Control over the text cursor -- or indeed, whether there is a text cursor, or even text at all -- depends on the host environment. Here's a version that works with MiniMicro: <lang MiniScript>print "Press control-C to exit..." while true
for c in "|/-\" text.setCell 0, 0, c wait 0.25 end for
end while</lang>
And here's a version that will work with command-line MiniScript, running on a terminal that interprets standard VT100 escape sequences: <lang MiniScript>while true
for c in "|/-\" print c wait 0.25 print char(27) + "[2A" // move cursor up 2 lines end for
end while</lang>
Perl
The statement $| =1
is required in order to disable output buffering.
<lang perl>$|= 1;
while () {
for (qw[ | / - \ ]) { select undef, undef, undef, 0.25; printf "\r ($_)"; }
}</lang>
Perl 6
Traditionally these are know as throbbers or progress indicators.
This implementation will accept an array of elements to use as its throbber frames, or as a scrolling marquee and optionally a delay before it returns the next element.
<lang perl6>class throbber {
has @.frames; has $.delay is rw = 0; has $!index = 0; has Bool $.marquee = False; method next { $!index = ($!index + 1) % +@.frames; sleep $.delay if $.delay; if $!marquee { ("\b" x @.frames) ~ @.frames.rotate($!index).join; } else { "\b" ~ @.frames[$!index]; } }
}
my $rod = throbber.new( :frames(< | / - \ >), :delay(.25) ); print "\e[?25lLong running process... "; print $rod.next for ^20;
my $clock = throbber.new( :frames("🕐" .. "🕛") ); print "\b \nSomething else with a delay... "; until my $done {
# do something in a loop; sleep 1/12; print $clock.next; $done = True if $++ >= 60;
}
my $scroll = throbber.new( :frames('PLEASE STAND BY... '.comb), :delay(.1), :marquee ); print "\b \nEXPERIENCING TECHNICAL DIFFICULTIES: { $scroll.frames.join }"; print $scroll.next for ^95;
END { print "\e[?25h\n" } # clean up on exit</lang>
Phix
<lang Phix>puts(1,"please_wait... ") cursor(NO_CURSOR) for i=1 to 10 do -- (approx 10 seconds)
for j=1 to 4 do printf(1," \b%c\b",`|/-\`[j]) sleep(0.25) end for
end for puts(1," \ndone") -- clear rod, "done" on next line </lang>
PicoLisp
<lang Lisp> (de rod ()
(until () (for R '(\\ | - /) (prin R (wait 250) "\r")(flush) ) ) )
(rod) </lang>
Python
<lang python>from time import sleep while True:
for rod in r'\|/-': print(rod, end='\r') sleep(0.25)</lang>
Racket
<lang racket>
- lang racket
(define (anim)
(for ([c "\\|/-"]) (printf "~a\r" c) (sleep 0.25)) (anim))
(anim) </lang>
REXX
This REXX program would work for all REXXes if there was a common way to sleep (suspend) execution for fractional seconds.
This REXX version will work for:
- Personnal REXX
- PC REXX
<lang rexx>/*REXX program displays a "spinning rod" (AKA: trobbers or progress indicators). */ if 4=='f4'x then bs= "16"x /*EBCDIC? Then use this backspace chr.*/
else bs= "08"x /* ASCII? " " " " " */
signal on halt /*jump to HALT when user halts pgm.*/ $= '│/─\' /*the throbbing characters for display.*/
do j=1 /*perform until halted by the user. */ call charout , bs || substr($, 1 + j//length($), 1) call delay .25 /*delays a quarter of a second. */ end /*j*/
halt: say bs ' ' /*stick a fork in it, we're all done. */</lang>
Ring
<lang ring>load "stdlib.ring" rod = ["|", "/", "-", "\"] for n = 1 to len(rod)
see rod[n] + nl sleep(0.25) system("cls")
next</lang> Output:
| / - \
Ruby
<lang ruby>def spinning_rod
begin printf("\033[?25l") # Hide cursor %w[| / - \\].cycle do |rod| print rod sleep 0.25 print "\b" end ensure printf("\033[?25h") # Restore cursor end
end
puts "Ctrl-c to stop." spinning_rod </lang>
Rust
<lang rust>fn main() {
let characters = ['|', '/', '-', '\\']; let mut current = 0;
println!("{}[2J", 27 as char); // Clear screen.
loop { println!("{}[;H{}", 27 as char, characters[current]); // Move cursor to 1,1 and output the next character. current += 1; // Advance current character. if current == 4 {current = 0;} // If we reached the end of the array, start from the beginning. std::thread::sleep(std::time::Duration::from_millis(250)); // Sleep 250 ms. }
}</lang>
Scala
<lang Scala>object SpinningRod extends App {
val start = System.currentTimeMillis
def a = "|/-\\"
print("\033[2J") // hide the cursor
while (System.currentTimeMillis - start < 20000) { for (i <- 0 until 4) { print("\033[2J\033[0;0H") // clear terminal, place cursor at top left corner for (j <- 0 until 80) print(a(i)) // 80 character terminal width, say Thread.sleep(250) } } print("\033[?25h") // restore the cursor
}</lang>
Wee Basic
Since the "|" character isn't built into Wee Basic on the Nintendo DS, and it looks the part in Wee Basic on the Nintendo DS, the character "l" is used as a substitute. Also, since no working delay command has been found yet, a for loop is used to work around this problem. <lang Wee Basic>let loop=1 sub delay: for i=1 to 10000 next cls 1 return while loop=1 print 1 "l" gosub delay: print 1 "/" gosub delay: print 1 "-" gosub delay: print 1 "\" gosub delay: wend end</lang>
zkl
<lang zkl>foreach n,rod in ((1).MAX, T("|", "/", "-", "\\")){
print(" %s\r".fmt(rod));
Atomic.sleep(0.25);
}</lang> A loop foreach a,b in (c,d) translates to foreach a in (c) foreach b in (d). n.MAX is a 64 bit int (9223372036854775807).
A more useful example would be a worker thread showing a "I'm working" display (in another thread) and turning it off when that work is done. <lang zkl>fcn spin{ // this will be a thread that displays spinner
try{ foreach n,rod in ((1).MAX, "\\|/-"){ print(" ",rod,"\r");
Atomic.sleep(0.25);
} }catch{} // don't complain about uncaught exception that stops thread
}</lang> <lang zkl>// main body of code spinner:=spin.launch(); // start spinner thread, returns reference to thread Atomic.sleep(10); // do stuff vm.kick(spinner.value); // stop thread by throwing exception at it</lang>
ZX Spectrum Basic
<lang ZX Basic>10 LET A$="|/-\" 20 FOR C=1 TO 4 30 PRINT AT 0,0;A$(C) 40 PAUSE 4 50 NEXT C 60 GOTO 20 </lang>