가장 짧은 코드에서 탁구


28

도전은 간단합니다. pong http://en.wikipedia.org/wiki/Pong 의 고전적인 2 인 게임을 재현 할 수있는 가장 짧은 코드를 제공하십시오 . 그래픽 및 기능 수준은이 자바 스크립트 데모 http://codeincomplete.com/posts/2011/5/14/javascript_pong/demo.html 과 최대한 비슷해야합니다 (그러나 추가 옵션이 없으면 왼쪽을 클릭 할 수 있음) 또는 오른쪽 하단의 프레임, fps 등 정보).

항상 코드는 자유 언어로 작성되어야하고 (두 가지 의미에서) 리눅스에서 실행할 수 있어야합니다. 사용 된 모든 라이브러리는 무료로 제공되며 쉽게 구할 수 있어야하며이 경쟁의 목적으로 작성되지 않아야합니다 (그리고 아직 Pong!


솔직히,이 질문은 코드 골프에는 조금 어렵다. 탁구의 공 물리는 매우 복잡합니다.
beary605

@ beary605, 나는 공 물리학이 너무 복잡하다고 생각하지 않습니다. 내 솔루션은 자바 스크립트 데모와 '가능한 한'가깝고 물리학은 매우 간단합니다.
부스비

참고로 꽤 오랫동안 실행되는 다른 [golf-golf]가 있습니다. 미로 게임 , Noughts and Crosses (일명 Tic-Tac-Toe) 용 엔진 구축 (둘 다 기본적으로 "승리"하는 추가 항목을 사용할 수 있습니까?), 작은 HTTP 서버 작성 , 자체 통역 통역사 , 자체 컴파일러 컴파일 , 정규식 컴파일 ...
dmckee

@felipa, '가능한 한 가깝게'공식화 할 수 있습니까? 내 sed 솔루션이 선두에 있지 않은 이유를 모르겠습니다.
부스비

답변:


24

자바 스크립트, 883 (+ 70 HTML)

c=document.getElementById('c').getContext('2d')
c.fillStyle="#FFF"
c.font="60px monospace"
w=s=1
p=q=a=b=0
m=n=190
x=300;y=235
u=-5;v=3
setInterval(function(){if(w&&!s)return;s=0
c.clearRect(0,0,640,480)
for(i=5;i<480;i+=20)c.fillRect(318,i,4,10)
m+=p;n+=q
m=m<0?0:m;m=m>380?380:m
n=n<0?0:n;n=n>380?380:n
x+=u;y+=v
if(y<=0){y=0;v=-v}
if(y>=470){y=470;v=-v}
if(x<=40&&x>=20&&y<m+110&&y>m-10){u=-u+0.2;v+=(y-m-45)/20}
if(x<=610&&x>=590&&y<n+110&&y>n-10){u=-u-0.2;v+=(y-n-45)/20}
if(x<-10){b++;x=360;y=235;u=5;w=1}
if(x>640){a++;x=280;y=235;u=-5;w=1}
c.fillText(a+" "+b,266,60)
c.fillRect(20,m,20,100)
c.fillRect(600,n,20,100)
c.fillRect(x,y,10,10)},30)
document.onkeydown=function(e){k=(e||window.event).keyCode;w=w?0:k=='27'?1:0;p=k=='65'?5:k=='81'?-5:p;q=k=='40'?5:k=='38'?-5:q;}
document.onkeyup=function(e){k=(e||window.event).keyCode;p=k=='65'||k=='81'?0:p;q=k=='38'||k=='40'?0:q}


/* Variable index:
a -> left player score
b -> right player score
c -> context
e -> event
i -> counter for dashed line
k -> keycode
m -> left paddle y
n -> right paddle y
p -> left paddle y velocity
q -> right paddle y velocity
s -> is start of game
u -> ball x velocity
v -> ball y velocity
w -> game is waiting (paused)
x -> ball x
y -> ball y
*/

스크립트는 끝에 배치 <body>하거나 호출 할 수 있습니다 onLoad. 다음 캔버스 요소가 필요합니다.

<canvas id="c"width="640"height="480"style="background:#000"></canvas>

플레이어 1은 qa키를 사용하고 플레이어 2는 pl키를 사용합니다 . esc키를 눌러 일시 중지하고 아무 키나 눌러 시작 / 계속하십시오.

브라우저 에서 여기 에서 재생할 수 있습니다 .

사용할 물리를 확신 할 수 없었기 때문에 간단한 리플렉션 방법으로 시작한 다음 몇 가지 다양성을 추가하고 약간 실험했습니다. y 방향의 공 속도는 패들에서 공을 치는 위치에 영향을 받으므로 공이가는 위치를 약간 제어 할 수 있습니다. x 방향으로의 공 속도는 랠리를 칠 때마다 천천히 증가합니다.

라이브러리를 사용하는 솔루션으로 쉽게 이길 수 있다고 생각하지만 일반 자바 스크립트로 만드는 것이 재미있었습니다.


2
정말 좋은 구현입니다.
felipa

1
좀 더 골프를 쳤을지도 모르겠다. 나는 약 2 년 늦었다. 그러나 20이름이 지정된 변수에 할당 g하고 1 바이트를 저장할 수 있습니다.
Zacharý

젠장, 아제르바이잔 키보드로 연주하기가 어렵습니다 ...
dim

38

sed, 35

우표 스탬프 sed 명상으로 바를 조금 올립니다.

s/> / >/
s/ </< /
s/0</0>/
s/>1/<1/

명상은 두 대의 컴퓨터에서 stdin / stdout에서 즐길 수 있으며 반드시 네트워크로 연결되어 있지는 않습니다. 명상은 주에서 시작됩니다

0         <       1

왼쪽에 guru 0이 있고 오른쪽에 guru 0이 있습니다. 꺾쇠 괄호는 좌우로 움직이며, 전문가가 숫자를 움직여 커서를 옆으로 향하게하면 점수가 1 씩 증가하고 기쁨으로 기뻐합니다.

위의 상태를에 입력하면 명상이 시작되고 sed -f medi.sed컴퓨터가 다음 상태로 응답합니다. 성실한 전문가는 명상에 대해 말하면서 그들이 누를 다음 키를 큰 소리로 읽으며 두 전문가 모두 동시에 거룩한 키를 누르십시오 enter. 충실한 컴퓨터는 다음 상태로 응답합니다. 이것은 마지막과 마찬가지로 입력하여 큰 소리로 읽습니다. 무한한 행복이 올 때까지 미래로 나아가십시오.

도전을 원하는 전문가들은 '터보'모드를 사용할 수 있는데, 전문가들은 컴퓨터의 다음 상태를 협력 적으로 예측하고 현재 상태 대신 프롬프트에 입력하려고 시도합니다. 전문가는 미래에 들어가기 전에 예측 간의 일치를 확인하는 지혜를 가질 것입니다.


23
야 ... 방금 뭐 읽었 어?
MrZander

9
@MrZander 광범위한 명상을 통해서만 명상의 지혜가 드러날 수 있습니다. 이 묵상은 프로그램의 실행을 통해 가장 잘 도움이됩니다.
boothby

15

파이썬 ( 파이 게임 포함 ) 650 바이트

풍모

  • 1 및 2 플레이어 모드 -게임이 시작되면을 눌러 11 2명 또는 2 명을 누릅니다 . 이 키 중 하나를 누를 때까지 게임이 시작되지 않습니다.
  • 볼 속도 증가 -각 발리에서 볼 속도가 증가하여 10 발리 후 약 50 % 증가하고 20 후에는 그보다 50 % 빠릅니다.
  • 가변 볼 변형 -볼 변형은 패들의 어느 부분이 부딪 치는가와 충격에 따라 패들이 움직이는 지 여부에 따라 결정됩니다. 공이 한쪽 끝 근처에서 패들을 치는 경우, 공이 중간 근처에서 치는 것 (거의 곡면 인 것처럼)보다 더 강하게 편향됩니다. 또한, 패들이 움직이고 있다면, 패들의 움직임이 편향에 추가됩니다. 가장 강한 처짐을 얻으려면 공이 패들 끝 근처에 부딪쳐 야하고 패들은 같은 끝쪽으로 움직여야합니다. 이것은 Atari 2600의 원래 Pong과 매우 유사합니다.
  • 일시 중지 -언제든지 Space바를 눌러 게임을 일시 중지 할 수 있습니다 . 스페이스 바를 두 번 누르면 재생이 다시 시작됩니다.
  • 컨트롤 -예에서와 같이 플레이어 1은 QA키로 이동하고 플레이어 2는 P및로 이동 L합니다.

마지막으로, 여러 가지 이유로이 솔루션을 수락 된 답변으로 선택하지 말 것을 요청하고 싶습니다.

from pygame import*
init();d=display;s=d.set_mode((640,480))
g=p=16;j=q=80;x=y=200;o=t=h=v=1;z=m=n=0;w=[255]*3
while s.fill(time.wait(3)):
 event.get();k=key.get_pressed();t^=o*k[32];o=1-k[32];z=z or-k[49]-k[50]*2;e=k[113]-k[97];f=[k[112]-k[108],(h>0)*cmp(y,q-32)][z];a=p<g;b=q-[y,x][a]
 if p%608<g:m,n,p,h,v=[m+1-a,m,n+a,n,g+a*592,p,1-a*2,h/-.96,1,b/32.+~[f,e][a]][-g<b<j::2]
 for r in[(0,x,g,j),(624,y,g,j),(p,q,g,g)]+[(316,i*31,8,15)for i in range(g)]:draw.rect(s,w,r)
 if z*t:v*=(0<q<464)*2-1;x-=(0<x-e<400)*e/.6;y-=(0<y-f<400)*f/.6;p+=h;q+=v
 c=font.SysFont('monospace',j,1).render('%3d %%-3d'%m%n,1,w);s.blit(c,(320-c.get_width()/2,0));d.flip()

샘플 화면 캡처 :

참고 : 점수에 사용되는 글꼴은 시스템마다 다를 수 있습니다.


점수는 나를 위해 왼쪽 절반에 표시되며, 편향이 너무 강하다고 생각하지만 어쨌든 꽤 시원합니다 :)
aditsu

