最短コードでポン


28

挑戦は簡単です。pong http://en.wikipedia.org/wiki/Pongの古典的な2人用ゲームを再現するために、可能な限り最短のコードを提供します。グラフィックと機能のレベルは、このjavascriptデモンストレーションhttp://codeincomplete.com/posts/2011/5/14/javascript_pong/demo.htmlに可能な限り近い必要があります(ただし、左側にある追加オプションなしでクリックできます)または、右下のフレーム、fpsなどの情報)。

いつものように、コードは(両方の意味で)自由言語で書かれていなければならず、Linuxで実行可能でなければなりません。また、使用するライブラリはすべて無料で、簡単に入手でき、このコンペティションの目的で作成されてはなりません(また、Pongの作業バージョンがまだ含まれていない必要があります!)。


正直なところ、この質問はコードゴルフには少し難しすぎます。Pongのボール物理学はかなり複雑です。
beary605

@ beary605、ボールの物理学が複雑すぎるとは思わない。私のソリューションはjavascriptのデモに「可能な限り近い」ものであり、物理学は非常に単純です。
ブースビー

参考のために、かなり長く実行される他の[コードゴルフ]があります。迷路ゲームのエンジンを構築しNoughts and Crosses(別名Tic-Tac-Toe)(どちらもデフォルトで「勝つ」ことを好む追加エントリを使用できますか?)、小さなHTTPサーバーを書く自己解釈通訳自己-コンパイルするコンパイラコンパイル正規表現 ...
dmckee

@felipa、「できるだけ近い」形式化できますか?私のsedソリューションがリードしていない理由がわかりません。
ブースビー

1
@ beary605難しすぎる?
FantaC

回答:


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 id="c"width="640"height="480"style="background:#000"></canvas>

プレイヤー1つの用途qaキー、およびプレーヤー2つの用途pおよびlキー。押してesc一時停止するための鍵と継続/開始時に任意のキーを押します。

ここでブラウザ再生できます

使用する物理学がわからないので、単純な反射法から始めて、いくつかの種類を追加して、少し実験しました。y方向のボールの速度は、パドルのどこでボールを打ったかによって影響を受けるため、ボールの行き先をある程度制御できます。ラリーでヒットするたびに、x方向のボールの速度がゆっくりと増加します。

ライブラリを使用したソリューションによって簡単に破られると思われますが、プレーンJavaScriptで作成するのは楽しかったです。


2
それは本当に素晴らしい実装です。
フェリパ

1
もう少しゴルフができるかもしれませんが、ここで約2年遅れています。ただし20、名前の付いた変数に割り当てて、g1バイトを節約できます。
ザカリー16

くそー、アゼルティーキーボードで演奏するのは難しい...-
薄暗い

38

sed、35

郵便切手のセッド瞑想でバーを少し上げる

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

瞑想は、ネットワークで接続されているとは限らない2台のコンピューターのstdin / stdoutで楽しめます。瞑想は州で始まります

0         <       1

教祖0が左側に、1つが右側にあります。山かっこは左右に移動し、達人が自分の番号を操作してカーソルを横に移動すると、スコアが1つ増加し、喜びで大喜びします。

瞑想は、上記の状態をに入力することで開始されsed -f medi.sed、コンピューターは次の状態で応答します。従順な教祖は瞑想に登場し、彼らが押す次のキーを読み上げ、同時に両方の教祖が聖なるキーを押しenterます。忠実なコンピューターは次の状態で応答します。これは、最後と同じように一斉に入力されている間に読み上げられます。無限の至福が達成されるまで、未来へと進み続けます。

チャレンジを望む達人は「ターボ」モードをプレイできます。このモードでは、達人はコンピューターの次の状態を共同で予測し、現在の状態ではなくプロンプトに入力しようとします。グルには、未来に入る前に予測の一致を確認する知恵があります。


23
おい...何を読んだの?
MrZander

9
@MrZander広範な熟考を通してのみ、瞑想の知恵が明らかにされます。この熟考は、プログラムの実行によって最も助けられます。
ブースビー

