Piove nel mio terminale!


24

Descrizione della sfida

Devi mostrare una simulazione della pioggia nel terminal.

Nell'esempio riportato di seguito, l'aggiunta di 100 gocce di pioggia casuali (utilizza la funzione casuale predefinita offerta dalla tua lingua) coordinate, in attesa di 0,2 secondi e quindi ridisegnando nuovamente fino alla scadenza del tempo indicato. Qualsiasi personaggio può essere usato per rappresentare la goccia di pioggia.

parametri

  • Tempo di attesa tra ridisegno in secondi.
  • Tempo per cui la pioggia sarà visibile. Questo è solo un numero intero che rappresenta il numero di iterazioni. [Quindi, il tempo netto per cui sarà visibile la pioggia è questo numero intero moltiplicato per il tempo di attesa]
  • Messaggio da visualizzare al termine della pioggia. (Questo deve essere centrato)
  • Numero di gocce di pioggia da visualizzare sullo schermo.

Regole

  • Un singolo byte dovrebbe essere usato per rappresentare una goccia di pioggia, e può essere qualsiasi cosa, anche cani e gatti.
  • Non deve rispondere alle dimensioni del terminale, il che significa che non è necessario gestire il bug per varie dimensioni del terminale. È possibile specificare la larghezza e l'altezza del terminale da soli.
  • Si applicano le regole standard del golf.

Esempio di codice e output

Questa è una versione non golfata scritta in Python 2.7 usando ncurses.

import curses
import random
import time

myscreen = curses.initscr()
curses.curs_set(0) # no cursor please 
HEIGHT, WIDTH = myscreen.getmaxyx() 
RAIN = '/' # this is what my rain drop looks like 
TIME = 10 

def make_it_rain(window, tot_time, msg, wait_time, num_drops):
    """
    window    :: curses window 
    time      :: Total time for which it rains
    msg       :: Message displayed when it stops raining
    wait_time :: Time between redrawing scene 
    num_drops :: Number of rain drops in the scene 
    """
    for _ in range(tot_time):
        for i in range(num_drops):
            x,y=random.randint(1, HEIGHT-2),random.randint(1,WIDTH-2)       
            window.addstr(x,y,RAIN)
        window.refresh()
        time.sleep(wait_time)
        window.erase()

    window.refresh()
    window.addstr(HEIGHT/2, int(WIDTH/2.7), msg)


if __name__ == '__main__':
    make_it_rain(myscreen, TIME, 'IT HAS STOPPED RAINING!', 0.2, 100)
    myscreen.getch()
    curses.endwin()

Produzione -

inserisci qui la descrizione dell'immagine


3
In futuro, invece di postare di nuovo, modifica l'originale. Se le persone pensano che le specifiche siano chiare, le nomineranno per la riapertura.
Mago del grano,

6
Il testo deve essere centrato? Piove a caso, conta la posizione iniziale delle goccioline? Come stai misurando il tempo? In millisecondi, secondi, minuti? Che cosa sono i "Punti extra"?
Magic Octopus Urn

1
Se tu, A. Specifica le unità. B. Specificare le dimensioni del terminale o prenderlo come input. e C. Rimuovere la parte relativa ai punti extra; questa sfida sarebbe meglio definita.
Magic Octopus Urn

Quando dici "casuale", possiamo supporre che significhi "uniformemente casuale" ?
Trauma digitale

3
1 giorno nella sandbox spesso non è sufficiente. Ricorda che le persone sono qui a livello ricreativo e da fusi orari diversi: non è previsto un feedback immediato.
Trauma digitale

Risposte:


12

MATL , 52 byte

xxx:"1GY.Xx2e3Z@25eHG>~47*cD]Xx12:~c!3G80yn-H/kZ"why

Gli input sono, in questo ordine: pausa tra aggiornamenti, numero di rilasci, messaggio, numero di ripetizioni. Il monitor ha dimensioni 80 × 25 caratteri (hardcoded).

GIF o non è successo! (Esempio con ingressi 0.2, 100, 'THE END', 30)

inserisci qui la descrizione dell'immagine

Oppure provalo su MATL Online .

Spiegazione

xxx      % Take first three inputs implicitly and delete them (but they get
         % copied into clipboard G)
