Il pleut dans mon terminal!


24

Description du défi

Vous devez montrer une simulation de pluie dans le terminal.

Dans l'exemple ci-dessous, l'ajout de 100 gouttes de pluie au hasard (utilisez la fonction aléatoire par défaut que votre langue propose) coordonne, attend 0,2 seconde puis redessine jusqu'à ce que le temps imparti expire. N'importe quel caractère peut être utilisé pour représenter la goutte de pluie.

Paramètres

  • Temps d'attente entre redessiner en secondes.
  • Temps pendant lequel la pluie sera visible. Il s'agit simplement d'un entier représentant le nombre d'itérations. [Donc, le temps net pendant lequel la pluie sera visible est cet entier multiplié par le temps d'attente]
  • Message à afficher à la fin de la pluie. (Cela doit être centré)
  • Nombre de gouttes de pluie à afficher à l'écran.

Règles

  • Un seul octet doit être utilisé pour représenter une goutte de pluie, et cela peut être n'importe quoi, même des chats et des chiens.
  • Il ne doit pas être sensible à la taille du terminal, ce qui signifie que vous n'avez pas à gérer le bogue pour des tailles de terminal variées. Vous pouvez définir vous-même la largeur et la hauteur du terminal.
  • Les règles standards du golf s'appliquent.

Échantillon de code et sortie

Il s'agit d'une version non golfée écrite en python 2.7 utilisant 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()

Sortie -

entrez la description de l'image ici


3
À l'avenir, au lieu de publier à nouveau, veuillez modifier l'original. Si les gens pensent que les spécifications sont claires, ils le proposeront pour la réouverture.
Wheat Wizard

6
Le texte doit-il être centré? Pleut-il au hasard, la position initiale des gouttelettes est-elle importante? Comment mesurez-vous le temps? En millisecondes, secondes, minutes? Qu'est-ce que les «points supplémentaires»?
Urne de poulpe magique du

1
Si vous, A. Spécifiez les unités. B. Spécifiez la taille du terminal ou prenez-le comme entrée. et C. Retirez la partie concernant les points supplémentaires; ce défi serait mieux défini.
Urne de poulpe magique du

Lorsque vous dites "aléatoire", pouvons-nous supposer que cela signifie "uniformément aléatoire" ?
Digital Trauma

3
Une journée dans le bac à sable n'est souvent pas suffisante. N'oubliez pas que les gens sont ici à des fins récréatives et de différents fuseaux horaires - il ne faut pas s'attendre à une rétroaction immédiate.
Digital Trauma

Réponses:


12

MATL , 52 octets

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

Les entrées sont, dans cet ordre: pause entre les mises à jour, nombre de suppressions, message, nombre de répétitions. Le moniteur a une taille de 80 × 25 caractères (codés en dur).

GIF ou ça n'est pas arrivé! (Exemple avec entrées0.2 , 100, 'THE END', 30)

entrez la description de l'image ici

Ou essayez-le sur MATL Online .

Explication

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
J'aime comment ça se termine why:)
tkellehe

1
@tkellehe J'aime la description de votre profil :-)
Luis Mendo

1
Je vous remercie. Votre langue est tellement amusante à lire. (Oui, j'ai traqué vos réponses MATL lol)
tkellehe

10

JavaScript (ES6), 268 261 octets

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;

Au moins sur mon navigateur, la sortie est conçue pour s'intégrer dans la zone d'extrait de pile sans avoir à passer en «pleine page», donc si vous demandez plus de 702 gouttes de pluie, elle se bloquera.

Edit: enregistré 7 octets en utilisant un nœud de texte comme zone de sortie.


Vous pouvez enregistrer quelques octets en passant la fonction sous forme de chaîne à setInterval. Aussi, pourquoi utilisez-vous textContentau lieu de innerHTML?
Luke

@ L.Serné L'utilisation d'une fonction interne me permet de me référer aux variables de la fonction externe.
Neil

Oups, mon mauvais, n'a pas remarqué cela.
Luke

8

R, 196 192 185 185 octets

Juste une version simulée que j'ai écrite sur la base de la description. J'espère que c'est un peu ce que OP recherchait.

Enregistré quelques octets grâce à @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="")}

Les arguments:

  • w: Temps d'attente entre les images
  • t: Nombre total d'images
  • m: Message personnalisé
  • n: Nombre de gouttes de pluie

Exemple

Pourquoi semble-t-il qu'il pleut vers le haut?

Edit: je dois mentionner qu'il s'agit de ma console R-studio de 23x100 caractères personnalisée. Les dimensions sont codées en dur dans la fonction mais on pourrait en principe l'utiliser getOption("width")pour la rendre flexible à la taille de la console.

