ASCII Pong Oyunu


10

Ascii Pong

Zorluk klasik oyun "pong" ASCII karakterlerde mümkün olan en kısa kodda yeniden oluşturmaktır.

Gereksinimler / özellikler

  • "Ekran" 45x25 karakter olmalıdır.
  • Beyaz boşluk aslında beyaz boşluk olmalıdır.
  • Kürekler 9 işaretine eşit =========olmalıdır : ve en üstte ve en altta satırlarda olmalıdır (Orijinalin yukarıdan aşağıya yerine yan yana oynandığını biliyorum, ancak bunun ascii pong için daha iyi çalıştığını düşünüyorum ).
  • Top küçük veya büyük harf oveya sıfır olabilir.
  • Her türden iki giriş düğmesi (kullanıcı girişte bir harfi gösteren bir tuşa basarsa iyi olur, bu da iyidir) oyuncunun raketini bir kerede bir veya iki karakter sola ve sağa hareket ettirmek için.
  • Top, bir raket veya duvara çarptıktan sonra uygun açıyla sekmelidir (ipucu: x veya y fark değerini ortadan kaldırın).
  • Skor, çıktıda bir yerde gösterilmelidir. Skor, oyuncunun topa başarılı bir şekilde kaç kez vurduğudur.
  • Top oyuncunun raketini kaçırırsa, programı sonlandırın.
  • Olmamalıdır bazı (AI küreği sadece topun x değerle eşleşen bile) AI tür.
  • Top düz bir çizgide dikey veya yatay olarak hareket edemez.

Başlangıç ​​ekranı / ilk kare şöyle görünmelidir:

                  =========                  











                      o                      











                  =========                  
score: 0

Puanlama Bu , bu yüzden en kısa kod kazanır ... Ancak, karakter sayınızı azaltmak için bazı bonuslar vardır:

  • -30 karakter: Topun raketine vuracağı yere bağlı olarak yörüngesini değiştirme
  • -10 karakter: Oyunun zaman içinde hızlanmasını sağla
  • -20 karakter: AI'yı yenilebilir yapın
  • -20 karakter: Oyuncunun hareketsiz kaldığı ve oyunun kazanmadan veya kaybetmeden sonsuza kadar devam ettiği durumlardan kaçının (belirli yörüngeler ve AI desenlerinden kaynaklanır)
  • -20 karakter: Topun (yarı) rastgele bir yörüngede hareket etmesini sağlayın
  • -25 karakter: Sıfırlama seçeneği ekle

JavaScript'te ikramiye bulunmayan golf oynamayan bir örnek:

//init
var x = 22,
    y = 12,
    xd = Math.random() < 0.5 ? -1 : 1,
    yd = 1,
    player = opponent = 18,
    score = 0,

//interval that runs 10x per second (minus the runtimeof one cycle)
interval = setInterval(function() {
  //move ball
  x += xd;
  y += yd;

  //move opponent
  opponent = x - 4;

  //collision with walls
  if(x <= 0 || x >= 44) xd = -xd;

  //collision with paddles
  if(y == 1) {
    if(x >= opponent && x < opponent + 9) yd = -yd;
    else {
      //you win
      clearInterval(interval);
      document.body.innerHTML = "You win!<br>Your score was: " + score;
      return;
    }
  }
  else if(y == 23) {
    if(x >= player && x < player + 9) {
      yd = -yd;
      score++;
    }
    else {
      //you lose
      clearInterval(interval);
      document.body.innerHTML = "You lose!<br>Your score was: " + score;
      return;
    }
  }

  draw();
}, 100);

function draw() {
  var body = document.body;
  body.innerHTML = "";
  for(var i = 0; i < 25; i++) {
    for(var j = 0; j < 45; j++) {
      //white space is default
      var char = " ";
      
      //ball
      if(j == x && i == y) char = "o";
      
      //paddles
      if(i === 0) {
        if(j >= opponent && j < opponent + 9) char = "=";
      }
      else if(i == 24) {
        if(j >= player && j < player + 9) char = "=";
      }
      
      body.innerHTML += char;
    }
    body.innerHTML += "<br>";
  }
  body.innerHTML += "score: " + score;
}

//key press listener for left and right movement
window.onkeydown = function() {
  if (window.event.keyCode == 37) player -= 2;
  else if(window.event.keyCode == 39) player += 2;
};
<body style="font-family: monospace; white-space: pre">
  
</body>

Oyunlar başlasın!


