ASCII Game of Pong

10

Ascii Pong

Tantangannya adalah membuat ulang game klasik "pong" dalam karakter ASCII dengan kode sesingkat mungkin.

Persyaratan / spesifikasi

  • "Layar" harus 45x25 karakter.
  • Ruang putih sebenarnya harus ruang putih.
  • Dayung harus 9 sama dengan tanda-tanda: =========dan harus di baris paling atas dan paling bawah (saya tahu aslinya dimainkan dari sisi ke sisi, bukan dari atas ke bawah, tapi saya pikir ini bekerja lebih baik untuk ascii pong ).
  • Bola bisa menjadi huruf kecil atau huruf besar oatau nol.
  • Dua tombol input apa pun (baik-baik saja jika pengguna menekan tombol yang membuat huruf muncul di input, itu juga baik-baik saja) untuk memindahkan dayung pemain ke kiri dan kanan satu atau dua karakter sekaligus.
  • Bola harus memantul pada sudut yang tepat saat memukul dayung atau dinding (petunjuk: meniadakan nilai perbedaan x atau y).
  • Skor harus ditampilkan di suatu tempat di output. Skornya adalah berapa kali pemain berhasil mengenai bola.
  • Jika bola melewati dayung pemain, hentikan programnya.
  • Harus ada beberapa jenis AI (bahkan jika dayung AI hanya cocok nilai x bola).
  • Bola tidak dapat melakukan perjalanan dalam garis lurus secara vertikal atau horizontal.

Layar mulai / bingkai pertama akan terlihat seperti ini:

                  =========                  











                      o                      











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

Skor Ini adalah , jadi kode terpendek menang ... namun, ada beberapa bonus untuk mengurangi jumlah karakter Anda:

  • -30 karakter: Ubah lintasan bola tergantung di mana bola itu mengenai dayungnya
  • -10 karakter: Buat game lebih cepat dari waktu ke waktu
  • -20 karakter: Membuat AI beatable
  • -20 karakter: Hindari situasi di mana pemain tetap diam dan permainan berlangsung selamanya tanpa menang atau kalah (disebabkan oleh lintasan tertentu dan pola AI)
  • -20 karakter: Buat bola mulai bergerak pada lintasan acak (semi-)
  • -25 karakter: Tambahkan opsi reset

Ini adalah contoh un-golfed tanpa bonus dalam JavaScript:

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

Biarkan game dimulai!

Eric Vincent
sumber
3
Oke, bisakah seseorang setidaknya menjelaskan mengapa mereka menurunkan ini? Saya benar-benar ingin tahu karena saya pikir ini akan menyenangkan tetapi saya tidak punya banyak pengalaman.
Eric Vincent
3
Mencetak hal-hal ASCII tidak apa-apa tetapi dengan interaksi keyboard kita harus membangun seluruh aplikasi. Jenis-jenis tantangan itu disukai karena banyak bahasa tidak mendukung saya / o seperti itu. Menerapkan AI, fisika. Hampir seperti aplikasi skala penuh. Jika Anda melihat tantangan lain, mereka memiliki satu tugas yang mengambil input (atau tidak) dan menghasilkan output yang relevan. Menambahkan AI, fisika, dan keyboard knteraction hanya cara untuk banyak tantangan
Downgoat
1
@vihan AI untuk pong sangat sederhana, hanya harus mengikuti nilai x bola. Bahkan membuatnya beatable tidak terlalu sulit, cukup batasi kecepatan dayungnya. Satu-satunya masalah nyata dengan konsep ini adalah interaksi keyboard, yang dapat dikelola dalam berbagai bahasa yang masuk akal. Namun briefnya agak kabur dan terbuka (mengingat bahwa kami adalah pengikat untuk ketidakjelasan dan keadilan di sekitar sini), dan sejumlah besar bonus tidak membantu itu.
Level River St
2
Interaksi keyboard harus diselesaikan dalam (Re) Menerapkan Tetris juga, tapi itu tidak mengurangi popularitas tugas. (Ya, saya tahu, itu sebenarnya kontes popularitas , ini bukan.) Satu-satunya hal yang menurut saya mengganggu, adalah jumlah bonus. Tapi tentu tidak harus sesuai dengan seleraku.
manatwork

Jawaban:

4

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

