ASCII Ball in Box Animation


11

เขียนโปรแกรมที่แสดงลูกบอล ASCII ที่กำลังเคลื่อนที่*อยู่ในสี่เหลี่ยม (20 ถึง 10 ตัวอักษรรวมถึงเส้นขอบ) ลูกบอลต้องไม่ข้ามสี่เหลี่ยมผืนผ้าเช่นชนเมื่อชนกำแพง ฉากจะต้องถูกล้างและวาดใหม่ทุก 0.1 วินาทีและลูกบอลต้องเคลื่อนที่ 1 อักขระในทิศทาง x และ y ทุกเฟรม โปรแกรมที่สั้นที่สุดที่เขียนในภาษาใดก็ได้ชนะ

เอาต์พุตตัวอย่าง (เฟรม 1)

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

ตัวอย่างผลลัพธ์ (เฟรม 2)

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

เอาต์พุตตัวอย่าง (เฟรม 8)

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

ตัวอย่างผลลัพธ์ (เฟรม 9)

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

4
การพิมพ์ 99 บรรทัดใหม่มีคุณสมบัติเป็นการล้างหน้าจอหรือไม่
Ventero

ไม่ได้อยู่บนจอมอนิเตอร์ของฉันกับ1080x1920ความละเอียด :)
mellamokb

ที่เกี่ยวข้อง: codegolf.stackexchange.com/q/110410/55735
ติตัส

คำตอบ:


7

Ruby 1.9, 115 ตัวอักษร

ตรรกะการเคลื่อนไหวค่อนข้างคล้ายกับDanko 's คำตอบ

รุ่นนี้ได้รับการทดสอบบน 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}

