ASCII Game of Pong

10

Ascii Pong

Wyzwanie polega na odtworzeniu klasycznej gry „pong” w postaci ASCII w możliwie najkrótszym kodzie.

Wymagania / specyfikacje

  • „Ekran” powinien mieć 45 x 25 znaków.
  • Biała przestrzeń powinna być właściwie białą przestrzenią.
  • Łopatki powinny mieć 9 znaków równości: =========i powinny znajdować się na najwyższych i najniższych rzędach (wiem, że oryginał jest odtwarzany bokiem do boku zamiast od góry do dołu, ale myślę, że działa to lepiej w przypadku ascii ponga ).
  • Piłka może być małą olub dużą literą lub zerową.
  • Dwa przyciski wprowadzania dowolnego rodzaju (jest w porządku, jeśli użytkownik naciśnie klawisz powodujący wyświetlenie litery na wejściu, to też jest w porządku), aby przesunąć wiosło gracza w lewo lub w prawo o jeden lub dwa znaki na raz.
  • Po uderzeniu w wiosło lub ścianę piłka musi rykoszetować pod odpowiednim kątem (wskazówka: zaneguj wartość różnicy x lub y).
  • Wynik powinien być wyświetlony gdzieś na wyjściu. Wynik pokazuje, ile razy gracz z powodzeniem uderza piłkę.
  • Jeśli piłka nie trafi w wiosło gracza, zakończ program.
  • Powinno być jakieś AI (nawet jeśli wiosło AI po prostu odpowiada wartości x piłki).
  • Piłka nie może poruszać się w linii prostej w pionie lub w poziomie.

Ekran startowy / pierwsza klatka powinny wyglądać mniej więcej tak:

                  =========                  











                      o                      











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

Punktacja Jest to , więc wygrywa najkrótszy kod ... jednak istnieją pewne bonusy, które zmniejszają liczbę twoich postaci:

  • -30 znaków: Zmień trajektorię piłki w zależności od tego, gdzie trafi w wiosło
  • -10 znaków: Z czasem gra przyspiesza
  • -20 znaków: Spraw, aby AI było do pokonania
  • -20 postaci: Unikaj sytuacji, w których gracz pozostaje nieruchomy, a gra toczy się wiecznie, nie wygrywając ani nie przegrywając (spowodowane pewnymi trajektoriami i wzorami sztucznej inteligencji)
  • -20 znaków: Spraw, aby piłka zaczęła się poruszać na (pół-) losowej trajektorii
  • -25 znaków: Dodaj opcję resetowania

Oto przykład bez gry w golfa bez bonusów w 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>

Niech rozpocznie się gra!

Eric Vincent
źródło
3
Okej, ktoś może przynajmniej wyjaśnić, dlaczego to ocenił? Jestem naprawdę ciekawa, bo myślałam, że to będzie fajna zabawa, ale nie mam dużego doświadczenia.
Eric Vincent
3
Drukowanie elementów ASCII jest w porządku, ale przy interakcji z klawiaturą musielibyśmy zbudować całą aplikację. Tego rodzaju wyzwania są odrzucane, ponieważ wiele języków nie obsługuje takich operacji we / wy. Implementacja sztucznej inteligencji, fizyki. Prawie jak aplikacja na pełną skalę. Jeśli spojrzysz na inne wyzwania, mają one jedno zadanie, które wymaga wkładu (lub nie) i daje odpowiedni wynik. Dodanie sztucznej inteligencji, fizyki i interakcji z klawiaturą to po prostu droga do wyzwania
Downgoat
1
@vihan AI dla ponga jest niezwykle proste, wystarczy podążać za wartością x piłki. Nawet sprawienie, by był on trudny do pokonania, nie jest takie trudne, po prostu ogranicz prędkość wiosła. Jedynym prawdziwym problemem związanym z tą koncepcją jest interakcja klawiatury, którą można zarządzać w rozsądnej różnorodności języków. Krótki opis jest jednak dość niejasny i otwarty (biorąc pod uwagę, że jesteśmy tutaj zwolennikami jednoznaczności i uczciwości), a szeroki wachlarz bonusów na to nie pomaga.
Level River St
2
Interakcja z klawiaturą również musiała zostać rozwiązana w (Re) Implementing Tetris , ale to nie zmniejszyło popularności zadania. (Tak, wiem, to był konkurs popularności , to nie jest.) Jedyne, co osobiście niepokoi, to ilość bonusów. Ale na pewno nie musi to zależeć od mojego gustu.
manatwork

