庞码中最短的


28

挑战很简单。给出尽可能短的代码,以重现pong的经典2人游戏http://en.wikipedia.org/wiki/Pong。图形和功能级别应尽可能接近此javascript演示http://codeincomplete.com/posts/2011/5/14/javascript_pong/demo.html(但如果没有其他选项,您可以单击左侧的或右下角的帧,fps等信息)。

与往常一样,代码必须以一种自由的语言编写(在两种意义上),并且可以在linux上运行。使用的任何库也必须是免费的,易于使用的,并且不能为比赛目的而编写(并且还没有包含Pong!的工作版本)。


老实说,对于代码高尔夫来说,这个问题有点太难了。Pong的球物理非常复杂。
beary605

@ beary605,我认为球的物理原理并不复杂。我的解决方案“尽可能接近” JavaScript演示,并且物理过程非常简单。

仅供参考,还有一些其他的[code-golf]运行时间很长。构建一个迷宫游戏引擎Noughts and Crosss(又名井字游戏)(两者都可以使用其他条目,默认情况下谁喜欢“赢”?),编写一个小型HTTP服务器自解释器自编译编译器编译正则表达式 ...
dmckee 2013年

@felipa,您能否正式化“越近越好”?我不知道为什么我的sed解决方案无法发挥主导作用。

1
@ beary605 太难了吗?
FantaC

Answers:


24

Javascript 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元素:

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

播放器1使用qa键,而播放器2使用pl键。esc按键暂停,按任意键开始/继续。

您可以在此处的浏览器中播放它

我不确定要使用的物理方法,因此我从一种简单的反射方法开始,然后添加了一些变化并进行了一些试验。球在y方向上的速度受您在球拍上击球的位置的影响,因此您可以控制球的运动方向。球在x方向上的速度随着反弹中的每次击打而缓慢增加。

我怀疑它会很容易被使用库的解决方案击败,但是我很高兴用普通的javascript编写它。


2
这是一个非常好的实现。
felipa 2013年

1
还可以打更多的高尔夫球,我知道我迟到了两年。但是您可以分配20给一个名为的变量g并保存一个较小的字节。
扎卡里

该死,很难用azerty键盘弹奏……
昏暗的

38

sed,35岁

提高标准通过加盖邮票的静心冥想来的位置。

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

可以在两台计算机的stdin / stdout上进行冥想,而不必通过网络连接。冥想开始于状态

0         <       1

上师在左边为零,在右边为一。尖括号向左和向右移动,如果一位上师操纵他们的数字以使其接触到其侧面时与光标接触,它们的分数将增加1,并且他们会感到高兴。

通过将以上状态键入 sed -f medi.sed,然后计算机以下一个状态进行响应。虔诚的宗师输入冥想,大声朗读他们将要按下的下一键,两位大师同时按下通往enter未来的圣键。尽职计算机将回复下一个状态。反过来,与上一次一样键入时,则将其朗读。继续前进到未来,直到实现无限的幸福。

希望挑战的专家可能会使用“ turbo”模式,其中专家试图共同预测计算机的下一个状态,并将其键入提示中而不是当前状态。古鲁斯将有智慧在进入未来之前验证他们的预测之间的一致性。


23
杜德...我刚刚读了什么?
MrZander

9
@MrZander只有通过广泛的沉思,才能展现出冥想的智慧。通过程序的执行,可以最好地帮助这种思考。
展位

15

Python(含pygame)650字节

特征

  • 1和2玩家模式 -游戏开始时,按11个或22个玩家。在按下这些键之一之前,游戏不会开始。
  • 增加球的速度 -每一次抽球,球的速度都会增加,以至于在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您在Linux下运行吗?我将看看是否可以找到一种与所选字体无关的替代方案。偏转的想法是,可以使球以比桨叶可以移动的速度更快的速度(在我的秤上最大为2.5)偏转(1.67)。只有给它一些“旋转”,才有可能。如果击球时桨叶不动,则最大速度为1.5
2013年

是的,我正在使用Linux。我感到奇怪的是,球在击中桨叶后实际上可以“后退”(向上或向下),而不是沿相同方向(也许以不同的角度)继续前进。但是,我不知道Atari版本是否做到了。
2013年

@aditsu它花了几个字节,但是我相信无论选择哪种字体,分数都应该居中(只要是等宽字体)。请让我知道这对你有没有用。是的,挠度与我熟悉的Atari版本非常相似(尽管分布更平滑)。如果您将球拍想象成(凸)弯曲的表面(例如曲棍球球拍),我认为它应该更直观。
2013年

是的,它现在
处于

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小时)几乎是相同的傍我有我的雅达利2600的原始版本
普里莫

@primo我假设您是在谈论我的隐式声明,即您的解决方案不符合“尽可能接近”的标准。好吧,OP没有提到Atari 2600版本,而是他链接到的特定javascript实现。乍一看,您的代码有2个明显的区别:没有计算机播放器,也没有“ 7段”得分显示。“力学”之间可能还有更多差异。如果这些事情不重要,那么我认为该解决方案也应该有效。
aditsu

这是我的错 我确实的意思是“尽可能接近”,因此您的第一个解决方案是迄今为止最好的。
felipa

您可以删除c=window.c。您正在为其分配一个全局变量。
2013年

您可以++S[n].random(++S[n])
Shmiddty 2013年

5

HTML和JavaScript-1663

根据我更好的判断,我采取了疯狂的方法,将演示中的实际代码打入高尔夫球场。我删除了一些功能和界面元素,但是通常它的工作原理完全相同-0、1或2来选择人类玩家的数量,Q / A和P / L来移动。

除非我犯了一些错误,否则游戏玩法应该与原始分辨率相同,即像素为像素,毫秒为毫秒,为640 * 480(提示:调整浏览器窗口的大小会更改演示中的游戏大小)。它只是不给出指示,不宣布获胜者,也不处理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);}

屏幕截图示例:

enter image description here

编写此代码时考虑到了它的短促性,所以它是相当多的错误(有时球会穿过桨或环绕桨)。控件是对播放器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

乒乓球只是一个非常小的版本,其中球仅以对角线运行,并且始终具有相同的速度。

enter image description here


Failed outgolf: bit.ly/2VSIGz8
sergiol
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.