我的航站楼正在下雨!


24

挑战说明

您必须显示终端机中降雨的模拟。

在下面给出的示例中,它随机添加100个雨滴(使用您的语言提供的默认随机函数)坐标,等待0.2秒,然后再次重绘,直到给定时间到期。任何字符都可以用来表示雨滴。

参量

  • 重绘之间的等待时间(以秒为单位)。
  • 下雨的时间到了。这只是代表迭代次数的整数。[因此,下雨可见的净时间是该整数乘以等待时间]
  • 雨结束时显示的信息。(必须居中)
  • 屏幕上显示的雨滴数。

规则

  • 应该使用一个字节来表示雨滴,它可以是任何东西,甚至包括猫和狗。
  • 它不必响应终端大小,这意味着您不必处理各种终端大小的错误。您可以自行指定终端的宽度和高度。
  • 适用打高尔夫球的标准规则。

代码样本和输出

这是使用ncurses用python 2.7编写的非高尔夫版本。

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.删除有关加分的部分; 这个挑战将更好地定义。
魔术章鱼缸

当您说“随机”时,我们可以假设这意味着“均匀随机”吗?
Digital Trauma

3
在沙盒中停留1天通常是不够的。请记住,人们在这里休闲娱乐,时区各异-不应期望立即得到反馈。
Digital Trauma

Answers:


12

MATL,52字节

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

输入的顺序如下:在更新之间暂停,丢弃次数,消息,重复次数。显示器尺寸为80×25个字符(硬编码)。

GIF还是没有发生!(实施例具有输入0.2100'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

1
谢谢。您的语言非常有趣。(是的,我一直在跟踪您的MATL答案,哈哈)
tkellehe

10

的JavaScript(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;

至少在我的浏览器上,输出被设计为适合Stack Snippet区域,而不必进入“整页”,因此,如果您请求超过702个雨滴,则会崩溃。

编辑:通过使用文本节点作为我的输出区域保存了7个字节。


您可以通过将函数作为字符串传递给来节省一些字节setInterval。另外,为什么用textContent代替innerHTML
路加福音

@L.Serné使用内部函数使我可以引用外部函数中的变量。
尼尔

糟糕,我没注意到。
路加福音

8

R,196192185字节

我只是根据描述写的一个模拟版本。希望这是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,我不认为它会上升只是您的感知大声笑
hashcode55

@plannapus。实现会rep()自动使times参数变小,因此也不需要。保存了另外7个字节!
Billywob

非常好的解决方案。您可以通过将控制台大小推入函数参数来节省一个字节(如果允许的话);您可以使用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行乘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

Ruby + GNU Core Utils,169字节

该函数的参数是等待时间,迭代次数,消息和雨滴数量(按此顺序)。换行符以提高可读性。

tput和都需要Core Utils 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字节

这是我自己的尝试,不使用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。我发现的所有问题都已在此处修复。
暴民埃里克(Erik the Outgolfer)'17年

我发布的代码对我有用。是的,我实际上算错了,我没有算出白色的凹进空间,我也不知道。感谢您的链接!我将对其进行编辑。
hashcode55

@EriktheOutgolfer关于该ESC字符,是的,不需要转义序列。它只是有效地打印“ ESC [2J”,这是用于清除屏幕的ansi转义序列。但是,它不会重置光标位置。
hashcode55

您甚至可以打高尔夫球:)但是,您需要在代码下添加一个注释,该注释<esc>表示一个原义的0x1B ESC字节。字节数是242,而不是246
埃里克Outgolfer

@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

Perl 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的固定尺寸。

在线查看!


Perl 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确定终端的大小。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.