En kısa koddaki Pong


28

Zor olan basittir. Http://en.wikipedia.org/wiki/Pong pong klasik 2 oyunculu oyununu yeniden oluşturmak için mümkün olan en kısa kodu verin . Grafiklerin ve işlevselliklerin seviyesi, bu javascript gösterisine http://codeincomplete.com/posts/2011/5/14/javascript_pong/demo.html adresinden mümkün olduğunca yakın olmalıdır (ancak solda tıklayabileceğiniz ekstra seçenek olmadan) veya sağ alt kısımdaki çerçeve, fps vb. bilgileri).

Her zaman olduğu gibi, kod serbest bir dilde yazılmalıdır (her iki anlamda da) ve Linux üzerinde çalıştırılabilir olmalıdır. Kullanılan kütüphaneler de ücretsiz, kolay erişilebilir olmalı ve bu yarışmanın amaçları için yazılmamalıdır (ve zaten Pong'un çalışan bir versiyonunu içermiyor!).


Dürüst olmak gerekirse, bu soru kod golf için biraz zor. Pong için top fiziği oldukça karmaşık.
beary605

@ beary605, top fiziğinin fazla karmaşık olduğunu sanmıyorum. Benim çözümüm javascript gösterisine 'olabildiğince yakın' ve fizik oldukça basit.
saat

Sadece referans olarak, oldukça uzun süren başka bazı kod kodları var. Bir labirent oyunu için bir motor oluşturun , Noughts ve Crosses (aka Tic-Tac-Toe) (her ikisi de varsayılan olarak "kazanmak" isteyen ek girişler kullanabilir mi?), Küçük bir HTTP sunucusu yaz , Kendi Kendine Tercüman , Kendi derleme , derleme Regexes derleme ...
dmckee

@ felipa, 'Mümkün olduğunca yakın' resmileştirebilir misiniz? Sed çözümümün neden lider olmadığını bilmiyorum.
Mart'ta

1
@ beary605 çok mu zor?
FantaC

Yanıtlar:


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

Komut dosyası sonuna yerleştirilebilir <body>veya çağrılabilir onLoad. Aşağıdaki tuval elemanına ihtiyaç duyuyor:

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

Oyuncu 1 qve atuşları kullanır ve oyuncu 2 pve ltuşları kullanır . Basın esctuşuna duraklatmak ve herhangi bir tuşa / devam başlatın.

Tarayıcınızda buradan oynayabilirsiniz .

Kullanılacak fizikten emin değildim, bu yüzden basit bir yansıtma yöntemiyle başladım ve biraz çeşitlilik ekledim ve biraz denedim. Topun y yönündeki hızı, kürek üzerinde topa vurduğunuz yerden etkilenir, böylece topun nereye gittiği üzerinde bazı kontrolleriniz vardır. Topun x yönündeki hızı, her ralli vuruşunda yavaşça artar.

Kütüphaneleri kullanarak çözümlerle kolayca dövülebileceğinden şüpheleniyorum, ancak basit bir javascript ile yazarken çok eğlendim.


2
Bu gerçekten hoş bir uygulama.
felipa

1
Biraz daha golf oynayabilir miyim, burada iki yıl geciktiğimi biliyorum. ancak 20bir değişkene atayabilir gve bir kızamık bayt kaydedebilirsiniz.
Zacharı,

Kahretsin, azerty klavyede oynamak zor ...
dim

38

sed, 35

Bir posta pulu sed meditasyon ile çıtayı biraz yükseltmek .

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

Meditasyon, mutlaka bir ağa bağlı olmayan iki bilgisayardaki stdin / stdout'ta gerçekleştirilir. Meditasyon eyalette başlar

0         <       1

solda gurusu sıfır, sağda biri. Açılı ayraç sola ve sağa hareket eder ve bir guru, imleci kendi taraflarına gelince imleçle temas ettirmek için numaralarına manevra yaparsa, puanları birer birer artar ve sevinçle mutlu olurlar.

Meditasyon, yukarıdaki durumu yazarak başlatılır sed -f medi.sedve bilgisayar bir sonraki duruma yanıt verir. Meditasyona giren güzel gurusu, basacakları bir sonraki tuşa sesli olarak okurken, her iki gurusu enterda aynı anda geleceğin kutsal tuşuna basıyor . Güzel bilgisayar bir sonraki duruma cevap veriyor. Bu da, en sondaki gibi bir arada yazarken yüksek sesle okunur. Sonsuz mutluluk elde edene kadar geleceğe doğru ilerlemeye devam edin.

Bir meydan okuma arzusunda bulunan Gurus, 'turbo' modunda oynayabilir; burada gurular, bilgisayarın sonraki durumunu işbirliği içinde tahmin etmeye çalışır ve onu mevcut durum yerine istemine yazar. Gurus, geleceğe girmeden önce tahminleri arasındaki anlaşmayı doğrulayacak bilgeliğe sahip olacak.


23
Dostum ... az önce ne okudum?
MrZander

9
@ MrZander Sadece kapsamlı bir tefekkürle meditasyonun bilgeliği ortaya çıkarılabilir. Bu tefekkür programın yürütülmesiyle en iyi şekilde desteklenir.
saat

15

Python ( pygame ile ) 650 bayt

Özellikler

  • 1 ve 2 oyuncu modu - Oyun başladığında, 11 oyuncu veya 22 oyuncu için tuşuna basın . Bu tuşlardan birine basılana kadar oyun başlamaz.
  • Top hızının arttırılması - Her voleybolun top hızı artar, böylece 10 volttan sonra yaklaşık% 50 artar, 20'den sonra 20'den% 50 daha hızlı olur.
  • Değişken bilya saptırma - Bilya saptırma iki faktöre dayanır: raketin hangi kısmına çarptığı ve raketin darbeyle hareket edip etmediği. Top, rakete uçlardan birinin yakınında vurursa, ortasına yakın vurulduğundan (neredeyse kavisli bir yüzeydeymiş gibi) olduğundan daha güçlü bir şekilde yön değiştirir. Ek olarak, eğer kürek hareket halinde ise, kürek hareketi sapmaya eklenir. En güçlü sapmayı elde etmek için, topun raketin ucuna çarpması ve raketin aynı uca doğru hareket etmesi gerekir. Bu, Atari 2600'ün orijinal Pong'una çok benzer.
  • Duraklat - Oyun Spacebara basılarak herhangi bir zamanda duraklatılabilir . Boşluk çubuğuna ikinci kez basıldığında oyun devam eder.
  • Kontroller - Örnekte olduğu gibi, oyuncu 1 Qve Atuşları ile hareket eder ve oyuncu 2 Pve ile hareket eder L.

Son bir not olarak, çeşitli sebeplerden dolayı bu çözümün kabul edilen cevap olarak seçilmemesini rica ediyorum.

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

Örnek ekran görüntüsü:

Not: Skor için kullanılan yazı tipi sistemden sisteme değişebilir.


Skor sol yarıda benim için gösteriyor ve bence sapma çok güçlü, ama yine de oldukça havalı :)
aditsu 14:13