:"       % Take fourth input implicitly. Repeat that many times
  1G     %   Push first input (pause time)
  Y.     %   Pause that many seconds
  Xx     %   Clear screen
  2e3    %   Push 2000 (number of chars in the monitor, 80*25)
  Z@     %   Push random permutation of the integers from 1 to 2000
  25e    %   Reshape as a 25×80 matrix, which contains the numbers from 1 to 2000
         %   in random positions
  HG     %   Push second input (number of drops)
  >~     %   Set numbers that are <= second input to 1, and the rest to 0
  47*c   %   Multiply by 47 (ASCII for '/') and convert to char. Char 0 will
         %   be displayed as a space
  D      %   Display
]        % End
Xx       % Clear screen
12:~     % Push row vector of twelve zeros
c!       % Convert to char and transpose. This will produce 12 lines containing
         % a space, to vertically center the message in the 25-row monitor
3G       % Push third input (message string)
80       % Push 80
yn       % Duplicate message string and push its length
-        % Subtract
H/k      % Divide by 2 and round down
Z"       % Push string of that many spaces, to horizontally center the message 
         % in the 80-column monitor
w        % Swap
h        % Concatenate horizontally
y        % Duplicate the column vector of 12 spaces to fill the monitor
         % Implicitly display

1
Mi piace come finisce why:)
tkellehe

1
@tkellehe Mi piace la descrizione sul tuo profilo :-)
Luis Mendo

1
grazie. La tua lingua è molto divertente da leggere. (Sì, ho perseguitato le tue risposte MATL lol)
tkellehe

10

JavaScript (ES6), 268 261 byte

t=
(o,f,d,r,m,g=(r,_,x=Math.random()*78|0,y=Math.random()*9|0)=>r?g(r-(d[y][x]<`/`),d[y][x]=`/`):d.map(a=>a.join``).join`
`)=>i=setInterval(_=>o.data=f--?g(r,d=[...Array(9)].map(_=>[...` `.repeat(78)])):`



`+` `.repeat(40-m.length/2,clearInterval(i))+m,d*1e3)
<input id=f size=10 placeholder="# of frames"><input id=d placeholder="Interval between frames"><input id=r size=10 placeholder="# of raindrops"><input id=m placeholder="End message"><input type=button value=Go onclick=t(o.firstChild,+f.value,+d.value,+r.value,m.value)><pre id=o>&nbsp;

Almeno sul mio browser, l'output è progettato per adattarsi all'area dello Stack Snippet senza dover passare a "Pagina intera", quindi se chiedi più di 702 gocce di pioggia si bloccherà.

Modifica: salvato 7 byte utilizzando un nodo di testo come area di output.


È possibile salvare alcuni byte passando la funzione come stringa a setInterval. Inoltre, perché usi textContentinvece di innerHTML?
Luca

@ L.Serné L'uso di una funzione interna mi consente di fare riferimento alle variabili nella funzione esterna.
Neil,

Oops, mia cattiva, non me ne sono accorto.
Luca,

8

R, 196 192 185 byte

Solo una versione finta che ho scritto in base alla descrizione. Spero che sia un po 'quello che OP stava cercando.

Alcuni byte salvati grazie a @plannapus.

f=function(w,t,m,n){for(i in 1:t){x=matrix(" ",100,23);x[sample(2300,n)]="/";cat("\f",rbind(x,"\n"),sep="");Sys.sleep(w)};cat("\f",g<-rep("\n",11),rep(" ",(100-nchar(m))/2),m,g,sep="")}

Gli argomenti:

  • w: Tempo di attesa tra i frame
  • t: Numero totale di frame
  • m: Messaggio personalizzato
  • n: Numero di gocce di pioggia

Esempio

Perché sembra che piova verso l'alto?

Modifica: dovrei menzionare che questa è la mia console R-studio personalizzata da 23x100 caratteri. Le dimensioni sono codificate nella funzione ma in linea di principio si potrebbe usare getOption("width")per renderlo flessibile alle dimensioni della console.

inserisci qui la descrizione dell'immagine

Ungolfed e spiegato

f=function(w,t,m,n){
    for(i in 1:t){
        x=matrix(" ",100,23);             # Initialize matrix of console size
        x[sample(2300,n)]="/";            # Insert t randomly sampled "/"
        cat("\f",rbind(x,"\n"),sep="");   # Add newlines and print one frame
        Sys.sleep(w)                      # Sleep 
    };
    cat("\f",g<-rep("\n",11),rep(" ",(100-nchar(m))/2),m,g,sep="")  # Print centered msg
}