@aditsu 당신은 리눅스에서 운영하고 있습니까? 선택한 서체와 상관없이 작동하는 대안을 찾을 수 있는지 살펴 보겠습니다. 편향의 배후에있는 아이디어 는 패들이 움직일 수있는 것보다 빠른 속도 ( 내 스케일에서 최대 2.5)로 볼을 편향시킬 수 있다는 것입니다 ( 1.67 ). 이것은 당신이 그것에 '회전'을 줄 경우에만 가능합니다. 공이 타격을받을 때 패들이 움직이지 않으면 최대 속도는 1.5가 됩니다.
primo

예, 저는 Linux를 사용하고 있습니다. 공이 같은 방향 (아마 다른 각도에서)을 계속 유지하는 대신, 패들을 친 후에 공이 실제로 "뒤로"(위 또는 아래로) 움직일 수 있다는 것이 이상합니다. 그러나 아마도 Atari 버전은 그렇게했을 것입니다.
아디 츠

@aditsu 몇 바이트가 들었지만 선택한 글꼴에 관계없이 점수가 중심에 있어야한다고 생각합니다 (단일 공간 인 한). 그것이 당신을 위해 작동하는지 알려주세요. 그리고 예, 처짐은 내가 익숙했던 Atari 버전과 매우 유사합니다 (더 매끄럽게 분포되어 있지만). 패들을 (볼록한) 곡면 (에어 하키 패들과 같은)으로 생각한다면 더 직관적이어야한다고 생각합니다.
프리모

