Pong dalam kode terpendek

28

Tantangannya sederhana. Berikan kode sesingkat mungkin untuk mereproduksi permainan 2 pemain klasik pong http://en.wikipedia.org/wiki/Pong . Tingkat grafik dan fungsionalitas harus sedekat mungkin dengan demonstrasi javascript ini http://codeincomplete.com/posts/2011/5/14/javascript_pong/demo.html (tetapi tanpa opsi tambahan Anda dapat mengklik di sebelah kiri) atau bingkai, informasi fps dll. di kanan bawah).

Seperti biasa kode harus ditulis dalam bahasa bebas (dalam kedua pengertian) dan harus dapat dijalankan di linux. Setiap perpustakaan yang digunakan juga harus gratis, mudah tersedia, dan tidak ditulis untuk tujuan kompetisi ini (dan juga belum mengandung versi Pong yang berfungsi!).

felipa
sumber
Sejujurnya, pertanyaan ini agak terlalu sulit untuk kode golf. Fisika bola untuk Pong cukup rumit.
beary605
@ beary605, saya tidak berpikir fisika bola terlalu rumit. Solusi saya adalah 'sedekat mungkin' dengan demonstrasi javascript, dan fisika cukup sederhana.
Stanby
Hanya untuk referensi ada beberapa [kode-golf] lain yang berjalan cukup lama. Bangun mesin untuk permainan labirin , Noughts and Crosses (alias Tic-Tac-Toe) (keduanya dapat menggunakan entri tambahan, yang suka "menang" secara default?), Menulis server HTTP kecil , Penerjemah Interpretasi Mandiri , Self-Interpreter , Self- kompilasi kompiler , Kompilasi Regexes ...
dmckee
@felipa, Bisakah Anda memformalkan 'sedekat mungkin'? Saya tidak tahu mengapa solusi sed saya tidak dalam memimpin.
Stanby
1
@ beary605 terlalu sulit?
FantaC

Jawaban:

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
*/

Script dapat ditempatkan di akhir <body>atau dipanggil onLoad. Perlu elemen kanvas berikut:

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

Player 1 menggunakan qdan akunci, dan pemain 2 kegunaan yang pdan lkunci. Tekan esctombol untuk berhenti dan tombol apa saja untuk memulai / melanjutkan.

Anda dapat memainkannya di browser Anda di sini .

Saya tidak yakin dengan fisika yang akan digunakan, jadi saya mulai dengan metode refleksi sederhana dan kemudian menambahkan beberapa variasi dan sedikit bereksperimen dengannya. Kecepatan bola di arah y dipengaruhi oleh di mana pada dayung Anda memukul bola, sehingga Anda memiliki kontrol atas ke mana bola pergi. Kecepatan bola dalam arah x perlahan-lahan meningkat dengan setiap pukulan dalam reli.

Saya menduga itu akan dikalahkan dengan mudah dengan solusi menggunakan perpustakaan, tapi saya senang membuatnya dalam javascript biasa.

grc
sumber
2
Itu implementasi yang sangat bagus.
felipa
1
Bisa bermain golf sedikit lagi, saya tahu saya terlambat sekitar dua tahun di sini. tetapi Anda bisa menetapkan 20ke variabel bernama gdan menyimpan satu byte sangat sedikit.
Zacharý
Sial, sulit bermain di keyboard azerty ...
redup
38

sed, 35

Mengangkat bar sedikit dengan meditasi sed perangko.

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

Meditasi dinikmati di stdin / stdout di dua komputer, tidak harus terhubung oleh jaringan. Meditasi dimulai di negara bagian

0         <       1

dengan guru nol di sebelah kiri dan satu di sebelah kanan. Braket sudut bergerak ke kiri dan ke kanan, dan jika seorang guru melakukan manuver nomor mereka untuk menghubungi kursor ketika datang ke sisi mereka, skor mereka meningkat satu, dan mereka menjadi gembira dengan sukacita.

Meditasi dimulai dengan mengetik keadaan di atas sed -f medi.sed, dan komputer merespons dengan keadaan berikutnya. Guru yang berbakti mengetikkan meditasi, membaca dengan keras kunci berikutnya yang akan mereka tekan, dengan kedua guru menekan kunci suci ke entermasa depan pada saat yang sama. Komputer yang patuh membalas dengan keadaan berikutnya. Ini, pada gilirannya, dibacakan dengan keras saat diketik bersamaan dengan yang terakhir. Terus maju ke masa depan sampai kebahagiaan tanpa batas tercapai.