3
Tamam, birileri en azından bunu neden aşağı indirdiklerini açıklayabilir mi? Gerçekten merak ediyorum çünkü bunun eğlenceli olacağını düşündüm ama fazla tecrübem yok.
Eric Vincent

3
ASCII malzemelerini yazdırmak iyidir, ancak klavye etkileşimi ile tüm bir uygulama oluşturmamız gerekir. Bu tür zorluklar ön plana çıkar, çünkü birçok dil bu şekilde desteklemeyi desteklemez. Bir yapay zeka, fizik uygulamak. Neredeyse tam ölçekli bir uygulama gibi. Diğer zorluklara bakarsanız, bir girdi alan (ya da almayan) ve ilgili çıktı üreten bir görevi vardır. Bir AI, fizik ve klavye knteraction eklemek bir meydan okuma için çok yol
Downgoat

1
@vihan pong için AI son derece basittir, sadece topun x değerini takip etmek zorundadır. Dövülebilir hale getirmek bile o kadar zor değil, sadece kürek hızını sınırlayın. Konseptle ilgili tek gerçek sorun, makul çeşitli dillerde yönetilebilen klavye etkileşimi. Ancak özet oldukça belirsiz ve açık (burada belirsizlik ve adalet için sopa olduğumuz göz önüne alındığında) ve çok çeşitli bonuslar buna yardımcı olmuyor.
Level River St


2
Klavye etkileşimi de Tetris'in (Re) Uygulanmasında çözülmek zorundaydı , ancak bu görevin popülerliğini azaltmadı. (Evet, biliyorum, bu aslında popülerlik yarışmasıydı , bu değil.) Kişisel olarak rahatsız edici bulduğum tek şey bonus miktarı. Ama kesinlikle benim zevkime bağlı olmak zorunda değil.
manatwork

Yanıtlar:


4

Perl, 760 611 592 535 515 (640-30-10-20-20-20-25)

Tüm bonus öğeleri içeren bir konsol çözümü.
ANSI çıkış kodlarını (\ e [...) anlayan herhangi bir terminalde çalışmalıdır. Cygwin üzerinde test edildi.

Klavye kontrolleri:
Sol: 4
Sağ: 6
Sıfırla: 8

use Term::ReadKey;ReadMode 4;END{ReadMode 0}$|++;$a=$d=45;$b=25;$h=1;$j=$l=17;$p='='x9;sub P{print"\e[@_"}sub L{$%=$l+pop;if($%>0&$%+7<$a){P"25H\e[K\e[25;$%H$p ";$l=$%}}sub U{$%=$j+pop;if($%>0&$%+7<$a){P"1H\e[K\e[1;$%H$p ";$j=$%}}sub I{$}=int rand 42;$g=8;$i=1;P"2J\ec";L}I;while(1){if($c>0){$c--}else{$c=98;$d-=$d>6}if($c%9==0){U -1if$}<$j+4;U 1if$}>$j+6};if($c%$d==0){$m=$}+$h;$n=$g+$i;$h*=-1if$m<1||$m>$a;if($n>24&$}>=$l&$}<$l+9){$i*=-1;$h=-1if$m<$l+5;$h=1if$m>$l+5;$s++}if($n<2&$}>=$j&$}<$j+9){$i*=-1}P"$g;1H\e[K";$}+=$h;$g+=$i;P"$g;$}HO"}if($k=ReadKey -1){I,if$k>6;L$k<=>5}P"26;0Hscore:$s";exit,if$g>=$b;select($\,$\,$\,0.01);I,if$g<2}

1
Hey Luk, bunu seviyorum! Daha fazla karakter kaydedebilmenin birkaç yolunu paylaşacağımı düşündüm ... print4 kereden fazla kullandığınız için, yeni bir alt oluşturmak ve bunu aramak daha ucuz olmalıdır sub p{print@_}. Diğer tuşlar o size özgü yanı sıra kullanılan sakıncası yoksa, sen yerini alabilir if(defined($k=ReadKey(-1))){L(-1)if's'eq$k;L(1)if'd'eq$k;I,if'r'eq$k}ile L 114<=>ord$k if$k=ReadKey -1;. Bu sadece <r: -1, r: 0,> r: 1'i dönüştürür ki bu peşinde olduğunuz şey olmayabilir. Bu memnunsanız şunu kullanabilirsiniz [4] [5] ile anahtarları olarak [6]: L$k<=>5 if$k=ReadKey -1;.
Dom Hastings