네 중앙에 있습니다
aditsu

8

HTML 및 JavaScript (2)-525

OP는 "가능한 한 가까운"부분에 대해 크게 신경 쓰지 않는 것처럼 보였으므로 다음은 무자비하게 단순화하고 벗겨 내고 골프를 치는 대안 솔루션입니다. Q / A와 P / L을 연주하지만 다른 모든 키도 효과가 있습니다. 다시 말하지만 코드는 완전히 독립적이며 Linux의 Chromium 25에서 테스트했습니다. 작은 버그를 수용하거나 그래픽 품질 / 게임 플레이의 성능을 크게 저하시킬 수 있다면 더 골프를 타실 수 있습니다.

<canvas id=c><script>C=c.getContext('2d');f=C.fillRect.bind(C)
S=[-1,I=J=0];A=B=210;X=Y=1
function g(n){++S[n];N=Math.random(M=n*613+9)*471}D=document
D.onkeydown=D.onkeyup=function(e){d=!!e.type[5];k=e.keyCode
k&1?I=k&16?d:-d:J=k&4?-d:d}
g(0);setInterval(function(){A-=A<I|A>420+I?0:I
B-=B<J|B>420+J?0:J
M+=X;N+=Y
N<0|N>471?Y=-Y:0
M==622&N>B&N<B+51|M==9&N>A&N<A+51?X=-X:M>630?g(0):M||g(1)
f(0,0,c.width=640,c.height=480)
C.fillStyle='tan';C.font='4em x';C.fillText(S,280,60)
f(0,A,9,60);f(631,B,9,60);f(M,N,9,9)},6)</script>

