盒子动画中的ASCII球


11

编写一个程序,*在矩形内显示一个移动的ASCII球(20 x 10个字符,包括边框)。球一定不能越过矩形,例如,碰到墙时会掉落。必须每隔0.1秒钟清除并重新绘制场景,并且每帧球必须在x和y方向上移动1个字符。以任何一种语言编写的最短程序都将获胜。

输出示例(帧1)

+------------------+
|*                 |
|                  |
|                  |
|                  |
|                  |
|                  |
|                  |
|                  |
+------------------+

输出示例(第2帧)

+------------------+
|                  |
| *                |
|                  |
|                  |
|                  |
|                  |
|                  |
|                  |
+------------------+

输出示例(第8帧)

+------------------+
|                  |
|                  |
|                  |
|                  |
|                  |
|                  |
|                  |
|       *          |
+------------------+

输出示例(第9帧)

+------------------+
|                  |
|                  |
|                  |
|                  |
|                  |
|                  |
|        *         |
|                  |
+------------------+

4
打印99个换行符是否可以清除屏幕?
Ventero'4

我的显示器上没有1080x1920分辨率:)
mellamokb

Answers:


7

Ruby 1.9,115个字符

运动逻辑与Danko答案非常相似。

此版本仅在Linux上经过测试。

p=0
loop{u=(?|+?\s*18+"|
")*8
u[165-21*(7-p%14).abs-(17-p%34).abs]=?*
p+=1
puts"\e[2J",r=?++?-*18+?+,u,r
sleep 0.1}

使用Windows 7下的Ruby 1.9.3,puts"\e[2J"只需←[2J在屏幕上打印(和换行符)即可。
2012年

@res请参阅我的编辑以获取应在Windows上运行的版本(不幸的是我自己无法对其进行测试)。
Ventero'4

使用cls对我来说system ("cls")不起作用,但对我来说有效。
res 2012年

@res使用`cls`。字面反引号。
马克·里德

@MarkReed-那就是我试图写的..无论如何,它不起作用。Windows似乎需要system(“ cls”)。
res 2012年

4

Powershell,144个字符

基于乔伊(Joey)的出色答案,它利用了球坐标是帧索引(i)的函数这一事实,因此,如果您具有x=n-abs(n-(i mod (2*n))),x将从0变为n,然后回到0,依此类推...

for(){cls
($l="+$('-'*18)+")
7..0|%{$j=$_
"|$(-join(17..0|%{'* '[$j-[Math]::abs(7-$i%14)-or$_-[Math]::abs(17-$i%34)]}))|"}
$l;$i++;sleep -m 100}

好东西。尽管我为自己的名字感到自豪,因为我早些时候if(-1,18-eq$x){$a*=-1;$x+=2*$a}if(-1,8-eq$y){$b*=-1;$y+=2*$b}替换了4 ifs ;-)。不过,我确定必须有一个公式。
乔伊

3

Python 2,234

我敢肯定,这可以打更多,但我得走了,所以这就是我的沙发。以后会更多的工作

import os,time
a,b,c,d,e,n='+- |*\n'
w=d+c*18+d+n
s=a+b*18+a+n
x,y=0,0
g,h=17,7
j,k=1,1
while 1:
 if 0>x or x>g:j*=-1;x+=j
 if 0>y or y>h:k*=-1;y+=k
 os.system('cls');print s+w*y+d+c*x+e+c*(g-x)+d+n+w*(h-y)+s;x+=j;y+=k;time.sleep(0.1)

注意:在Windows命令控制台上工作。其他操作系统可能会使用cls与清除屏幕不同的命令,例如clear


确实print "\e[H\e[2J"在Windows上工作?
Patrick Oscity 2012年

@padde-当我在Windows 7下运行您的Ruby程序时,它似乎不起作用(请参阅我对您的帖子的评论)。
2012年

3

红宝石(179 174 147)

编辑摆脱了更多的字符:

l=?++?-*18+?++?\n
c=?|+?\s*18+?|+?\n
p=22
u=v=1
loop{f=l+c*8+l
f[p]=?*
puts"\e[2J"+f
p+=(u=f[p+u]==' '?u:-u)+21*(v=f[p+21*v]==' '?v:-v)
sleep 0.1}

编辑删除了一些字符,现在是174:

l="+#{'-'*18}+\n";f=l+"|#{' '*18}|\n"*8+l;x=y=u=v=1
loop{f[21*y+x]='*';$><<"\e[2J\e[f"+f;f[21*y+x]=' '
u=f[21*y+x+u]==' '?u:-u;v=f[21*(y+v)+x]==' '?v:-v
x+=u;y+=v;sleep 0.1}

取消高尔夫:

l="+#{'-'*18}+\n"           # top and bottom lines 
f=l+"|#{' '*18}|\n"*8+l     # complete box as string
x=y=u=v=1                   # x,y position; u,v next move
loop {                      #
  f[21*y+x]='*'             # add ball to box
  $> << "\e[2J\e[f"+f       # clear screen and print box with ball
  f[21*y+x]=' '             # remove ball from box
  u=f[21*y+x+u]==' '?u:-u   # next move in x direction
  v=f[21*(y+v)+x]==' '?v:-v # next move in y direction
  x+=u                      # perform move
  y+=v                      # --"--
  sleep 0.1                 # .zZZ...
}                           #

也不能sleep .1工作吗?
乔伊

不,不是1.9版。SyntaxError: (irb):1: no .<digit> floating literal anymore; put 0 before dot。但是如果将来我需要,我会再说一遍,谢谢!
Patrick Oscity

如果你在1.9你可以使用字符文字缩短了一些东西,例如?*,而不是'*'
乔伊

在Win7下使用Ruby 1.9.3,它在另一个之后(下方)打印矩形,每个矩形都←[2J←[f+------------------+作为第一行。
2012年

然后更改$> << "\e[2J\e[f"+f'cls';$><<f(使用反引号cls
Patrick Oscity 2012年

2

JavaScript(275283

s=Array(19).join(' ');n='\n';z=Array(9).join('|'+s+'|'+n).split(n,8);
x=y=0;a=b=1;t='+'+s.replace(/ /g,'-')+'+';
setInterval(function(){u=z[y];z[y]=u.replace(eval('/( {'+x+'}) /'),'$1*');
$('#o').text(t+n+z.join('\n')+n+t);z[y]=u;x+=a;y+=b;if(!x|x==17)a=-a;if(!y|y==7)b=-b},100)

演示:http//jsfiddle.net/eKcfu/2/

我很快就写完了,所以我相信仍有很大的改进空间。欢迎提出建议:)

编辑1:删除不必要的单独函数调用,直接嵌入setInterval


2

Haskell,212个字符

import System
main=mapM_ f$s 19`zip`s 9
s n=[2..n]++[n-1,n-2..3]++s n
f p=r"clear">>putStr(unlines[[" |-+*"!!(19#i+2*(9#j)+4*e((i,j)==p))|i<-[1..20]]|j<-[1..10]])>>r"sleep 0.1"
b#n=e$n<2||n>b
e=fromEnum
r=system

使用一种功能更强的方法来计算坐标,方法是分别为每个坐标创建无限序列,然后将它们压缩在一起(第2行和第3行)。剩下的就是绘图代码。


2

PowerShell,184 185 215

生病时我的大脑无法正常工作,只能半打...

不过,其中有一些不错的技巧。

for($a=$b=1){cls
($l="+$('-'*18)+")
0..7|%{$j=$_
"|$(-join(0..17|%{'* '[$j-$y-or$_-$x]}))|"}
$l
$x+=$a;$y+=$b
if(-1,18-eq$x){$a*=-1;$x+=2*$a}if(-1,8-eq$y){$b*=-1;$y+=2*$b}sleep -m 100}

[编辑]:在字段上循环要短得多。


2

QBasic中(QB64),178个 173字节

a$="+------------------+
?a$
for c=1to 8
?"|                  |
next
?a$
do
x=19-abs(17-(i mod 34))
y=9-abs(7-(i mod 14))
locate y,x
?"*
_delay .1
locate y,x
?" "
i=i+1
loop

-5字节归功于DLosc


真好!对于无限循环,你可以用DO ... LOOP代替WHILE 1 ... WEND,并保存5个字节。
DLosc

1

Perl 5,141个字符

print"\e[H\e[2J",$h="+"."-"x18 ."+
",(map{"|".$"x$q,(abs$t%14-7)-$_?$":"*",$"x(17-$q),"|
"}0..7),$h,select'','','',0.1while$q=abs$t++%34-17,1

不会像示例输出那样从左上角开始,但这不是必需的。


1

Ruby 1.9,162个字符

@Ventero的答案低了35个字符,但令我印象深刻的是,我仍然可以使用相对简单的方法来处理实际逻辑,而将其归类。^ [是文字ESC(1个字符)。

x=y=0
v=h=1
s=' '
loop{puts"^[[2J"+b="+#{?-*18}+",*(0..7).map{|i|"|#{i!=y ?s*18:s*x+?*+s*(17-x)}|"},b
y+=v
y+=v*=-1if y<0||y>7
x+=h
x+=h*=-1if x<0||x>17
sleep 0.1}

1

R,233个字符

s=c("\n+",rep("-",18),"+");for (j in 1:8){cat(s,sep="");cat(rep(c("\n|",rep("",17),"|"),j-1));cat(c("\n|",rep(" ",j-1),"*",rep(" ",18-j),"|"),sep="");cat(rep(c("\n|",rep("",17),"|"),8-j));cat(s,sep="");Sys.sleep(0.1);system("clear")}

1

另一个bash的入门- 213 204个字符

并不是真正的获奖者,但仍然很有趣。它使用vt100 char序列进行绘图。(此处报告的代码使用215个字符,以提高可读性,可以通过转义删除2个字符,例如'*'-> \ *

e(){ printf "\e[$1";}
e 2J;e H
h='+------------------+'
echo $h
for((;++j<9;));do printf '|%18s|\n';done
echo $h
e '3;2H*'
while :;do
e 'D '
((i/17%2))&&e D||e C
((++i/7%2))&&e A||e B
e 'D*'
sleep .1
done

1

Powershell,139个字节

受到DankoDurbić的回答的启发。

for(){cls
,"+$('-'*18)+
"*2-join("|$(' '*18)|
"*8-replace"^(\W{$(21*[Math]::abs(7-$i%14)+[Math]::abs(17-$i++%34))}.) ",'$1*')
sleep -m 100}

该脚本使用-replace运算符*在矩形内部进行绘制。

较少使用的脚本来解释其工作原理:

for(){
    cls
    $y=[Math]::abs(7-$i%14)
    $x=[Math]::abs(17-$i++%34)
    $b="+$('-'*18)+`n"
    $m="|$(' '*18)|`n"*8-replace"^(\W{$(21*$y+$x)}.) ",'$1*'
    ,$b*2-join($m)          # draw it
    sleep -m 100
}

0

重击278300、296

h="+------------------+"
w="|                  |"
g(){
echo -e "\e[$2;$1H$3"
}
g 1 1 $h
for i in {1..8}
do
echo "$w"
done
echo $h
x=4
y=4
p=1
q=1
for((;;))
do
((x==19&&p==1||x==2&&p==-1))&&p=-$p
((y==9&&q==1||y==2&&q==-1))&&q=-$q
x=$((x+p))
y=$((y+q))
g $x $y \*
sleep .1
g $x $y " "
done

该行中的\ e echo -e "\e[$2;$1H$3"可以由

echo -e "\x1b"

更换它。作为二进制0x1b,它缩短了3个字符;我只为“ \ e”计算1,因为只有版面设计软件才会强制我使用\e


一位匿名用户建议进行编辑以删除其中的$符号,并在下一行类似地((...))替换x=$(($x+$p))((x+=p))。(他们还建议使用\e转义字符)。
彼得·泰勒

我建议另外使用它\*代替"*"
彼得·泰勒

@PeterTaylor:感谢匿名用户。我合并了建议1,并以修改后的形式使用了2,而您则是。
用户未知

@userunknown:您是1,337需要永久锁定的代表:P
mellamokb '04

1
@mellamokb:它不见了。
用户未知

0

TI基础,169个 167字节

1→X
1→Y
1→S
1→T
While 1
ClrHome
Output(Y,X,"*
S(X>1 and X<20)+(X=1)-(X=20→S
T(Y>1 and Y<10)+(Y=1)-(Y=10→T
X+S→X
Y+T→Y
For(N,1,20,19
For(O,1,10,9
Output(O,N,"+
End
End
For(N,2,19
For(O,1,10,9
Output(O,N,"-
End
End
For(O,2,9
Output(O,1,"|
Output(O,20,"|
End
End

速度很慢,但是可以。


(X=20)→S可以(X=20→S,你可以利用的AN节省几个字节的决赛(循环我肯定行8,9可以golfed,但我不知道此刻如何。
MI赖特

@MIWright我将Ans放在哪里?
阶段

"| \ Output(O,1,Ans \ Output(O,20,Ans应该管用。
MI Wright 2015年

@MIWright但是,这不是用三个字符串替换两个字符串吗?并在其上方添加两个字符串,使其变为+4?
阶段

你什么意思?Ans是一个一字节的令牌,键入2nd (-)。由于|令牌在计算器上是两个字节,因此最终将节省一个字节。
MI Wright

0

PHP,196186148字节

我删除了避免整数溢出以节省6个字节的操作。它将持续运行290亿年,直到溢出为止。在32位系统上仍然是6.8年。我说那是可以接受的。

计算位置而不是调整位置可以节省很多时间,可以一次又一次准备完整的模板。

for(;++$i;$s[-3-21*abs($i%14-7)-abs($i%34-17)]="*",print$f(_,9e5,"
").$s.$z,usleep(1e5))$s=($f=str_pad)($z=$f("+",19,"-")."+
",189,$f("|",19)."|
");
").$z;

与运行 -nr。需要PHP 7.1。

细目

for(;++$i;      # infinite loop:
                    # 2. set asterisk at appropriate position
    $s[-3-21*abs($i%14-7)-abs($i%34-17)]="*";
                    # 3. clear screen: print 900k newlines
    print$f(_,9e5*0+2,"\n")
            .$s.$z, # 4. print field
    usleep(1e5))    # 5. sleep 100000 microseconds
                    # 1. create template
    $s=($f=str_pad)($z=$f("+",19,"-")."+\n",189,$f("|",19)."|\n");
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.