entrez la description de l'image ici

Non golfé et expliqué

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
}

Cela semble parfaitement bien! +1 et je ne pense pas que ça
monte,

@plannapus. Réalisé rep()automatiquement, l' timesargument se pose donc pas besoin non plus. Enregistré encore 7 octets!
Billywob

Très belle solution. Vous pouvez enregistrer un octet en poussant la taille de la console aux arguments de fonction (si cela est autorisé); vous pouvez enregistrer un autre octet en utilisant runifplutôt qu'en sampleremplissant aléatoirement la matrice. Comme ça: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 octets

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

Version non golfée:

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 sur mon terminal

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

4

R, 163 caractères

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

Avec des retraits et des nouvelles lignes:

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

Il est adapté à une taille de terminal de 24 lignes par 80 colonnes. west le temps d'attente, tle nombre d'images, nle nombre de gouttes de pluie et mle message final.

Elle diffère de la réponse de @ billywob par l'utilisation différente de sample: si la taille de sortie est omise, sampledonne une permutation du vecteur d'entrée (ici un vecteur contenant le nombre nécessaire de gouttes de pluie et le nombre d'espaces correspondant, grâce au fait que l'argument timesde fonction repest vectorisé). Comme la taille du vecteur correspond exactement à la taille de l'écran, il n'est pas nécessaire d'ajouter de nouvelles lignes ou de le forcer à former une matrice.

Gif de sortie


3

NodeJS: 691 158 148 Octets

modifier

Comme demandé, les fonctionnalités supplémentaires ont été supprimées et jouées au 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)

Les règles spécifient le non-respect de la taille, mais cette version inclut un problème pour les premières images. C'est 129 octets.

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)

Réponse précédente

Peut-être pas le meilleur golf, mais je me suis un peu emporté. Il a la direction du vent et le facteur de pluie en option.

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)

Voir le webm de cela fonctionne ici


2

Noodel , non 44 octets

J'avais centré le texte sur ma liste de choses à faire depuis que j'ai fait le langage ... Mais, j'étais paresseux et je n'ai pas ajouté avant ce défi. Donc, ici, je ne suis pas en compétition, mais je me suis amusé avec le défi :)

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

La taille de la console est codée en dur à 25x50, ce qui ne semble pas bien dans l'éditeur en ligne, mais le fait pour l'extrait de code.

Essayez-le :)


Comment ça marche

Ø                                            # 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 c'est une langue cool à avoir dans ma boîte à outils haha! Quoi qu'il en soit, heureux que vous ayez aimé le défi :) +1
hashcode55

2

Ruby + GNU Core Utils, 169 octets

Les paramètres de la fonction sont le temps d'attente, le nombre d'itérations, le message et le nombre de gouttes de pluie, dans cet ordre. De nouvelles lignes pour la lisibilité.

Core Utils était nécessaire pour tputet 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 octets

Ceci est mon propre essai sans utiliser 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

Merci à @ErikTheOutgolfer pour la correction et la sauvegarde de mes octets.


Vous ne pouvez pas mettre une forboucle sur une seule ligne (comme vous l'avez fait dans 40)];for i in u(). Vous avez également besoin d'un caractère ESC dans '[2J'je pense. De plus, il y avait un espace supplémentaire à l'intérieur u(n): r[y. Je ne sais pas comment vous en avez compté 249. Tous les problèmes que j'ai trouvés ont été corrigés ici .
Erik the Outgolfer

Le code que j'ai publié fonctionne pour moi. Et oui, je l'ai mal compté, je n'ai pas compté l'espace blanc en retrait, je ne le savais pas. Merci pour le lien! Je vais le modifier.
hashcode55

@EriktheOutgolfer Oh et oui concernant ce caractère ESC, aucune séquence d'échappement n'est nécessaire. Il imprime simplement 'ESC [2J' efficacement, qui est une séquence d'échappement ansi pour effacer l'écran. Cependant, cela ne réinitialise pas la position du curseur.
hashcode55

Vous pouvez jouer au golf encore plus :) Mais vous devez ajouter une note sous votre code spécifiant que <esc>dénote un octet ESC littéral 0x1B. Le nombre d'octets est 242 , pas 246.
Erik the Outgolfer

@EriktheOutgolfer Oh merci!
hashcode55

1

SmileBASIC, 114 octets

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$

La taille de la console est toujours de 50 * 30.


1

Perl 5, 156 octets

154 octets code + 2 pour -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

Utilise une taille fixe de 160x50.

Voyez-le en ligne!


Perl 5, 203 octets

201 octets code + 2 pour -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

Utilise tputpour déterminer la taille du terminal.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.