Questo sembra perfettamente bene! +1 e non penso che stia salendo, è solo la tua percezione lol
hashcode55

@plannapus. Realizzato rep()automaticamente risolve l' timesargomento, quindi non è nemmeno necessario. Salvati altri 7 byte!
Billywob,

Soluzione molto bella. È possibile salvare un byte premendo le dimensioni della console per gli argomenti della funzione (se consentito); puoi salvare un altro byte usando runifinvece di samplepopolare casualmente la matrice. In questo modo:f=function(w,t,m,n,x,y){for(i in 1:t){r=matrix(" ",x,y);r[runif(n)*x*y]="/";cat("\f",rbind(r,"\n"),sep="");Sys.sleep(w)};cat("\f",g<-rep("\n",y/2),rep(" ",(x-nchar(m))/2),m,g,sep="")}
rturnbull,

5

C 160 byte

f(v,d,w,char *s){i,j;char c='/';for(i=0;i<v;i++){for(j=0;j<d;j++)printf("%*c",(rand()%100),c);fflush(stdout);sleep(w);}system("clear");printf("%*s\n",1000,s);}

v-Time the raindrops are visible in seconds.
d-Number of drops per iteration
w-Wait time in seconds, before the next iteration
s-String to be passed on once its done

Versione non golfata:

void f(int v, int d, int w,char *s)
{ 

   char c='/';
   for(int i=0;i<v;i++)
   { 
      for(int j=0;j<d;j++)
         printf("%*c",(rand()%100),c);

      fflush(stdout);
      sleep(w); 
   }   
   system("clear");
   printf("%*s\n", 1000,s);
}

Testcase sul mio terminale

v - 5 seconds
d - 100 drops
w - 1 second wait time
s - "Raining Blood" :)

4

R, 163 caratteri

f=function(w,t,n,m){for(i in 1:t){cat("\f",sample(rep(c("/"," "),c(n,1920-n))),sep="");Sys.sleep(w)};cat("\f",g<-rep("\n",12),rep(" ",(80-nchar(m))/2),m,g,sep="")}

Con rientri e righe:

f=function(w,t,n,m){
    for(i in 1:t){
        cat("\f",sample(rep(c("/"," "),c(n,1920-n))),sep="")
        Sys.sleep(w)
    }
    cat("\f",g<-rep("\n",12),rep(" ",(80-nchar(m))/2),m,g,sep="")
}

È adattato a una dimensione terminale di 24 linee per 80 colonne. wè il tempo di attesa, til numero di fotogrammi, nil numero di gocce di pioggia e mil messaggio finale.

Si differenzia dalla risposta di @ billywob nel diverso uso di sample: se la dimensione di output viene omessa, samplefornisce una permutazione del vettore di input (qui un vettore che contiene il numero necessario di gocce di pioggia e il corrispondente numero di spazi, grazie al fatto che l'argomento timesdi la funzione repè vettoriale). Poiché la dimensione del vettore corrisponde esattamente alla dimensione dello schermo, non è necessario aggiungere nuove linee o forzare la forma in una matrice.

Gif di output


3

NodoJS: 691 158 148 byte

modificare

Come richiesto, funzionalità aggiuntive rimosse e golf.

s=[];setInterval(()=>{s=s.slice(L='',9);for(;!L[30];)L+=' |'[Math.random()*10&1];s.unshift(L);console.log("\u001b[2J\u001b[0;0H"+s.join('\n'))},99)

Le regole specificano il mancato rispetto delle dimensioni, ma questa versione include un problema tecnico per i primi frame. Sono 129 byte.

s='';setInterval(()=>{for(s='\n'+s.slice(0,290);!s[300];)s=' |'[Math.random()*10&1]+s;console.log("\u001b[2J\u001b[0;0H"+s)},99)

Risposta precedente

Forse non è il miglior golf, ma mi sono lasciato trasportare un po '. Ha la direzione del vento e il fattore pioggia opzionali.

node rain.js 0 0.3

var H=process.stdout.rows-2, W=process.stdout.columns,wnd=(arg=process.argv)[2]||0, rf=arg[3]||0.3, s=[];
let clr=()=>{ console.log("\u001b[2J\u001b[0;0H") }
let nc=()=>{ return ~~(Math.random()*1+rf) }
let nl=()=>{ L=[];for(i=0;i<W;i++)L.push(nc()); return L}
let itrl=(l)=>{ for(w=0;w<wnd;w++){l.pop();l.unshift(nc())}for(w=0;w>wnd;w--){l.shift();l.push(nc())};return l }
let itrs=()=>{ if(s.length>H)s.pop();s.unshift(nl());s.map(v=>itrl(v)) }
let d=(c,i)=>{if(!c)return ' ';if(i==H)return '*';if(wnd<0)return '/';if(wnd>0)return '\\';return '|'}
let drw=(s)=>{ console.log(s.map((v,i)=>{ return v.map(  c=>d(c,i)  ).join('') }).join('\r\n')) }
setInterval(()=>{itrs();clr();drw(s)},100)

Guarda il webm che funziona qui


2

Noodel , 44 byte non competitivi

Avevo centrato il testo sul mio elenco di cose da fare da quando ho creato la lingua ... Ma ero pigro e non l'ho aggiunto fino a dopo questa sfida. Quindi, qui non sto gareggiando, ma mi sono divertito con la sfida :)

ØGQÆ×Øæ3/×Æ3I_ȥ⁻¤×⁺Æ1Ḷḋŀ÷25¶İÇæḍ€Æ1uụC¶×12⁺ß

La dimensione della console è hard coded su 25x50 che non ha un bell'aspetto nell'editor online, ma lo fa per lo snippet.

Provalo:)