15

Python(pygameを使用)650バイト

特徴

  • 1および2プレーヤーモード -ゲームの開始時に、11プレーヤーまたは22プレーヤーを押します。これらのキーのいずれかが押されるまで、ゲームは開始されません。
  • ボール速度の増加 -各ボレーでは、ボール速度が増加し、10ボレー後は約​​50%増加し、20ボレー後はそれよりも50%速くなります。
  • 可変ボールのたわみ -ボールのたわみは、パドルのどの部分に当たるか、およびインパクト時にパドルが動いているかどうかという2つの要因に基づいています。ボールが端の1つ近くでパドルに衝突すると、ボールは中央付近で衝突する場合よりも強く曲がります(まるで曲面であるかのように)。さらに、パドルが動いている場合、パドルの動きがたわみに追加されます。最も強いたわみを得るには、パドルの端近くでボールを打たなければならず、パドルは同じ端に向かって動いている必要があります。これは、Atari 2600の元のPongと非常によく似ています。
  • 一時停止 - Spaceバーを押すと、いつでもゲームを一時停止できます。スペースバーをもう一度押すと、再生が再開されます。
  • コントロール -例と同様に、プレーヤー1が移動するQAキー、とプレイヤー2が移動するPL

最後に、さまざまな理由から、このソリューションを承認済みの回答として選択しないようにお願いします。

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になります。
primo

はい、Linuxを使用しています。ボールが同じ方向に(おそらく異なる角度で)連続するのではなく、パドルを打った後に実際に「戻る」(上または下に)移動できるのは奇妙だと思います。しかし、アタリ版がそれをしたのかもしれません、私は知りません。
-aditsu

@aditsu数バイトかかりましたが、選択されたフォントに関係なく、スコアは中央に配置されるべきだと思います(等幅である限り)。うまくいくかどうか教えてください。そして、はい、たわみは私がよく知っていたアタリバージョンに非常に似ています(より滑らかな分布ですが)。パドルを(エアホッケーパドルのように)(凸状の)曲面として想像すると、より直感的になるはずです。
primo

はい、それは今中心にあります
-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


私は異議を理解していません。私の知る限り思い出すことができるよう、(3時間この記事の前に編集した)715バイトバージョンはポン私はアタリ2600のために持っていた元のバージョンとほぼ同じです
プリモ

@primoあなたのソリューションは「可能な限り近い」基準を満たさないという私の暗黙の主張について話していると思います。まあ、OPはAtari 2600バージョンについて言及していませんでしたが、彼がリンクした特定のjavascript実装について言及していました。また、一見すると、コードには2つの明らかな違いがあります。コンピュータープレーヤーも「7セグメント」スコア表示もありません。「メカニクス」にはおそらくもっと多くの違いがあります。これらのことが重要でない場合、このソリューションも有効であると思います。
aditsu

これは私の間違いです。私は本当に「できる限り近い」という意味でしたので、あなたの最初の解決策はこれまでのところ最高です。
フェリパ

を削除できますc=window.c。グローバル変数をそれ自体に割り当てています。
Shmiddty

あなたは移動することによって、1つの以上の文字を保存することができます++S[n]の内側.random(++S[n])
Shmiddty

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);}

サンプルのスクリーンショット:

ここに画像の説明を入力してください

このコードは短さを念頭に置いて作成されたため、かなりバグがあります(ボールがパドルを通過したり、パドルを包んだりすることがあります)。コントロールは、プレーヤー1ではQ / A、プレーヤー2ではO / Lです。


1
P:唯一のプレイヤーのキーはフレームごとに登録されているとしてゲームとして、あなたのポンバージョンも、非常に不公平なようだ
ジョナサン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

ボールが斜めの角度でのみ走り、常に同じ速度を持つ、ポンの非常に最小限のバージョンです。

ここに画像の説明を入力してください


失敗したアウトゴルフ:bit.ly/2VSIGz8
sergiol
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.