터미널에 비가옵니다!


24

도전 설명

터미널에서 비의 시뮬레이션을 보여 주어야합니다.

아래 예제에서 무작위로 100 개의 빗방울을 추가 (언어가 제공하는 기본 임의 함수 사용)하여 0.2 초 동안 기다렸다가 주어진 시간이 만료 될 때까지 다시 그립니다. 빗방울을 나타내는 데 모든 문자를 사용할 수 있습니다.

매개 변수

  • 다시 그리기 간격 (초)입니다.
  • 비가 보이는 시간. 이것은 반복 횟수를 나타내는 정수일뿐입니다. [따라서 비가 보일 순 시간은이 정수에 대기 시간을 곱한 값입니다]
  • 비가 내릴 때 표시되는 메시지. (이것은 중앙에 있어야합니다)
  • 화면에 표시 할 빗방울 수입니다.

규칙

  • 빗방울을 나타내는 데 1 바이트를 사용해야하며, 고양이 나 개까지도 가능합니다.
  • 터미널 크기에 반응 할 필요가 없으므로 다양한 터미널 크기에 대한 버그를 처리 할 필요가 없습니다. 터미널 너비와 높이를 직접 지정할 수 있습니다.
  • 골프의 표준 규칙이 적용됩니다.

코드 샘플 및 출력

이것은 ncurses를 사용하여 python 2.7로 작성된 ungolfed 버전입니다.

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

출력-

여기에 이미지 설명을 입력하십시오


3
나중에 다시 게시하는 대신 원본을 수정하십시오. 사람들이 사양이 명확하다고 생각하면 다시 열도록 지정합니다.
위트 마법사

6
텍스트를 중앙에 배치해야합니까? 무작위로 비가 내립니까, 물방울의 초기 위치가 중요합니까? 시간을 어떻게 측정합니까? 밀리 초, 초, 분? "추가 포인트"란 무엇입니까?
Magic Octopus Urn

1
그렇다면 A. 단위를 지정하십시오. B. 터미널 크기를 지정하거나 입력으로 사용하십시오. 그리고 C. 여분의 점들에 대해 부품을 제거하십시오. 이 도전은 더 잘 정의 될 것입니다.
Magic Octopus Urn

당신이 "무작위"라고 말할 때, 우리는 "균일하게 무작위" 를 의미한다고 가정 할 수 있습니까?
디지털 외상

3
샌드 박스에서 하루는 충분하지 않은 경우가 많습니다. 사람들은 여가 활동과 다양한 시간대에 있다는 것을 기억하십시오. 즉각적인 피드백을 기 대해서는 안됩니다.
디지털 외상

답변:


12

MATL , 52 바이트

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

입력 순서는 업데이트 간격, 삭제 횟수, 메시지, 반복 횟수입니다. 모니터의 크기는 80 × 25 자 (하드 코딩)입니다.

GIF 또는 그렇지 않았다! (입력 예는 0.2, 100, 'THE END', 30)

여기에 이미지 설명을 입력하십시오

또는 MATL Online 에서 사용해보십시오 .

설명

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
나는 그것이 끝나는 방법을 좋아한다 why:)
tkellehe

1
@tkellehe 나는 귀하의 프로필에 대한 설명을 좋아합니다 :-)
Luis Mendo

1
고맙습니다. 당신의 언어는 읽기에 너무 재미 있습니다. (예, MATL 답변을 스토킹하고 있습니다 )
tkellehe

10

자바 스크립트 (ES6), 268 261 바이트

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;

적어도 내 브라우저에서 출력은 "전체 페이지"로 가지 않아도 스택 스 니펫 영역에 맞도록 설계되었으므로 702 개 이상의 빗방울을 요청하면 충돌이 발생합니다.

편집 : 텍스트 노드를 내 출력 영역으로 사용하여 7 바이트를 저장했습니다.


함수를에 문자열로 전달하여 몇 바이트를 절약 할 수 있습니다 setInterval. 또한 왜 textContent대신에 사용 innerHTML합니까?
Luke

@ L.Serné 내부 함수를 사용하면 외부 함수의 변수를 참조 할 수 있습니다.
Neil

내 나쁜, 죄송합니다.
Luke

8

R, 196192 185 바이트

설명을 기반으로 작성한 모의 버전입니다. OP가 찾고 있던 것이기를 바랍니다.

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

인수 :

  • w: 프레임 간 대기 시간
  • t: 총 프레임 수
  • m: 맞춤 메시지
  • n: 빗방울 수

비가 위쪽으로 비가 내리는 것처럼 보이는 이유는 무엇입니까?

편집 : 이것은 사용자 정의 된 23x100 문자 R-studio 콘솔임을 언급해야합니다. 치수는 기능에 하드 코딩되어 있지만 원칙적 getOption("width")으로 콘솔 크기에 유연하게 사용할 수 있습니다.

여기에 이미지 설명을 입력하십시오