Come funziona

Ø                                            # Pushes all of the inputs from the stack directly back into the stdin since it is the first token.

 GQÆ×Ø                                       # Turns the seconds into milliseconds since can only delay by milliseconds.
 GQ                                          # Pushes on the string "GQ" onto the top of the stack.
   Æ                                         # Consumes from stdin the value in the front and pushes it onto the stack which is the number of seconds to delay.
    ×                                        # Multiplies the two items on top of the stack.
                                             # Since the top of the stack is a number, the second parameter will be converted into a number. But, this will fail for the string "GQ" therein treated as a base 98 number producing 1000.
     Ø                                       # Pops off the new value, and pushes it into the front of stdin.

      æ3/×Æ3I_ȥ⁻¤×⁺                          # Creates the correct amount of rain drops and spaces to be displayed in a 50x25 console.
      æ3                                     # Copies the forth parameter (the number of rain drops).
        /                                    # Pushes the character "/" as the rain drop character.
         ×                                   # Repeats the rain drop character the specified number of times provided.
          Æ3                                 # Consumes the number of rain drops from stdin.
            I_                               # Pushes the string "I_" onto the stack.
              ȥ                              # Converts the string into a number as if it were a base 98 number producing 25 * 50 = 1250.
               ⁻                             # Subtract 1250 - [number rain drops] to get the number of spaces.
                ¤                            # Pushes on the string "¤" which for Noodel is a space.
                 ×                           # Replicate the "¤" that number of times.
                  ⁺                          # Concatenate the spaces with the rain drops.

                   Æ1Ḷḋŀ÷25¬İÇæḍ€            # Handles the animation of the rain drops.
                   Æ1                        # Consumes and pushes on the number of times to loop the animation.
                     Ḷ                       # Pops off the number of times to loop and loops the following code that many times.
                      ḋ                      # Duplicate the string with the rain drops and spaces.
                       ŀ                     # Shuffle the string using Fisher-Yates algorithm.
                        ÷25                  # Divide it into 25 equal parts and push on an array containing those parts.
                           ¶                 # Pushes on the string "¶" which is a new line.
                            İ                # Join the array by the given character.
                             Ç               # Clear the screen and display the rain.
                              æ              # Copy what is on the front of stdin onto the stack which is the number of milliseconds to delay.
                               ḍ             # Delay for the specified number of milliseconds.
                                €            # End of the loop.

                                 Æ1uụC¶×12⁺ß # Creates the centered text that is displayed at the end.
                                 Æ1          # Pushes on the final output string.
                                   u         # Pushes on the string "u" onto the top.
                                    ụC       # Convert the string on the top of the stack to an integer (which will fail and default to base 98 which is 50) then center the input string based off of that width.
                                      ¶      # Push on a the string "¶" which is a new line.
                                       ×12   # Repeat it 12 times.
                                          ⁺  # Append the input string that has been centered to the new lines.
                                           ß # Clear the screen.
                                             # Implicitly push on what is on the top of the stack which is the final output.