@ aditsu Linux altında mı çalışıyorsunuz? Seçilen yazı tipi yüzünden bağımsız olarak çalışan bir alternatif bulabilecek miyim bir bakayım. Sapmanın arkasındaki fikir, topu fırlatmanın hareket ettirebileceğinden ( 1.67 ) daha hızlı bir hızda (ölçeğimde maksimum 2.5 ) saptırmanın mümkün olabileceğidir . Bu sadece biraz 'spin' verirseniz mümkündür. Topa vurduğunda raket hareket etmiyorsa, maksimum hız 1.5 olacaktır .
primo

Evet Linux kullanıyorum. Topun, aynı yöne (belki de farklı bir açıyla) devam etmek yerine, rakete vurduktan sonra gerçekte "geri" (yukarı veya aşağı) gidebilmesi garip buluyorum. Ama belki Atari versiyonu bunu yaptı, bilmiyorum.
aditsu

@aditsu Birkaç byte'a mal oldu, ancak seçilen yazı tipine bakılmaksızın skorun ortalanması gerektiğine inanıyorum (tek aralıklı olduğu sürece). İşe yararsa bana haber ver. Ve evet, sapma (daha yumuşak bir dağılım olmasına rağmen) aşina olduğum Atari versiyonuna çok benziyor. Raketi (dışbükey) kavisli bir yüzey (bir hava hokeyi raketi gibi) olarak hayal ediyorsanız, daha sezgisel olması gerektiğini düşünüyorum.
primo

