Hujan di terminal saya!

24

Deskripsi Tantangan

Anda harus menunjukkan simulasi hujan di terminal.

Dalam contoh yang diberikan di bawah ini menambahkan 100 tetesan hujan secara acak (gunakan fungsi acak default yang ditawarkan bahasa Anda) koordinat, menunggu 0,2 detik dan kemudian menggambar kembali sampai waktu yang diberikan berakhir. Karakter apa pun dapat digunakan untuk mewakili tetesan hujan.

Parameter

  • Tunggu waktu antara menggambar ulang dalam hitungan detik.
  • Waktu dimana hujan akan terlihat. Ini hanya bilangan bulat yang mewakili jumlah iterasi. [Jadi, waktu bersih dimana hujan akan terlihat adalah bilangan bulat ini dikalikan dengan waktu tunggu]
  • Pesan yang akan ditampilkan saat hujan berakhir. (Ini harus dipusatkan)
  • Jumlah tetesan hujan yang akan ditampilkan di layar.

Aturan

  • Satu byte harus digunakan untuk mewakili tetesan hujan, dan itu bisa apa saja, bahkan kucing dan anjing.
  • Itu tidak harus responsif terhadap ukuran terminal yang berarti Anda tidak harus menangani bug untuk ukuran terminal yang bervariasi. Anda dapat menentukan sendiri lebar dan tinggi terminal.
  • Aturan standar bermain golf berlaku.

Contoh dan Output Kode

Ini adalah versi yang tidak ditandai yang ditulis dalam python 2.7 menggunakan 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()

Keluaran -

masukkan deskripsi gambar di sini

hashcode55
sumber
3
Di masa depan alih-alih mengirim lagi, harap edit yang asli. Jika orang berpikir bahwa spesifikasi itu jelas, mereka akan mencalonkannya untuk dibuka kembali.
Wheat Wizard
6
Apakah teks harus di tengah? Apakah hujan turun secara acak, apakah posisi awal tetesan penting? Bagaimana Anda mengukur waktu? Dalam milidetik, detik, menit? Apa itu "Poin Tambahan"?
Guci Gurita Ajaib
1
Jika Anda, A. Tentukan unit. B. Tentukan ukuran terminal atau anggap sebagai input. dan C. Lepaskan bagian tentang poin ekstra; tantangan ini akan lebih jelas.
Guci Gurita Ajaib
Ketika Anda mengatakan "acak", dapatkah kita menganggap itu berarti "acak seragam" ?
Trauma Digital
3
1 hari di kotak pasir seringkali tidak cukup. Ingatlah bahwa orang-orang di sini rekreasi dan dari berbagai zona waktu - umpan balik langsung tidak boleh diharapkan.
Digital Trauma

Jawaban:

12

MATL , 52 byte

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

Inputnya adalah, dalam urutan ini: jeda antara pembaruan, jumlah tetes, pesan, jumlah pengulangan. Monitor memiliki ukuran 80 × 25 karakter (hard-coded).

GIF atau itu tidak terjadi! (Contoh dengan input 0.2, 100, 'THE END', 30)

masukkan deskripsi gambar di sini

Atau coba di MATL Online .

Penjelasan

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
Luis Mendo
sumber
1
Saya suka bagaimana ini berakhir why:)
tkellehe
1
@tkellehe Saya suka deskripsi di profil Anda :-)
Luis Mendo
1
Terima kasih. Bahasa Anda sangat menyenangkan untuk dibaca. (Ya, saya telah menguntit jawaban MATL Anda 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;

Setidaknya di browser saya, output dirancang agar sesuai dengan area Stack Snippet tanpa harus pergi "Halaman penuh", jadi jika Anda meminta lebih dari 702 tetesan air hujan, itu akan crash.

Sunting: Disimpan 7 byte dengan menggunakan simpul teks sebagai area output saya.

Neil
sumber
Anda dapat menyimpan beberapa byte dengan meneruskan fungsi sebagai string setInterval. Juga, mengapa Anda menggunakan textContentbukan innerHTML?
Luke
@ L.Serné Menggunakan fungsi dalam memungkinkan saya untuk merujuk ke variabel di fungsi luar.
Neil
Ups, salahku, tidak memperhatikan itu.
Luke
8

R, 196 192 185 byte

Hanya versi tiruan yang saya tulis berdasarkan deskripsi. Semoga ini yang OP cari.

Menyimpan beberapa byte berkat @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="")}

Argumen:

  • w: Tunggu waktu antar frame
  • t: Jumlah total frame
  • m: Pesan khusus
  • n: Jumlah tetesan hujan

Contoh

Mengapa terlihat seperti hujan ke atas?

Sunting: Saya harus menyebutkan bahwa ini adalah konsol R-studio karakter 23x100 saya yang dapat disesuaikan. Dimensi hardcoded ke dalam fungsi tetapi seseorang pada prinsipnya dapat digunakan getOption("width")untuk membuatnya fleksibel untuk ukuran konsol.

masukkan deskripsi gambar di sini