감사합니다 Shmiddty


나는 이의를 이해하지 못한다. 내가 기억할 수있는 한, 715 바이트 버전 (이 포스트 3 시간 전에 편집 된)은 내가 Atari 2600에 대해 가지고 있던 Pong의 원래 버전과 거의 동일하다.
primo

@primo 귀하의 솔루션이 "가능한 한 가까운"기준을 충족하지 않는다는 내 암시적인 주장에 대해 이야기하고 있다고 가정합니다. OP는 Atari 2600 버전을 언급하지 않았지만 그가 링크 한 특정 자바 스크립트 구현을 언급했습니다. 첫눈에 코드에는 두 가지 눈에 띄는 차이가 있습니다. 컴퓨터 플레이어가없고 "7- 세그먼트"점수 표시가 없습니다. "역학"에는 훨씬 더 많은 차이가있을 것입니다. 이러한 것들이 중요하지 않다면이 솔루션도 유효해야한다고 생각합니다.
aditsu

이것은 나의 실수이다. 나는 "가능한 한 가깝다"는 것을 의미했기 때문에 첫 번째 솔루션이 지금까지 최고입니다.
felipa

를 제거 할 수 있습니다 c=window.c. 전역 변수를 자신에게 할당하고 있습니다.
Shmiddty

++S[n].random(++S[n])
Shmiddty

5

HTML 및 JavaScript-1663

더 나은 판단에 반대하여 데모에서 실제 코드를 골라내는 미친 접근 방식을 취했습니다. 일부 기능과 인터페이스 요소를 제거했지만 일반적으로 0, 1 또는 2와 동일하게 작동하여 인간 플레이어 수, Q / A 및 P / L을 선택하여 이동합니다.

내가 실수를하지 않는 한 게임 플레이는 픽셀 단위 픽셀과 밀리 초 단위로 밀리 초 단위로 동일해야합니다 (힌트 : 브라우저 창의 크기를 조정하면 데모의 게임 크기가 변경됨). 지시 사항을 제시하지 않고 당첨자를 발표하지 않으며 esc를 처리하지 않습니다.

코드는 완전히 독립적이며 Linux의 Chromium 25에서 테스트했습니다. Firefox는 그다지 좋아하지 않습니다.