1
Ayrıca, birkaç düzeltme bloğunu bir postfix ifkontrolüyle değiştirebilir veya biraz daha fazla tasarruf için üçlü ile değiştirebilirsiniz, ancak bu, iç içe yerleştirmeyle ilgili zor olabilir ... 2 baytlık bir tasarruf için $d--if$d>6değiştirebileceğiniz başka bir bloğunuz $d-=$d>6var. birkaç yerde daha çalışabilir ve ;$p=H.'='x9 .$"bunun yerine başka bir küçük tasarruf olabilir $p="H========= ". Umarım bunlardan bazıları faydalıdır!
Dom Hastings

1
Teşekkürler, beğendiğine sevindim. İpuçlarınız 50 bayt ile daha da golf oynamak için yardımcı oldu! Ord ile olan hile kötü. $ D - = $ d> 6 numarası çok tuhaf görünüyordu. Ayrıca, "$ aH" gibi bir şey yazdırırken, "$ {a} H" nin bash'da olduğu gibi çalıştığını keşfettim. :)
LukStorms

1
Ah evet! Alfabetik olmayan değişken adları ( $}veya bir şey) veya barewords ( $a.H) kullanarak bunun birkaç yolu , bu durumda size yardımcı olup olmayacağından emin değilim. Fark ettiğim bir şey var, sub P eğer sadece bir argümanınız varsa, endişelenecek bir alan ayırıcısı olmadığından print"\e[@_"bunun yerine sahip olabilirsiniz .pop. Eğer harfler yerine numpad kullanıyorsanız Ayrıca, kullanılan gerekmez ordgibi $kolurdu 4ya 6Yapabileceğin böylece 5<=>$kyerine.
Dom Hastings

1
Tekrar teşekkürler. Perl'in O_o gibi değişkenleri kabul edeceğini düşünmemiştim. Ama işe yarıyor ve birkaç bayt bununla kurtarıldı. Ama $ kullanmayı denemeyin! değişken. O zaman tuhaf şeyler olur.
LukStorms

1

JavaScript, 618 bayt + HTML, 99 bayt

Peki, diğer dillerde uygulanabilir olmasa bile golf JavaScript'im yanıtı:

var x,y,xd,yd,p,o,s,n,i,j,c,k;function a(){x=22;y=12;xd=Math.random()<.5?-1:1;yd=1;p=o=18;s=0;n=setInterval(function(){x+=xd;y+=yd;o=x-4;if(x<=0||x>=44)xd=-xd;if(y==1){if(x>=o&&x<o+9)yd=-yd;else{clearInterval(n);b.innerHTML="You Win!<br>Score: "+s;return}}else if(y==23){if(x>=p&&x<p+9){yd=-yd;s++;}else{clearInterval(n);b.innerHTML="You Lose!<br>Score: "+s;return}}d();},100);}function d(){b.innerHTML="";for(i=0;i<25;i++){for(j=0;j<45;j++){c=" ";if(j==x&&i==y)c="o"; if(i==0&&j>=o&&j<o+9)c="=";if(i==24&&j>=p&&j<p+9)c="=";b.innerHTML+=c;} b.innerHTML+="<br>";}b.innerHTML+="score: "+s;}onkeydown=function(){ k=window.event.keyCode;if(k==37)p-=2;if(k==39)p+=2;};
<button onclick="a()">start</button><div id="b"style="font-family:monospace;white-space:pre"></div>

Bonuslar için -20 ve -25


Hm, bu bana çok golf gibi gelmiyor. Hala iki harfli değişken adlarından kurtulabilir, birkaç &&jetonu değiştirebilir &, bol miktarda ;jetonu ortadan kaldırabilir , sonrasında gereksiz alanlardan {kurtulabilir ve hatta HTML'deki bazı alıntı karakterlerden kurtulabilirsiniz. Ve muhtemelen çok daha fazlası. Bu sadece bir tahmindir, ancak UglifyJS'den kaçınmayı ve elle küçültmeyi deneyebilirsiniz. :)
Chiru

6
Oldukça cryptic bu şekilde gönderdi. Okuyucu, tuş işleme için 663 karakter kodunu aramalı, daha sonra hangi tuşların 37 ve 39 koduna sahip olduğunu bulmak için muhtemelen STFW'yi aramalıdır. Test edemediğimde -20 kazandığınız 3 bonusdan hangisini asla bulamayacağım.
manatwork
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.