언 골프 및 설명

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
}

이것은 완벽하게 좋아 보인다! +1 그리고 나는 그것의 위로 올라갈 것이라고 생각하지 않습니다. lol
hashcode55

@plannapus. 실현 rep()times인수를 자동으로 해결 하므로 그럴 필요도 없습니다. 다른 7 바이트를 절약했습니다!
Billywob

아주 좋은 해결책. 콘솔 크기를 함수 인수로 푸시하여 1 바이트를 절약 할 수 있습니다 (허용되는 경우). 무작위로 행렬을 채우는 runif대신 사용하여 다른 바이트를 저장할 수 있습니다 sample. 그래서처럼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 바이트

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

언 골프 버전 :

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

터미널의 테스트 케이스

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

4

R, 163 자

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

들여 쓰기와 줄 바꿈으로 :

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

24 줄 x 80 열의 터미널 크기에 적합합니다. w대기 시간, t프레임 n수, 빗방울 수 및 m최종 메시지입니다.

그것은 상이한 billywob의 답변 @ 의 다른 사용은 sample출력 사이즈가 생략 된 경우 : sample여기서 입력 벡터 (빗방울의 필요한 수를 포함하는 벡터의 순열 및 스페이스에 대응하는 번호를 제공하는 사실이 인수 덕분 times중을 함수 rep가 벡터화 됨). 벡터의 크기는 화면의 크기와 정확히 일치하므로 줄 바꿈을 추가하거나 행렬에 강제로 형성 할 필요가 없습니다.

출력의 GIF


3

NodeJS : 691 158 148 바이트

편집하다

요청에 따라 추가 기능이 제거되고 골프가되었습니다.

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)

이 규칙은 크기 무시를 지정하지만이 버전에는 처음 몇 프레임의 결함이 포함됩니다. 그것은이다 129 바이트.

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)

이전 답변

아마도 최고의 골프는 아니지만, 나는 조금 멀어졌습니다. 선택적으로 풍향과 비 요소가 있습니다.

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)

여기에서 작동하는 webm 참조


2

Noodel , 비경쟁 44 바이트

나는 언어를 만든 이후해야 할 일 목록에 중심을 둔 텍스트를 가지고있었습니다. 그래서, 나는 경쟁하지 않지만 도전에 재미를 느꼈습니다 :)

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

콘솔 크기는 25x50으로 하드 코딩되어 온라인 편집기에서는 좋지 않지만 코드 조각에는 적합합니다.

시도 해봐:)


작동 원리

Ø                                            # 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
아 내 도구 상자 하하에 멋진 언어입니다! 어쨌든, 당신이 도전을 좋아해서 기쁘다 :) +1
hashcode55

2

루비 + GNU 코어 유틸리티, 169 바이트

함수의 매개 변수는 대기 시간, 반복 횟수, 메시지 및 빗방울 수의 순서입니다. 가독성 개행.

코어의 Utils이 필요했다 tputclear.

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

파이썬 2.7, 254 251 바이트

이것은 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

바이트를 수정하고 저장해 준 @ErikTheOutgolfer에게 감사합니다.


for한 줄에 루프를 넣을 수 없습니다 (에있는 것처럼 40)];for i in u(). '[2J'내 생각 에는 ESC 문자가 필요합니다 . 또한에 추가 공간이있었습니다 u(n): r[y. 그래도 249를 세는 방법을 모르겠습니다. 내가 찾은 모든 문제는 여기 에서 해결 되었습니다 .
Outgolfer Erik

내가 게시 한 코드가 나를 위해 작동합니다. 그리고 그래, 나는 실제로 그것을 잘못 계산했다. 나는 하얀 들여 쓰기 공간을 세지 않았다. 나는 그것에 대해 몰랐다. 링크 주셔서 감사합니다! 편집하겠습니다.
hashcode55

@ EriktheOutgolfer 아, 맞습니다. ESC 문자에 대해서는 이스케이프 시퀀스가 ​​필요하지 않습니다. 그것은 단지 'ESC [2J'를 효과적으로 인쇄하는데, 이것은 화면을 지우는 ansi escape sequence입니다. 커서 위치는 재설정되지 않습니다.
hashcode55

당신은 훨씬 더 골프 수 있습니다 :) 그러나 당신 <esc>은 리터럴 0x1B ESC 바이트 를 나타내는 코드 아래에 메모를 추가해야합니다 . 바이트 수는 246 이 아니라 242입니다 .
Outgolfer Erik

@EriktheOutgolfer 아 감사합니다!
hashcode55

1

SmileBASIC, 114 바이트

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$

콘솔 크기는 항상 50 * 30입니다.


1

펄 5, 156 바이트

154 바이트 코드 + 2 -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

고정 크기 160x50을 사용합니다.

온라인으로보십시오!


펄 5, 203 바이트

201 바이트 코드 + 2 -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

tput터미널의 크기를 결정하는 데 사용 합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.