<body bgcolor=0><canvas id=c height=480><script>R=Math.random
C=c.getContext('2d');f=C.fillRect.bind(C)
S=[l=G=I=J=K=L=0,0];r=17;u=463;o=24;q=12;z=10;s=640;v=36
function T(z,t,u,v){P=0;if(e=v*E-u*F){a=(u*t-v*z)/e;b=(E*t-F*z)/e
a<0|a>1|b<0|b>1?0:P={x:M+a*E,y:N+a*F,d:u,s:0,X:X,Y:Y}}}function
i(p,q,h){T(p-22*(E<0),q,0,h)
P?0:T(p,q-h*(F<0),22,0)}function
U(p){if(p.a)if(M<p.x&X<0|M>p.x+q&X>0)p.u=0
else{P=p.P;if(P&&P.X*X>0&P.Y*Y>0&P.s<p.l/z)P.s+=t
else{E=X*z;F=Y*z;i(M-p.x+5,s*q,s*o)
if(p.P=P){y=P.y;while(y<r|y>u)y=y<r?34-y:y>u?u+u-y:y
P.y=y+R(e=(p.l+2)*(X<0?M-p.x-q:p.x-M)/64)*2*e-e}}P?p.u=P.y<p.y+25?1:P.y>p.y+35?-1:0:0}y=p.y-p.u*t*198
p.y=y<q?q:y>408?408:y}function
W(n,x){a=9.6;b=[~8,3,62,31,75,93,~2,7,-1,u][n]
b&4&&f(x,o,v,a);b&64&&f(x,o,a,o)
b&2&&f(x+v,o,-a,o);b&8&&f(x,43.2,v,a)
b&32&&f(x,48,a,o);b&1&&f(x+v,48,-a,o)
b&16&&f(x,72,v,-a)}A={u:0,x:0,y:210};B={u:0,x:628,y:210}
function g(n){if(++S[n]>8)G=A.a=B.a=0
else{N=R(M=n?635:5)*446+r;Y=157.5;X=n?-Y:Y
A.l=z+S[0]-S[1];B.l=20-A.l}}D=document
D.onkeydown=D.onkeyup=function(e){d=!!e.type[5]
k=e.keyCode-45;if(k>2&k<6&d&!G){G=S=[-1,0];A.a=k<4;B.a=k<5
g(0)}k^31?k^35?k^20?k^v?0:I=d:J=d:K=d:L=d
A.a?0:A.u=I-J;B.a?0:B.u=K-L}
setInterval(function(){t=new Date()/1000-l;l+=t;U(A);U(B)
if(G){E=t*X+4*t*t;F=t*Y+4*t*t
x=M+E;y=N+F;m=X+t*(X>0?8:-8);n=Y+t*(Y>0?8:-8)
if(n>0&y>u){y=u;n=-n}if(n<0&y<r){y=r;n=-n}p=m<0?A:B
i(M-p.x+5,N-p.y+5,70)
if(P){if(P.d){y=P.y;n=-n}else{x=P.x;m=-m}n*=n*p.u<0?.5:p.u?1.5:1}M=x;N=y
X=m;Y=n;M>645?g(0):M<-5&&g(1)}c.width=s;C.fillStyle='#fff'
f(0,0,s,q);f(0,468,s,q);for(j=o;j--;)f(314,6+o*j,q,q)
W(S[0],266.5);W(S[1],338.5)
f(0,A.y,q,60);f(s,B.y,-q,60);G&&f(M-5,N-5,z,z)},50/3)</script>

개선을위한 Shmiddty의 일부 크레딧


4

처리 중, 487 자

int a=320,b=240,c=2,d=2,e=0,f=0,g=0,h=0,i=15,j=80,k=640,
l=160,m;void setup(){size(k,b*2);}void draw(){background
(0);if(keyPressed){if(key=='q'&&g>0)g-=i;if(key=='a'&&g<
j*5)g+=i;if(key=='o'&&h>0)h-=i;if(key=='l'&&h<j*5)h+=i;}
rect(0,g,i,j);for(m=0;m<k;m+=30)rect(312,m,i,i);rect(a,b
,i,i);rect(625,h,i,j);a+=c;b+=d;c*=a<i&&(b>g&&b+i<g+j)||
a>610&&(b>h&&b+i<h+j)?-1:1;d*=b<0||b>=465?-1:1;if(a<0){f
++;a=0;b=240;c=2;}if(a>k){e++;a=625;b=240;c=-2;}textSize
(j);text(e,l,j);text(f,3*l,j);}

샘플 스크린 샷 :

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

이 코드는 짧음을 염두에두고 만들어 졌기 때문에 버그가 많았습니다 (공이 때때로 패들을 통과하거나 그 주위를 감 쌉니다). 컨트롤은 플레이어 1의 Q / A와 플레이어 2의 O / L입니다.