Odpowiedzi:

4

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

Rozwiązanie konsolowe ze wszystkimi dodatkami.
Powinien działać na każdym terminalu, który rozumie kody specjalne ANSI (\ e [...). Testowane na cygwinie.

Sterowanie za pomocą klawiatury: w
lewo: 4 w
prawo: 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
źródło
1
Hej Luk, kocham to! Pomyślałem, że podzielę się kilkoma sposobami na zaoszczędzenie kilku znaków ... Ponieważ używasz printwięcej niż 4 razy, skonfigurowanie nowego subwoofera i wywołanie tego powinno być tańsze sub p{print@_}. Jeśli nie przeszkadza inne klawisze wykorzystywane, jak również te, które konkretne, można wymienić if(defined($k=ReadKey(-1))){L(-1)if's'eq$k;L(1)if'd'eq$k;I,if'r'eq$k}z L 114<=>ord$k if$k=ReadKey -1;. To po prostu konwertuje <r: -1, r: 0,> r: 1, co może nie być tym, czego szukasz. Jeśli jesteś zadowolony z tego, można użyć [4] [5] [6] jako klucze z: L$k<=>5 if$k=ReadKey -1;.
Dom Hastings
1
Wygląda również na to, że możesz zastąpić kilka bloków if ifsprawdzeniem postfiksów lub zamienić na trójskładnik, aby uzyskać więcej oszczędności, ale może to okazać się trudne przy zagnieżdżaniu ... Masz inny blok, na $d--if$d>6który możesz zmienić $d-=$d>62-bajtowe zapisywanie, które może działać również w kilku innych miejscach, a ;$p=H.'='x9 .$"zamiast tego jest kolejna mała oszczędność $p="H========= ". Mam nadzieję, że niektóre z nich są przydatne!
Dom Hastings
1
Dzięki, cieszę się, że ci się podoba. Twoje wskazówki pomogły w dalszym golfie z 50 bajtami! Ta sztuczka z ord jest nikczemna. Sztuczka $ d - = $ d> 6 wyglądała tak dziwnie. Odkryłem również, że podczas drukowania czegoś takiego jak „$ aH” stanowi problem, że „$ {a} H” działa tak, jak w przypadku bash. :)
LukStorms
1
O tak! Kilka sposobów obejścia tego za pomocą niealfabetycznych nazw zmiennych ( $}lub czegoś takiego) lub za pomocą słów kluczowych ( $a.H), nie jestem pewien, czy to pomoże ci w tym przypadku, czy nie. Zauważyłem coś, sub P jeśli kiedykolwiek miałeś tylko jeden argument, możesz print"\e[@_"zamiast tego, .popponieważ nie będzie się martwić separatorem pól. Ponadto, jeśli używasz NUM zamiast liter, nie trzeba do użytku ord, jak $kbędzie 4albo 6tak można robić 5<=>$kzamiast tego.
Dom Hastings,
1
Dzięki jeszcze raz. Nie sądziłem, że perl zaakceptuje zmienne takie jak O_o. Ale działa, a kilka bajtów zostało przez to odzyskanych. Ale nie próbuj używać $! zmienna. Dziwne rzeczy się wtedy zdarzają.
LukStorms
1

JavaScript, 618 bajtów + HTML, 99 bajtów

Oto moja odpowiedź JavaScript na golfa, nawet jeśli nie jest to możliwe w innych językach:

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 i -25 za bonusy

Eric Vincent
źródło
Hm, nie wygląda mi to na golfa. Nadal możesz pozbyć się dwuliterowych nazw zmiennych, zastąpić kilka &&tokenów &, wyeliminować wiele ;tokenów, pozbyć się niepotrzebnych spacji, {a nawet pozbyć się niektórych znaków cudzysłowu w HTML. I prawdopodobnie nawet o wiele więcej. To tylko przypuszczenie, ale możesz spróbować uniknąć UglifyJS i ręcznie zminimalizować. :)
Chiru,
6
Całkiem tajemniczy wysłany w ten sposób. Czytelnik musi przeszukać kod 663 znaków w celu obsługi klawiszy, a następnie być może STFW, aby dowiedzieć się, które klucze mają kod 37 i 39. (W każdym razie nie ma reakcji na lewy i prawy klawisz strzałki w najnowszym Firefoksie, którego używam.) nie mogąc tego przetestować, nigdy nie dowiem się, dla którego z 3 dostępnych bonusów zdobyłeś -20.
manatwork