Gurus yang menginginkan tantangan dapat memainkan mode 'turbo', di mana guru mencoba untuk bersama-sama memprediksi kondisi komputer berikutnya, dan mengetiknya ke prompt alih-alih keadaan saat ini. Gurus akan memiliki kebijaksanaan untuk memverifikasi persetujuan antara prediksi mereka sebelum memasuki masa depan.

stan
sumber
23
Bung ... apa yang baru saja saya baca?
MrZander
9
@ MRZander Hanya melalui perenungan yang luas barulah kebijaksanaan meditasi dapat diungkapkan. Perenungan ini paling baik dibantu melalui pelaksanaan program.
Stanby
15

Python (dengan pygame ) 650 byte

fitur

  • Mode 1 dan 2 pemain - Saat permainan dimulai, tekan 1untuk 1 pemain, atau 2untuk 2 pemain. Permainan tidak akan dimulai sampai salah satu tombol ini ditekan.
  • Meningkatkan kecepatan bola - Setiap voli, kecepatan bola dinaikkan sehingga setelah 10 voli, volumenya meningkat sekitar 50%, setelah 20 akan menjadi 50% lebih cepat dari itu, dll.
  • Defleksi bola variabel - Defleksi bola didasarkan pada dua faktor: berapa bagian dayung yang dipukulnya, dan apakah dayung bergerak atau tidak. Jika bola memukul dayung di dekat salah satu ujungnya, itu akan dibelokkan lebih kuat daripada jika menyerang di dekat tengah (hampir seolah-olah itu adalah permukaan melengkung). Selain itu, jika dayung sedang bergerak, gerakan dayung ditambahkan ke defleksi. Untuk mendapatkan defleksi terkuat, bola harus menyerang di dekat ujung dayung, dan dayung harus bergerak ke arah ujung yang sama. Ini sangat mirip dengan Pong asli untuk Atari 2600.
  • Jeda - Permainan dapat dijeda kapan saja dengan menekan Spacebilah. Mainkan akan dilanjutkan setelah menekan spasi untuk kedua kalinya.
  • Kontrol - Seperti contoh, pemain 1 bergerak dengan Qdan Akunci, dan pemain 2 bergerak dengan Pdan L.

Sebagai catatan akhir, saya ingin meminta agar solusi ini tidak dipilih sebagai jawaban yang diterima, karena berbagai alasan.

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()

Contoh tangkapan layar:

Catatan: font yang digunakan untuk skor dapat bervariasi dari satu sistem ke sistem lainnya.

primo
sumber
Skor menunjukkan di setengah kiri untuk saya, dan saya pikir defleksi terlalu kuat, tapi tetap saja keren :)
aditsu
@aditsu apakah Anda beroperasi di linux? Saya akan melihat apakah saya dapat menemukan alternatif yang berfungsi terlepas dari wajah font yang dipilih. Gagasan di balik defleksi adalah bahwa mungkin untuk membelokkan bola dengan kecepatan lebih cepat (maksimum 2,5 pada skala saya) daripada dayung dapat bergerak ( 1,67 ). Ini hanya mungkin jika Anda memberinya 'putaran'. Jika dayung tidak bergerak saat bola menyerang, kecepatan maksimumnya adalah 1,5 .
Primo
Ya saya menggunakan Linux. Saya merasa aneh bahwa bola dapat benar-benar "kembali" (naik atau turun) setelah mengenai dayung, alih-alih melanjutkan ke arah yang sama (mungkin pada sudut yang berbeda). Tapi mungkin versi Atari yang melakukannya, saya tidak tahu.
aditsu
@aditsu Harganya beberapa byte, tapi saya percaya skornya harus terpusat terlepas dari font yang dipilih (asalkan itu monospace). Beri tahu saya jika itu berhasil untuk Anda. Dan ya, lendutannya sangat mirip (walaupun distribusinya lebih halus) dengan versi Atari yang saya kenal. Jika Anda membayangkan dayung sebagai permukaan (cembung) melengkung (seperti dayung hoki udara), saya pikir itu harus lebih intuitif.
Primo
Ya itu terpusat sekarang
aditsu
8