ด้วย Ruby 1.9.3 ภายใต้ Windows 7 puts"\e[2J"เพียงพิมพ์←[2J(และขึ้นบรรทัดใหม่) บนหน้าจอ
res

@res ดูการแก้ไขสำหรับเวอร์ชันที่ควรรันบน Windows (ไม่สามารถทดสอบด้วยตนเองได้)
Ventero

การใช้clsไม่ได้ผลสำหรับฉัน แต่system ("cls")ทำได้
res

@res ใช้ `cls ' backticks ตัวอักษร
Mark Reed

@ MarkReed - นั่นคือสิ่งที่ฉันพยายามเขียน .. อย่างไรก็ตามมันใช้งานไม่ได้ Windows ดูเหมือนจะต้องการระบบ ("cls")
res

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}ซึ่งแทนที่สี่ตัวifก่อนหน้านี้ ;-) ฉันแน่ใจว่าจะต้องมีสูตร แต่
Joey

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

@padde - ดูเหมือนว่าจะไม่ทำงานเมื่อฉันรันโปรแกรม Ruby ของคุณใน Windows 7 (ดูความคิดเห็นของฉันที่โพสต์ของคุณ)
res

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}

Ungolfed:

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ทำงานด้วยหรือ
Joey

ไม่ไม่ใช่ใน 1.9 SyntaxError: (irb):1: no .<digit> floating literal anymore; put 0 before dot. แต่ฉันจะกลับไปที่ถ้าฉันต้องการในอนาคตขอบคุณ!
Patrick Oscity

หากคุณอยู่ที่ 1.9 คุณสามารถใช้ตัวอักษรถ่านเพื่อย่อบางสิ่งเช่น?*แทน'*'ฯลฯ
Joey

ใช้ Ruby 1.9.3 ภายใต้ Win7 นี้จะพิมพ์รูปสี่เหลี่ยมผืนผ้าหนึ่งหลัง (ด้านล่าง) อื่น ๆ แต่ละคนมี←[2J←[f+------------------+เป็นบรรทัดแรก
res

จากนั้นเปลี่ยน$> << "\e[2J\e[f"+fเป็น'cls';$><<f(ใช้ backticks เพื่อcls)
Patrick Oscity

2

จาวาสคริปต์ (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)

ตัวอย่าง: 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 ตัวอักษร

35 ตัวอักษรขี้อายจากคำตอบของ @ Ventero แต่ฉันก็รู้สึกประทับใจที่ฉันสามารถทำให้มันลงไปได้ไกลมากในขณะที่ยังใช้วิธีการที่ตรงไปตรงมากับตรรกะที่แท้จริง ^ [คือ 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

อีกรายการทุบตี - 213 204 ตัวอักษร

ไม่ใช่ผู้ชนะรางวัลจริงๆ แต่ก็สนุกดี มันใช้ลำดับถ่าน vt100 สำหรับการวาดภาพ (รหัสที่รายงานที่นี่ใช้ 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 ไบต์

แรงบันดาลใจจาก 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}

สคริปต์นี้ใช้ตัว-replaceดำเนินการเพื่อวาด*ภายในสี่เหลี่ยม

สคริปต์ golfed น้อยลงเพื่ออธิบายวิธีการทำงาน:

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 ในบรรทัดecho -e "\e[$2;$1H$3"สามารถสร้างได้โดย

echo -e "\x1b"

เพื่อแทนที่ ในฐานะไบนารี 0x1b จะสั้นลง 3 ตัวอักษร ฉันนับเพียง 1 สำหรับ "\ E" เพราะเพียง layouting \eกองกำลังซอฟแวร์ผมที่จะใช้


ผู้ใช้ที่ไม่ระบุชื่อแนะนำให้ทำการแก้ไขเพื่อลบ$สัญลักษณ์ภายใน((...))และแทนที่x=$(($x+$p))ด้วย((x+=p))และคล้ายกันในบรรทัดต่อไปนี้ (พวกเขายังแนะนำให้ใช้\eสำหรับตัวละครหนีด้วย)
Peter Taylor

ผมจะแนะนำนอกจากว่าอาจจะทำงานแทนสำหรับ\* "*"
Peter Taylor

@PeterTaylor: ขอบคุณผู้ใช้ที่ไม่ระบุชื่อ ฉันรวมข้อเสนอแนะหมายเลข 1 และใช้หมายเลข 2 ในแบบฟอร์มที่แก้ไขแล้วและของคุณ
ผู้ใช้ที่ไม่รู้จัก

@userunknown: คุณเป็นตัวแทนของ1,337ความต้องการที่จะถูกล็อคอย่างถาวรในสถานที่: P
mellamokb

1
@mellamokb: มันหายไปแล้ว
ผู้ใช้ที่ไม่รู้จัก

0

TI Basic, 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และคุณสามารถใช้ประโยชน์จาก Ans เพื่อบันทึกไม่กี่ไบต์ในรอบสุดท้ายสำหรับ (วนซ้ำฉันเส้นบวก 8 และ 9 สามารถเล่นกอล์ฟได้ แต่ฉันไม่แน่ใจว่าตอนนี้อย่างไร
MI Wright

@MIWright ฉันจะใส่ Ans ที่ไหน?
ช่วง

"| \ Output(O,1,Ans \ Output(O,20,Ansควรทำงาน.
MI Wright

@MIWright แต่นั่นไม่ใช่การแทนที่สตริงอักขระสองตัวด้วยสตริงอักขระสามตัวใช่ไหม และการเพิ่มสตริงอักขระสองตัวด้านบนทำให้เป็น +4?
ช่วง

คุณหมายถึงอะไร Ansเป็นโทเค็นหนึ่งไบต์2nd (-)ที่พิมพ์ด้วย นั่นจะเป็นการบันทึกหนึ่งไบต์เนื่องจาก|โทเค็นคือสองไบต์บนเครื่องคิดเลข
MI Wright

0

PHP, 196 186 148 ไบต์

ฉันลบออกโดยหลีกเลี่ยงการล้นจำนวนเต็มเพื่อบันทึก 6 ไบต์ มันจะทำงานเป็นเวลา 29 พันล้านปีก่อนที่จะล้น ยัง 6.8 ปีในระบบ 32 บิต ฉันพูดได้ว่าเป็นที่ยอมรับ

การคำนวณตำแหน่งแทนการปรับตำแหน่งจะบันทึกเป็นจำนวนมากเตรียมเทมเพลตที่สมบูรณ์พร้อมกันในล็อตอื่น

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");
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.