In meinem Terminal regnet es!


24

Herausforderungsbeschreibung

Sie müssen eine Regensimulation im Terminal anzeigen.

In dem folgenden Beispiel werden 100 Regentropfen nach dem Zufallsprinzip hinzugefügt (verwenden Sie die Standard-Zufallsfunktion, die Ihre Sprache anbietet). Warten Sie 0,2 Sekunden und zeichnen Sie dann erneut, bis die angegebene Zeit abgelaufen ist. Für die Darstellung des Regentropfens kann ein beliebiges Zeichen verwendet werden.

Parameter

  • Wartezeit zwischen Neuzeichnen in Sekunden.
  • Zeit, für die der Regen sichtbar sein wird. Dies ist nur eine Ganzzahl, die die Anzahl der Iterationen darstellt. [Die Nettodauer, für die der Regen sichtbar sein wird, ist diese ganze Zahl multipliziert mit der Wartezeit.]
  • Meldung, die angezeigt wird, wenn der Regen aufhört. (Dies muss zentriert sein)
  • Anzahl der Regentropfen, die auf dem Bildschirm angezeigt werden sollen.

Regeln

  • Ein einzelnes Byte sollte verwendet werden, um einen Regentropfen darzustellen, und es kann alles sein, sogar Katzen und Hunde.
  • Es muss nicht auf die Terminalgröße reagieren, was bedeutet, dass Sie den Fehler bei unterschiedlichen Terminalgrößen nicht behandeln müssen. Sie können die Terminalbreite und -höhe selbst festlegen.
  • Es gelten die Standardregeln für das Golfen.

Codebeispiel und Ausgabe

Dies ist eine ungolfed Version, die mit ncurses in Python 2.7 geschrieben wurde.

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()

Ausgabe -

Bildbeschreibung hier eingeben


3
Bitte bearbeiten Sie in Zukunft das Original, anstatt es erneut zu veröffentlichen. Wenn die Leute der Meinung sind, dass die Spezifikationen klar sind, werden sie sie zur Wiedereröffnung vorschlagen.
Weizen-Assistent

6
Muss der Text zentriert sein? Regnet es zufällig, spielt die Ausgangslage der Tröpfchen eine Rolle? Wie messen Sie die Zeit? In Millisekunden, Sekunden, Minuten? Was sind "Extra Points"?
Magic Octopus Urn

1
Wenn ja, A. Geben Sie die Einheiten an. B. Geben Sie die Terminalgröße an oder nehmen Sie sie als Eingabe. und C. Entfernen Sie das Teil über zusätzliche Punkte; Diese Herausforderung wäre besser definiert.
Magic Octopus Urn

Wenn Sie "zufällig" sagen, können wir annehmen, dass dies "gleichmäßig zufällig" bedeutet ?
Digitales Trauma

3
1 Tag im Sandkasten reicht oft nicht aus. Denken Sie daran, dass die Menschen hier in ihrer Freizeit und aus verschiedenen Zeitzonen sind - eine sofortige Rückmeldung ist nicht zu erwarten.
Digitales Trauma

Antworten:


12

MATL , 52 Bytes

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

Eingaben sind in dieser Reihenfolge: Pause zwischen Aktualisierungen, Anzahl der Abbrüche, Meldung, Anzahl der Wiederholungen. Der Monitor hat eine Größe von 80 × 25 Zeichen (fest codiert).

GIF oder es ist nicht passiert! (Beispiel mit Eingängen 0.2, 100, 'THE END', 30)

Bildbeschreibung hier eingeben

Oder probieren Sie es bei MATL Online .

Erläuterung

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
Ich mag, wie es endet in why:)
tkellehe

1
@ Tkellehe Ich mag die Beschreibung in Ihrem Profil :-)
Luis Mendo

1
Danke dir. Ihre Sprache macht so viel Spaß zu lesen. (Ja, ich habe Ihre MATL- Antworten verfolgt, 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;

Zumindest in meinem Browser ist die Ausgabe so konzipiert, dass sie in den Bereich des Stapel-Snippets passt, ohne dass "Ganze Seite" angezeigt werden muss. Wenn Sie also mehr als 702 Regentropfen anfordern, stürzt die Ausgabe ab.

Bearbeiten: 7 Bytes mit einem Textknoten als Ausgabebereich gespeichert.


Sie können einige Bytes sparen, indem Sie die Funktion als Zeichenfolge an übergeben setInterval. Auch warum benutzt du textContentstatt innerHTML?
Luke

@ L.Serné Wenn ich eine innere Funktion verwende, kann ich auf die Variablen in der äußeren Funktion verweisen.
Neil

Hoppla, mein Schlimmes, hat das nicht bemerkt.
Luke

8

R, 196 192 185 Bytes

Nur eine Scheinversion, die ich aufgrund der Beschreibung geschrieben habe. Hoffentlich ist es etwas, wonach OP gesucht hat.

Einige Bytes dank @plannapus gespart.

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="")}

Die Argumente:

  • w: Wartezeit zwischen Bildern
  • t: Gesamtzahl der Bilder
  • m: Benutzerdefinierte Nachricht
  • n: Anzahl der Regentropfen

Beispiel

Warum scheint es nach oben zu regnen?

Bearbeiten: Ich sollte erwähnen, dass dies meine angepasste 23x100 Zeichen R-Studio-Konsole ist. Die Abmessungen sind in die Funktion fest einprogrammiert, aber man könnte sie im Prinzip verwenden getOption("width"), um die Größe der Konsole flexibel zu gestalten.