Solusi konsol dengan semua hal bonus.
Ini harus bekerja pada terminal apa pun yang memahami kode pelarian ANSI (\ e [...). Diuji pada cygwin.

Kontrol keyboard:
Kiri: 4
Kanan: 6
Reset: 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}
LukStorms
sumber
1
Hei Luk, cintai ini! Kupikir saya akan membagikan beberapa cara Anda mungkin dapat menghemat lebih banyak karakter ... Karena Anda menggunakan printlebih dari 4 kali, seharusnya lebih murah untuk membuat sub baru dan menyebutnya sub p{print@_}. Jika Anda tidak keberatan menggunakan tombol lain seperti yang Anda spesifik, Anda dapat menggantinya if(defined($k=ReadKey(-1))){L(-1)if's'eq$k;L(1)if'd'eq$k;I,if'r'eq$k}dengan L 114<=>ord$k if$k=ReadKey -1;. Ini hanya mengkonversi <r: -1, r: 0,> r: 1 yang mungkin bukan yang Anda cari. Jika Anda senang dengan ini, Anda bisa menggunakan [4] [5] [6] sebagai kunci dengan: L$k<=>5 if$k=ReadKey -1;.
Dom Hastings
1
Sepertinya Anda juga bisa mengganti beberapa blok jika dengan postfix ifmemeriksa atau mengganti dengan ternary untuk penghematan lebih banyak, tetapi itu mungkin terbukti rumit dengan bersarang ... Anda memiliki blok lain $d--if$d>6yang dapat Anda ubah ke $d-=$d>6untuk penghematan 2-byte yang mungkin bekerja di beberapa tempat lagi dan penghematan kecil lainnya ;$p=H.'='x9 .$"bukan $p="H========= ". Semoga beberapa di antaranya bermanfaat!
Dom Hastings
1
Terima kasih, senang Anda menyukainya. Kiat Anda membantu menurunkannya lebih lanjut dengan 50 byte! Trik dengan ord itu jahat. Trik $ d - = $ d> 6 terlihat sangat aneh. Saya juga menemukan bahwa ketika mencetak sesuatu seperti "$ aH" adalah masalah, bahwa "$ {a} H" berfungsi seperti itu akan di bash. :)
LukStorms
1
Ah ya! Beberapa cara yang menggunakan nama variabel non-alfabet ( $}atau sesuatu) atau menggunakan kata kunci ( $a.H), tidak yakin apakah itu akan membantu Anda dalam kasus ini atau tidak. Sesuatu Aku melihat, dalam sub P jika Anda hanya pernah memiliki satu argumen untuk itu, Anda bisa memiliki print"\e[@_"bukan .popkarena tidak akan ada pemisah lapangan untuk khawatir tentang. Juga, jika Anda menggunakan papan angka bukan huruf, Anda tidak perlu digunakan ord, karena $kakan 4atau 6sehingga Anda bisa melakukan 5<=>$ksebaliknya.
Dom Hastings
1
Terima kasih lagi. Tidak berpikir perl akan menerima variabel seperti itu O_o. Tapi itu berhasil dan beberapa byte diatasi dengan itu. Tapi jangan coba-coba menggunakan $! variabel. Hal-hal aneh terjadi kemudian.
LukStorms
1

JavaScript, 618 byte + HTML, 99 byte

Baiklah, inilah jawaban JavaScript yang saya mainkan meskipun tidak layak dalam bahasa lain:

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>

-20 dan -25 untuk bonus

Eric Vincent
sumber
Hm, ini tidak terlihat seperti golf bagi saya. Anda masih bisa menghilangkan nama variabel dua huruf, gantikan beberapa &&token& , menghilangkan banyak ;token, menyingkirkan spasi yang tidak perlu setelah {dan bahkan menyingkirkan beberapa karakter kutipan dalam HTML. Dan mungkin lebih banyak, bahkan. Ini hanya dugaan, tetapi Anda mungkin ingin mencoba menghindari UglifyJS dan memperkecil dengan tangan. :)
Chiru
6
Cukup samar diposting dengan cara ini. Pembaca harus mencari kode 663 karakter untuk penanganan kunci, kemudian mungkin STFW untuk mengetahui kunci mana yang memiliki kode 37 dan 39. (Lagi pula, tidak ada reaksi pada tombol panah kiri dan kanan dalam Firefox terbaru yang saya gunakan.) Jadi karena tidak dapat mengujinya, saya tidak akan pernah menemukan yang mana dari 3 bonus yang Anda dapatkan -20.
manatwork