Evet şimdi ortalanmış
aditsu 14:13

8

HTML ve JavaScript (2 al) - 525

OP, “mümkün olduğunca yakın” kısmıyla fazla ilgilenmiyor gibi göründüğü için, acımasızca basitleştirdiğim, çıkardığım ve golf oynadığım alternatif bir çözüm. Q / A ve P / L oynamak için, ancak diğer her tuşun da bir etkisi var. Yine, kod tamamen kendi kendine yetiyor ve onu Chromium 25'te Linux'ta test ettim. Küçük hatalar veya grafik kalitesinin / oyunun daha büyük bozunmasını kabul edebiliyorsanız daha da golf oynayabilirim.

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

Teşekkürler Shmiddty


İtirazı anlamıyorum. Bildiğim kadarıyla hatırlamak gibi, (3 saat bu yazı daha önce düzenlenmiş) 715 bayt sürümü Pong benim Atari 2600 için vardı orijinal sürümüne neredeyse aynıdır
primo

@primo Sanırım, çözümünüzün "mümkün olduğunca yakın" kriterine uymadığını ima ettiğim iddiamdan bahsediyorsunuz. Peki, OP Atari 2600 versiyonundan bahsetmedi, ancak bağlantı verdiği özel bir javascript uygulamasından bahsetti. İlk bakışta kodunuzda 2 farklı fark var: bilgisayar oynatıcısı yok ve "7 segmentli" skor gösterimi yok. "Mekanik" konusunda muhtemelen çok daha fazla fark var. Eğer bunlar önemli değilse, o zaman bu çözümün de geçerli olması gerektiğini düşünüyorum.
aditsu

Bu benim hatam. Gerçekten "mümkün olduğunca yakın" demek istedim, bu yüzden ilk çözümünüz şu ana kadarki en iyisi.
felipa

kaldırabilirsiniz c=window.c. Kendisine global bir değişken ataıyorsun.
Shmiddty

++S[n].random(++S[n])
Şunun

5

HTML ve JavaScript - 1663

Daha iyi karar vermeme karşı, çılgın demosundan golf oynamaya çılgınca bir yaklaşım izledim. Bazı özellikleri ve arayüz öğelerini kaldırdım, ancak genel olarak tam olarak aynı çalışıyor - insan oyuncu, Q / A ve P / L sayılarını seçmek için 0, 1 veya 2.

Bazı hatalar yapmadığım sürece oyun aynı olmalı, piksel için piksel ve milisaniye için milisaniye, 640 * 480'deki orijinalle aynı olmalıdır (ipucu: tarayıcı penceresinin yeniden boyutlandırılması demodaki oyun boyutunu değiştirir). Sadece talimat vermez, kazananı ilan etmez ve esc ile ilgilenmez.

Kod tamamen kendi kendine yetiyor ve onu Chromium 25'te Linux'ta test ettim. Firefox bundan pek hoşlanmıyor.

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

Bazı iyileştirmeler için Shmiddty'e kredi


4

İşleme, 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);}

Örnek ekran görüntüsü:

görüntü tanımını buraya girin

Bu kod akılda tutularak yapıldı, bu yüzden oldukça sıkıcı (top bazen raketin içinden geçiyor ya da etrafına sarılıyor). Kontroller, Oyuncu 1 için Q / A ve Oyuncu 2 için O / L'dir.


1
Bir oyun olarak, Pong versiyonunuz da oldukça adil görünüyor, çünkü kare başına sadece bir oyuncunun anahtarı kaydedilmiş: P
Jonathan Frech

2

1283 karakter

Bu biraz daha golf olabilir ama işte burada.

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

Düzenleme: Ücretsiz, Linux tarafından çalıştırılabilir bir dil için gereksinimi görmedim ...


2

Tcl / Tk , 932 bayt

Etkileşimli kabukta çalıştırılmalıdır

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 .

Not:

 #There is an Enter at the end

Topun sadece çapraz açılardan geçtiği ve her zaman aynı hıza sahip olduğu Pong'un sadece çok az bir sürümü.

görüntü tanımını buraya girin


Başarısız outgolf: bit.ly/2VSIGz8
sergiol 0
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.