Bildbeschreibung hier eingeben

Ungolfed und erklärte

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
}

Das sieht ganz gut aus! +1 und ich glaube nicht, dass es nach oben geht, nur deine Wahrnehmung lol
hashcode55

@plannapus. Realized rep()meldet das timesArgument automatisch ab, so dass dies auch nicht erforderlich ist. Weitere 7 Bytes gespeichert!
Billywob

Sehr schöne Lösung. Sie können ein Byte speichern, indem Sie die Konsolengröße auf Funktionsargumente verschieben (sofern dies zulässig ist). Sie können ein weiteres Byte speichern, indem Sie die Matrix nicht zufällig füllen, runifsondern verwenden sample. Wie so: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 Bytes

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

Ungolfed-Version:

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);
}

Testfall auf meinem Terminal

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

4

R 163 Zeichen

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="")}

Mit Einrückungen und Zeilenumbrüchen:

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="")
}

Es ist an eine Terminalgröße von 24 Zeilen mal 80 Spalten angepasst. wist die Wartezeit, tdie Anzahl der Frames, ndie Anzahl der Regentropfen und mdie endgültige Nachricht.

Es unterscheidet sich von der Antwort von @ billywob durch die unterschiedliche Verwendung von sample: Wenn die Ausgabegröße weggelassen wird, samplewird eine Permutation des Eingabevektors angezeigt (hier ein Vektor, der die erforderliche Anzahl von Regentropfen und die entsprechende Anzahl von Leerzeichen enthält, dank dieses Argumentstimes von Funktion repist vektorisiert). Da die Größe des Vektors genau der Größe des Bildschirms entspricht, müssen keine Zeilenumbrüche hinzugefügt oder erzwungen zu einer Matrix geformt werden.

Gif der Ausgabe


3

NodeJS: 691 158 148 Bytes

Bearbeiten

Auf Wunsch werden zusätzliche Funktionen entfernt und Golf gespielt.

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)

Die Regeln legen fest, dass die Größe nicht berücksichtigt wird. Diese Version enthält jedoch einen Fehler für die ersten paar Frames. Es ist 129 Bytes.

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)

Vorherige Antwort

Vielleicht nicht das beste Golfspiel, aber ich wurde ein bisschen mitgerissen. Es hat optional Windrichtung und Regenfaktor.

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)

Siehe webm hier


2

Nudel , nicht konkurrierende 44 Bytes

Ich hatte zentrierten Text auf meiner Liste der Sachen, die zu tun sind, seit ich die Sprache gemacht habe ... Aber ich war faul und fügte erst nach dieser Herausforderung hinzu. Also, hier konkurriere ich nicht, hatte aber Spaß mit der Herausforderung :)

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

Die Konsolengröße ist fest auf 25x50 codiert, was im Online-Editor nicht gut aussieht, aber für das Snippet.

Versuch es:)


Wie es funktioniert

Ø                                            # 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, das ist eine coole Sprache in meiner Toolbox, haha! Wie auch immer, ich
bin

2

Ruby + GNU Core Utils, 169 Byte

Parameter für die Funktion sind Wartezeit, Anzahl der Iterationen, Nachricht und Anzahl der Regentropfen in dieser Reihenfolge. Zeilenumbrüche zur besseren Lesbarkeit.

Core Utils wurden für tputund benötigt 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 Bytes

Dies ist mein eigener Versuch, ohne ncurses zu verwenden.

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

Vielen Dank an @ErikTheOutgolfer für das Korrigieren und Speichern von Bytes.


Sie können keine forSchleife in eine Zeile einfügen (wie in 40)];for i in u(). Sie brauchen auch ein ESC-Zeichen in, '[2J'denke ich. Es gab auch einen zusätzlichen Raum in u(n): r[y. Ich weiß allerdings nicht, wie Sie 249 gezählt haben. Alle Probleme, die ich gefunden habe, wurden hier behoben .
Erik der Outgolfer

Der Code, den ich gepostet habe, funktioniert für mich. Und ja, ich habe es tatsächlich falsch gezählt, ich habe den weißen eingerückten Raum nicht gezählt, ich wusste nichts darüber. Danke für den Link! Ich werde es bearbeiten.
Hashcode55

@EriktheOutgolfer Oh und ja, bezüglich dieses ESC-Zeichens ist keine Escape-Sequenz erforderlich. Es wird nur effektiv 'ESC [2J' gedruckt, was eine Escape-Sequenz zum Löschen des Bildschirms darstellt. Die Cursorposition wird jedoch nicht zurückgesetzt.
Hashcode55

Sie können noch mehr Golf spielen :) Sie müssen jedoch eine Anmerkung unter Ihrem Code einfügen, die angibt, dass es sich um <esc>ein wörtliches 0x1B-ESC-Byte handelt.
Byteanzahl

@EriktheOutgolfer Oh danke!
Hashcode55

1

SmileBASIC, 114 Bytes

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$

Die Konsolengröße beträgt immer 50 * 30.


1

Perl 5, 156 Bytes

154 Byte Code + 2 für -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

Verwendet eine feste Größe von 160x50.

Sehen Sie es online!


Perl 5, 203 Bytes

201 Byte Code + 2 für -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

Verwendet tputdie Größe des Terminals zu bestimmen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.