1
게임마다 Pong 버전도 프레임 당 하나의 플레이어 키만 등록되므로 상당히 불공평 해 보입니다. P
Jonathan Frech

2

C #-1283 자

이것은 훨씬 더 골프를 칠 수 있지만 여기 있습니다.

using System;using System.Drawing;using System.Runtime.InteropServices;using System.Windows.Forms;using r=System.Drawing.RectangleF;namespace f{public partial class f:Form{public f(){InitializeComponent();}private void f_Load(object sender,EventArgs e){var t=this;var s=new r(0,0,300,300);var q=new r(0,0,15,50);var o=new r(0,0,15,50);var x=new PointF(150,150);var v=.06F;var h=v;var b=new r(x.X,x.Y,15,15);var p1=0;var p2=0;var p=new PictureBox{Size=t.Size,Location=new Point(0,0)};t.Controls.Add(p);p.Paint+=(wh,n)=>{var g=n.Graphics;Action<Brush,r>f=g.FillRectangle;var k=new SolidBrush(Color.Black);var w=new SolidBrush(Color.White);var d=new byte[256];GetKeyboardState(d);var l=q.Location;var _1=.1F;q.Location=new PointF(0,d[90]>1?l.Y+_1:d[81]>1?l.Y-_1:l.Y);l=o.Location;o.Location=new PointF(269,d[77]>1?l.Y+_1:d[79]>1?l.Y-_1:l.Y);f(k,s);f(w,q);f(w,o);Func<r,bool>i=b.IntersectsWith;h=i(q)||i(o)?-h:h;v=b.Top<1||b.Bottom>t.Height-30?-v:v;b.Offset(h,v);if(b.Left<0){p2++;b.Location=x;}if(b.Right>290){p1++;b.Location=x;}f(w,b);for(int j=0;j<19;)f(w,new r(140,(j+(j++%2))*15,10,10));var a=new Font("Arial",20);g.DrawString(p1.ToString(),a,w,100,12);g.DrawString(p2.ToString(),a,w,170,12);p.Invalidate();};}[DllImport("user32.dll")]static extern bool GetKeyboardState(byte[]s);}}

편집 : 무료 Linux 실행 언어에 대한 요구 사항을 보지 못했습니다 ...


2

Tcl / Tk , 932 바이트

대화식 쉘에서 실행해야합니다.

gri [can .c -w 1024 -he 768 -bg #000]
proc A {} {set ::v [expr (int(rand()*36)+1)*20]}
proc R {C t\ X} {.c cr r $C -f #aaa -t $t}
proc I {} {incr ::v 20}
time {R "504 [I] 520 [I]"} 18
R "0 0 1024 20"
R "0 748 1024 768"
R "0 340 20 440" b
R "1004 340 1024 440" B
R "40 [A] 60 [I]" P
lmap n 4\ 5 T F\ S {.c cr t ${n}62 60 -ta $T -te 0 -fi #aaa -font {"" 56}}
proc C t\ n {lindex [.c coo $t] $n}
lmap {a b c d e} {q b 1 >20 -20 a b 3 <740 20 p B 1 >20 -20 l B 3 <740 20} {bind . $a "if \[C $b $c]$d {.c move $b 0 $e}"}
lassign {0 0 20 20} F S y x
proc M {} {lmap {_ a b c d e f} {0 <40 b 20 S 960 980 2 >984 B -20 F 80 100} {if [C P $_]$a {if [C P 1]>=[C $b 1]&&[C P 3]<=[C $b 3] {bell
set ::x $c} {.c itemco $d -te [incr ::$d]
if \$::$d>8 {tk_messageBox -message WINNER!
lmap T F\ S {.c itemco $T -te [set ::$T 0]}}
.c coo P $e [A] $f [I]}}}
.c move P $::x [set ::y [expr [C P 1]<40?20:[C P 3]>727?-20:$::y]]
after 99 M}
M
focus -f .

노트 :

 #There is an Enter at the end

공은 대각선으로 만 달리고 항상 같은 속도를 갖는 아주 작은 Pong 버전입니다.

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


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