<div id="noodel" code="ØGQÆ×Øæ3/×Æ3I_ȥ⁻¤×⁺Æ1Ḷḋŀ÷25¶İÇæḍ€Æ1uụC¶×12⁺ß" input='0.2, 50, "Game Over", 30' cols="50" rows="25"></div>

<script src="https://tkellehe.github.io/noodel/noodel-latest.js"></script>
<script src="https://tkellehe.github.io/noodel/ppcg.min.js"></script>


1
Ah, questo è un bel linguaggio da avere nella mia cassetta degli attrezzi ahah! Comunque, sono contento che ti sia piaciuta la sfida :) +1
hashcode55

2

Utilità Ruby + GNU Core, 169 byte

I parametri della funzione sono il tempo di attesa, il numero di iterazioni, il messaggio e il numero di gocce di pioggia, in quell'ordine. Newline per la leggibilità.

Gli utensili di base erano necessari per tput e clear.

->w,t,m,n{x=`tput cols`.to_i;z=x*h=`tput lines`.to_i
t.times{s=' '*z;[*0...z].sample(n).map{|i|s[i]=?/};puts`clear`+s;sleep w}
puts`clear`+$/*(h/2),' '*(x/2-m.size/2)+m}

1

Python 2.7, 254 251 byte

Questo è il mio tentativo senza usare ncurses.

from time import*;from random import*;u=range;y=randint
def m(t,m,w,n):
    for _ in u(t):
        r=[[' 'for _ in u(40)]for _ in u(40)]
        for i in u(n):r[y(0,39)][y(0,39)]='/'
        print'\n'.join(map(lambda k:' '.join(k),r));sleep(w);print '<esc>[2J'
    print' '*33+m

Grazie a @ErikTheOutgolfer per avermi corretto e salvato byte.


Non puoi mettere un forciclo in una riga (come hai fatto in 40)];for i in u(). Hai anche bisogno di un carattere ESC in '[2J'credo. Inoltre, c'era uno spazio extra in u(n): r[y. Non so come tu abbia contato 249 però. Tutti i problemi che ho riscontrato sono stati risolti qui .
Erik the Outgolfer,

Il codice che ho pubblicato funziona per me. E sì, in realtà l'ho considerato sbagliato, non ho contato lo spazio rientrato bianco, non lo sapevo. Grazie per il link! Lo modificherò.
hashcode55

@EriktheOutgolfer Oh e sì per quel carattere ESC, non è necessaria alcuna sequenza di escape. Stampa 'ESC [2J' in modo efficace, che è una sequenza di escape per cancellare lo schermo. Tuttavia, non ripristina la posizione del cursore.
hashcode55

Puoi giocare a golf ancora di più :) Ma devi aggiungere una nota sotto il codice specificando che <esc>indica un byte ESC letterale 0x1B. Il conteggio dei byte è 242 , non 246.
Erik the Outgolfer,

@EriktheOutgolfer Oh grazie!
hashcode55

1

SmileBASIC, 114 byte

INPUT W,T,M$,N
FOR I=1TO T
VSYNC W*60CLS
FOR J=1TO N
LOCATE RND(50),RND(30)?7;
NEXT
NEXT
LOCATE 25-LEN(M$)/2,15?M$

Le dimensioni della console sono sempre 50 * 30.


1

Perl 5, 156 byte

154 byte codice + 2 per -pl.

$M=$_;$W=<>;$I=<>;$R=<>;$_=$"x8e3;{eval'$-=rand 8e3;s!.{$-}\K !/!;'x$R;print;select$a,$a,$a,$W;y!/! !;--$I&&redo}$-=3920-($l=length$M)/2;s;.{$-}\K.{$l};$M

Utilizza una dimensione fissa di 160x50.

Guardalo online!


Perl 5, 203 byte

201 byte codice + 2 per -pl.

$M=$_;$W=<>;$I=<>;$R=<>;$_=$"x($z=($x=`tput cols`)*($y=`tput lines`));{eval'$-=rand$z;s!.{$-}\K !/!;'x$R;print;select$a,$a,$a,$W;y!/! !;--$I&&redo}$-=$x*($y+!($y%2))/2-($l=length$M)/2;s;.{$-}\K.{$l};$M

Utilizza tputper determinare la dimensione del terminale.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.