Tidak diikat dan dijelaskan

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
}
Billywob
sumber
Ini terlihat sangat baik! +1 dan saya tidak berpikir itu akan naik hanya persepsi Anda lol
hashcode55
@plannapus. Realisasi argumen rep()lantai secara otomatis timessehingga tidak perlu untuk itu juga. Disimpan 7 byte lagi!
Billywob
Solusi yang sangat bagus Anda dapat menyimpan satu byte dengan menekan ukuran konsol agar berfungsi argumen (jika itu diizinkan); Anda dapat menyimpan byte lain dengan menggunakan runifdaripada samplesecara acak mengisi matriks. Seperti itu: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

Versi tidak disatukan:

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 di terminal saya

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

R, 163 karakter

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

Dengan indentasi dan baris baru:

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

Ini disesuaikan dengan ukuran terminal 24 baris dengan 80 kolom. wadalah waktu tunggu, tjumlah bingkai, njumlah tetesan air hujan dan mpesan terakhir.

Ini berbeda dari jawaban @ billywob dalam penggunaan berbeda sample: jika ukuran output dihilangkan, samplememberikan permutasi dari vektor input (di sini vektor berisi jumlah hujan yang diperlukan dan jumlah ruang yang sesuai, berkat fakta bahwa argumen timesdari (fungsi repvektor). Karena ukuran vektor sesuai persis dengan ukuran layar, tidak perlu menambahkan baris baru, atau memaksa-bentuknya ke dalam matriks.

Gif output

plannapus
sumber
3

NodeJS: 691 158 148 Bytes

Edit

Seperti yang diminta, fitur tambahan dihapus dan 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)

Aturan menentukan mengabaikan ukuran, tetapi versi ini termasuk kesalahan untuk beberapa frame pertama. Itu adalah 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)

Jawaban sebelumnya

Mungkin bukan golf terbaik, tapi aku agak terbawa suasana. Ini memiliki arah angin dan faktor hujan opsional.

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)

Lihat webm yang berfungsi di sini

M3D
sumber
2

Noodel , 44 byte tidak bersaing

Saya memiliki teks yang terpusat pada daftar hal yang harus saya lakukan sejak saya membuat bahasa ... Tapi, saya malas dan tidak menambahkan sampai setelah tantangan ini. Jadi, di sini saya tidak bersaing, tetapi bersenang-senang dengan tantangan :)

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

Konsol berukuran sulit dikodekan ke 25x50 yang tidak terlihat bagus di editor online, tetapi tidak untuk potongan.

Cobalah:)


Bagaimana itu bekerja

Ø                                            # 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>

tkellehe
sumber
1
Ah, itu bahasa yang asyik untuk ada di kotak peralatan saya haha! Bagaimanapun, senang Anda menyukai tantangan :) +1
hashcode55
2

Ruby + GNU Core Utils, 169 byte

Parameter ke fungsi adalah waktu tunggu, jumlah iterasi, pesan, dan jumlah tetesan hujan, dalam urutan itu. Baris baru untuk keterbacaan.

Core Utils dibutuhkan untuk tputdan 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}
Nilai Tinta
sumber
1

Python 2.7, 254 251 byte

Ini adalah percobaan saya sendiri tanpa menggunakan 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

Terima kasih kepada @ErikTheOutgolfer untuk mengoreksi dan menyelamatkan saya byte.

hashcode55
sumber
Anda tidak dapat meletakkan satu forlingkaran dalam satu baris (seperti yang Anda lakukan pada 40)];for i in u(). Anda juga perlu char ESC di '[2J'saya pikir. Juga, ada ruang ekstra di u(n): r[y. Saya tidak tahu bagaimana Anda menghitung 249. Semua masalah yang saya temukan sudah diperbaiki di sini .
Erik the Outgolfer
Kode yang saya posting berfungsi untuk saya. Dan ya saya benar-benar menghitungnya salah, saya tidak menghitung ruang lekukan putih, saya tidak tahu tentang itu. Terima kasih untuk tautannya! Saya akan mengeditnya.
hashcode55
@EriktheOutgolfer Oh dan yeah mengenai ESC char, tidak ada urutan jalan keluar yang diperlukan. Itu hanya mencetak 'ESC [2J' secara efektif, yang merupakan urutan melarikan diri untuk membersihkan layar. Itu tidak mengatur ulang posisi kursor.
hashcode55
Anda dapat golf lebih banyak :) Tapi Anda perlu menambahkan catatan di bawah kode Anda menentukan yang <esc>menunjukkan byte ESC 0x1B literal. Hitungan Byte adalah 242 , bukan 246.
Erik the Outgolfer
@EriktheOutgolfer Oh terima kasih!
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$

Ukuran konsol selalu 50 * 30.

12Me21
sumber
1

Perl 5, 156 byte

154 byte kode + 2 untuk -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

Menggunakan ukuran tetap 160x50.

Lihat online!


Perl 5, 203 byte

201 byte kode + 2 untuk -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

Penggunaan tputuntuk menentukan ukuran terminal.

Dom Hastings
sumber