Bóng ASCII trong hoạt hình hộp


11

Viết chương trình hiển thị một quả bóng ASCII đang di chuyển *bên trong một hình chữ nhật (20 x 10 ký tự bao gồm cả đường viền). Quả bóng không được vượt qua hình chữ nhật, ví dụ như va đập khi nó chạm vào tường. Cảnh phải được xóa và vẽ lại sau mỗi 0,1 giây và bóng phải di chuyển 1 char theo hướng x và y mỗi khung hình. Chương trình ngắn nhất được viết bằng bất kỳ ngôn ngữ nào.

Ví dụ đầu ra (khung 1)

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

Ví dụ đầu ra (khung 2)

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

Ví dụ đầu ra (khung 8)

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

Ví dụ đầu ra (khung 9)

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

4
Có in 99 dòng mới đủ điều kiện như xóa màn hình?
Ventero

Không có trên màn hình của tôi với 1080x1920độ phân giải :)
mellamokb

Câu trả lời:


7

Ruby 1.9, 115 ký tự

Logic chuyển động khá giống với câu trả lời của Danko .

Phiên bản này đã được thử nghiệm trên 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}

Với Ruby 1.9.3 trong Windows 7, puts"\e[2J"chỉ cần in ←[2J(và một dòng mới) trên màn hình.
res

@res Xem bản chỉnh sửa của tôi để biết phiên bản chạy trên Windows (không thể tự kiểm tra phiên bản đó).
Ventero

Sử dụng clskhông làm việc cho tôi, nhưng system ("cls")không.
res

@res sử dụng `cls`. Backticks nghĩa đen.
Mark Reed

@MarkReed - Đó là những gì tôi đã cố viết .. Dù sao, nó không hoạt động. Windows dường như yêu cầu hệ thống ("cls").
res

4

Powershell, 144 ký tự

Dựa trên câu trả lời xuất sắc của Joey , sử dụng thực tế là tọa độ bóng là một hàm của chỉ số khung (i), vì vậy nếu bạn có thứ gì đó như x=n-abs(n-(i mod (2*n))), x sẽ chuyển từ 0 đến n, trở về 0, v.v.

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}

Đẹp một. Mặc dù tôi rất tự hào về if(-1,18-eq$x){$a*=-1;$x+=2*$a}if(-1,8-eq$y){$b*=-1;$y+=2*$b}điều đó đã thay thế bốn ifgiây trước đó ;-). Tôi đã chắc chắn rằng phải có một công thức, mặc dù.
Joey

3

Con trăn 2, 234

Tôi chắc chắn rằng điều này có thể được chơi gôn nhiều hơn, nhưng tôi phải đi đây là những gì tôi có. sẽ làm việc nhiều hơn sau

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)

lưu ý: hoạt động trên bảng điều khiển lệnh Windows. Các hệ điều hành khác có thể sử dụng một lệnh khác ngoài clsviệc xóa màn hình, chẳng hạn nhưclear


không print "\e[H\e[2J"hoạt động trên windows?
Patrick Oscarity

@padde - Nó dường như không hoạt động khi tôi chạy chương trình Ruby của bạn trong Windows 7 (xem nhận xét của tôi về bài đăng của bạn).
res

3

Hồng ngọc ( 179 174 147)

EDIT đã loại bỏ một số ký tự khác:

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}

EDIT cạo sạch một số ký tự, bây giờ 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}

Ung dung:

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...
}                           #

Không nên sleep .1làm việc quá?
Joey

Không, không phải trong 1.9. SyntaxError: (irb):1: no .<digit> floating literal anymore; put 0 before dot. Nhưng tôi sẽ quay lại với điều đó nếu tôi cần nó trong tương lai, cảm ơn!
Patrick Oscarity

Nếu bạn ở trên 1.9, bạn có thể sử dụng các ký tự char để rút ngắn một số thứ, ví dụ ?*thay vì '*', v.v.
Joey

Sử dụng Ruby 1.9.3 trong Win7, cái này in hình chữ nhật lần lượt (bên dưới) cái kia, mỗi cái có ←[2J←[f+------------------+dòng đầu tiên.
res

sau đó đổi $> << "\e[2J\e[f"+fthành 'cls';$><<f(sử dụng backticks cho cls)
Patrick Oscarity

2

JavaScript (275 283 )

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)

Bản trình diễn: http://jsfiddle.net/eKcfu/2/

Tôi đã viết nó lên khá nhanh vì vậy tôi chắc chắn vẫn còn khá nhiều chỗ để cải thiện. Đề xuất được chào đón :)

Chỉnh sửa 1 : Loại bỏ cuộc gọi chức năng riêng biệt không cần thiết, nhúng trực tiếp vào setInterval.


2

Haskell, 212 ký tự

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