HTML & JavaScript (ambil 2) - 525

Karena OP tampaknya tidak terlalu peduli dengan bagian "sedekat mungkin", inilah solusi alternatif yang tanpa belas kasihan saya sederhanakan, lucuti, dan main golf. T / A dan P / L untuk dimainkan, tetapi setiap tombol lainnya juga memiliki efek. Sekali lagi, kode ini sepenuhnya mandiri dan saya mengujinya di Chromium 25 di Linux. Saya dapat bermain golf lebih jauh jika Anda dapat menerima bug kecil atau penurunan kualitas grafis / gameplay yang lebih besar.

<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>

Terima kasih Shmiddty

aditsu
sumber
Saya tidak mengerti keberatannya. Sejauh yang saya ingat, versi 715 byte (diedit 3 jam sebelum posting ini) hampir identik dengan versi asli Pong yang saya miliki untuk Atari 2600 saya.
primo
@ primo Saya berasumsi Anda sedang berbicara tentang klaim tersirat saya bahwa solusi Anda tidak memenuhi kriteria "sedekat mungkin". Nah, OP tidak menyebutkan versi Atari 2600, tetapi implementasi javascript tertentu yang ia tautkan. Dan pada pandangan pertama ada 2 perbedaan mencolok dalam kode Anda: tidak ada pemain komputer dan tidak ada tampilan skor "7-segmen". Mungkin ada lebih banyak perbedaan dalam "mekanika". Jika hal-hal ini tidak penting, maka saya pikir solusi ini juga harus valid.
aditsu
Ini kesalahan saya. Saya benar-benar bermaksud "sedekat mungkin" jadi solusi pertama Anda adalah yang terbaik sejauh ini.
felipa
Anda dapat menghapus c=window.c. Anda menugaskan variabel global untuk dirinya sendiri.
Shmiddty
Anda dapat menyimpan 1 karakter lebih banyak dengan pindah ke ++S[n]dalam.random(++S[n])
Shmiddty
5

HTML & JavaScript - 1663

Terhadap penilaian saya yang lebih baik, saya mengambil pendekatan gila golf kode sebenarnya dari demo. Saya menghapus beberapa fitur dan elemen antarmuka, tetapi umumnya berfungsi persis sama - 0, 1 atau 2 untuk memilih jumlah pemain manusia, Q / A dan P / L untuk dipindahkan.

Kecuali saya membuat beberapa kesalahan, gameplay harus identik, pixel untuk pixel dan milidetik untuk milidetik, ke aslinya di 640 * 480 (petunjuk: mengubah ukuran jendela browser mengubah ukuran game dalam demo). Itu hanya tidak memberikan instruksi, tidak mengumumkan pemenang dan tidak menangani esc.

Kode sepenuhnya mandiri dan saya mengujinya di Chromium 25 di Linux. Firefox tidak terlalu menyukainya.

<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>

Beberapa kredit untuk Shmiddty untuk perbaikan

aditsu
sumber
4

Memproses, 487 karakter

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

Contoh tangkapan layar:

masukkan deskripsi gambar di sini

Kode ini dibuat dengan pikiran pendek, sehingga sangat buggy (bola terkadang melewati dayung, atau membungkusnya). Kontrol adalah Q / A untuk Player 1 dan O / L untuk Player 2.

segfaultd
sumber
1
Sebagai permainan, versi Pong Anda juga tampaknya tidak adil, karena hanya satu kunci pemain yang terdaftar per frame: P
Jonathan Frech
2

C # - 1283 karakter

Ini bisa bermain golf lebih banyak tapi ini dia

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

Sunting: Tidak melihat persyaratan untuk bahasa yang dapat dijalankan linux gratis ...

Brandon
sumber
2

Tcl / Tk , 932 bytes

Harus dijalankan di shell interaktif

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 .

catatan:

 #There is an Enter at the end

Hanya versi Pong yang sangat minim, di mana bola hanya berjalan di sudut diagonal dan selalu memiliki kecepatan yang sama.

masukkan deskripsi gambar di sini

sergiol
sumber
Gagal outgolf: bit.ly/2VSIGz8
sergiol