Sử dụng một cách tiếp cận chức năng hơn để tính toán tọa độ, bằng cách tạo chuỗi vô hạn cho mỗi tọa độ riêng biệt và sau đó nén chúng lại với nhau (dòng 2 và 3). Phần còn lại là vẽ mã.


2

PowerShell, 184 185 215

Chỉ chơi gôn vì não tôi không hoạt động bình thường khi tôi bị ốm ...

Một vài thủ thuật hay trong đó, mặc dù.

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}

[Chỉnh sửa]: Vòng lặp trên trường ngắn hơn nhiều.


2

QBasic (QB64), 178 173 byte

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 byte nhờ DLosc


Đẹp! Đối với vòng lặp vô hạn, bạn có thể sử dụng DO ... LOOPthay thế WHILE 1 ... WENDvà lưu 5 byte.
DLosc

1

Perl 5, 141 ký tự

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

Không bắt đầu ở góc trên bên trái như đầu ra ví dụ, nhưng điều đó không được nêu là một yêu cầu.


1

Ruby 1.9, 162 ký tự

35 câu trả lời ngại ngùng về câu trả lời của @ Ventero, nhưng tôi rất ấn tượng rằng tôi có thể đưa nó xuống đến mức này trong khi vẫn sử dụng một cách tiếp cận tương đối đơn giản với logic thực tế. ^ [Là một ESC theo nghĩa đen (1 char).

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 ký tự

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

Một mục bash khác - 213 204 ký tự

Không thực sự là một người chiến thắng giải thưởng, nhưng dù sao nó cũng rất vui. Nó sử dụng chuỗi char vt100 cho bản vẽ. (mã được báo cáo ở đây sử dụng 215 ký tự cho khả năng đọc, có thể xóa 2 ký tự bằng cách thoát, ví dụ: '*' -> \ *

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 byte

Lấy cảm hứng từ câu trả lời của Danko Durbić .

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

Kịch bản này sử dụng -replacetoán tử để vẽ *bên trong hình chữ nhật.

Kịch bản ít chơi gôn hơn để giải thích cách thức hoạt động:

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

Bash 278 300, 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 trong dòng echo -e "\e[$2;$1H$3"có thể được sản xuất bởi

echo -e "\x1b"

để thay thế nó. Như nhị phân 0x1b, nó ngắn hơn 3 ký tự; Tôi chỉ đếm 1 cho "\ e", vì chỉ phần mềm bố trí buộc tôi sử dụng \e.


Một người dùng ẩn danh đã đề xuất các chỉnh sửa để xóa các $ký hiệu bên trong ((...))và thay thế x=$(($x+$p))bằng ((x+=p))và tương tự trên dòng sau. (Họ cũng đề nghị sử dụng \echo nhân vật thoát).
Peter Taylor

Tôi sẽ đề nghị ngoài ra \*có thể làm việc thay thế cho "*".
Peter Taylor

@PeterTaylor: Cảm ơn người dùng ẩn danh. Tôi đã kết hợp đề xuất số 1 và sử dụng số 2 ở dạng đã sửa đổi và của bạn.
người dùng không xác định

@userunknown: Bạn 1,337cần phải khóa vĩnh viễn tại chỗ: P
mellamokb

1
@mellamokb: Nó đi rồi.
người dùng không xác định

0

TI Basic, 169 167 byte

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

Rất chậm, nhưng nó hoạt động.


(X=20)→Scó thể (X=20→S, và bạn có thể tận dụng Ans để lưu một vài byte trong vòng lặp For (vòng lặp. Tôi có thể chơi các dòng 8 và 9 tích cực, nhưng tôi không chắc tại thời điểm này.
MI Wright

@MIWright Tôi sẽ đặt Ans ở đâu?
giai đoạn

"| \ Output(O,1,Ans \ Output(O,20,Ansnên làm việc.
MI Wright

@MIWright Nhưng không phải là thay thế một chuỗi hai ký tự bằng một chuỗi ba ký tự sao? Và thêm hai chuỗi ký tự phía trên nó, làm cho nó +4?
giai đoạn

Ý anh là gì? Ansmã thông báo một byte , được nhập bằng 2nd (-). Điều đó sẽ kết thúc việc lưu một byte, vì |mã thông báo là hai byte trên máy tính.
MI Wright

0

PHP, 196 186 148 byte

Tôi đã loại bỏ việc tránh tràn số nguyên để lưu 6 byte. Nó sẽ chạy trong 29 tỷ năm trước khi tràn; vẫn còn 6,8 năm trên hệ thống 32 bit. Tôi nói rằng những người khác chấp nhận được.

Tính toán vị trí thay vì điều chỉnh nó đã tiết kiệm rất nhiều, chuẩn bị mẫu hoàn chỉnh ở một lô khác.

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;

Chạy với -nr. Yêu cầu PHP 7.1.

sự cố :

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");
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.