ASCII Pong-Spiel

10

Ascii Pong

Die Herausforderung besteht darin, das klassische Spiel "Pong" in ASCII-Zeichen in kürzestem Code nachzubilden.

Anforderungen / Spezifikationen

  • Der "Bildschirm" sollte 45x25 Zeichen groß sein.
  • Leerraum sollte eigentlich Leerraum sein.
  • Die Paddel sollten 9 Gleichheitszeichen haben: =========und sollten sich in der obersten und untersten Reihe befinden (ich weiß, dass das Original von Seite zu Seite statt von oben nach unten gespielt wird, aber ich denke, dass dies für ASCII Pong besser funktioniert ).
  • Der Ball kann ein Klein- oder Großbuchstabe ooder eine Null sein.
  • Zwei Eingabetasten jeglicher Art (es ist in Ordnung, wenn der Benutzer eine Taste drückt, mit der ein Buchstabe in der Eingabe angezeigt wird, das ist auch in Ordnung), um das Paddel des Spielers jeweils um ein oder zwei Zeichen nach links und rechts zu bewegen.
  • Der Ball muss beim Auftreffen auf ein Paddel oder eine Wand im richtigen Winkel abprallen (Hinweis: Negieren Sie den x- oder y-Differenzwert).
  • Die Partitur sollte irgendwo in der Ausgabe angezeigt werden. Die Punktzahl gibt an, wie oft der Spieler den Ball erfolgreich schlägt.
  • Wenn der Ball das Paddel des Spielers verfehlt, beenden Sie das Programm.
  • Es sollte einige Art von AI (auch wenn die Paddel der KI nur der x - Wert des Balls übereinstimmt).
  • Der Ball kann sich weder vertikal noch horizontal in einer geraden Linie bewegen.

Der Startbildschirm / das erste Bild sollte ungefähr so ​​aussehen:

                  =========                  











                      o                      











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

Wertung Dies ist , also gewinnt der kürzeste Code ... es gibt jedoch einige Boni, um die Anzahl Ihrer Charaktere zu verringern:

  • -30 Zeichen: Ändert die Flugbahn des Balls je nachdem, wo er auf das Paddel trifft
  • -10 Zeichen: Beschleunigen Sie das Spiel im Laufe der Zeit
  • -20 Zeichen: Mach die KI schlagbar
  • -20 Zeichen: Vermeiden Sie Situationen, in denen der Spieler still bleibt und das Spiel für immer weitergeht, ohne zu gewinnen oder zu verlieren (verursacht durch bestimmte Flugbahnen und KI-Muster).
  • -20 Zeichen: Lassen Sie den Ball sich auf einer (halb-) zufälligen Flugbahn bewegen
  • -25 Zeichen: Fügen Sie eine Rücksetzoption hinzu

Hier ist ein Beispiel ohne Golf ohne Boni in 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>

Lasst die Spiele beginnen!

Eric Vincent
quelle
3
Okay, kann jemand wenigstens erklären, warum er das abgelehnt hat? Ich bin wirklich neugierig, weil ich dachte, das würde Spaß machen, aber ich habe nicht viel Erfahrung.
Eric Vincent
3
Das Ausdrucken von ASCII-Inhalten ist in Ordnung, aber bei Tastaturinteraktion müssten wir eine ganze App erstellen. Diese Art von Herausforderungen wird verpönt, weil viele Sprachen solche E / A nicht unterstützen. Implementierung einer KI, Physik. Fast wie eine vollständige Anwendung. Wenn Sie sich andere Herausforderungen ansehen, haben sie eine Aufgabe, die eine Eingabe übernimmt (oder nicht) und eine relevante Ausgabe erzeugt. Das Hinzufügen einer KI-, Physik- und Tastatur-Interaktion ist für eine Herausforderung einfach zu viel
Downgoat
1
@vihan die KI für Pong ist extrem einfach, sie muss nur dem x-Wert des Balls folgen. Selbst wenn es schlagbar ist, ist es nicht so schwer. Begrenzen Sie einfach die Geschwindigkeit des Paddels. Das einzige wirkliche Problem mit dem Konzept ist die Tastaturinteraktion, die in einer angemessenen Vielfalt von Sprachen verwaltet werden kann. Der Auftrag ist jedoch ziemlich vage und offen (da wir hier für Eindeutigkeit und Fairness eintreten), und die große Auswahl an Boni hilft dem nicht.
Level River St
2
Die Tastaturinteraktion musste auch bei der (Neu-) Implementierung von Tetris gelöst werden , was jedoch die Popularität der Aufgabe nicht beeinträchtigte. (Ja, ich weiß, das war eigentlich ein Beliebtheitswettbewerb , das ist es nicht.) Das einzige, was ich persönlich störend finde, ist die Höhe der Boni. Muss aber sicher nicht meinem Geschmack entsprechen.
Manatwork

Antworten:

4

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

Eine Konsolenlösung mit all dem Bonusmaterial.
Es sollte auf jedem Terminal funktionieren, das die ANSI-Escape-Codes versteht (\ e [...). Auf Cygwin getestet.

Tastatursteuerung:
Links: 4
Rechts: 6
Zurücksetzen: 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
quelle
1
Hey Luk, ich liebe das! Ich dachte, ich würde ein paar Möglichkeiten nennen, wie Sie möglicherweise mehr Zeichen sparen können ... Da Sie printmehr als vier Mal verwenden, sollte es billiger sein, ein neues Sub einzurichten und das aufzurufen sub p{print@_}. Wenn Sie keine anderen Tasten etwas dagegen , sowie diejenigen , die Sie spezifisch verwendet werden, können Sie ersetzen if(defined($k=ReadKey(-1))){L(-1)if's'eq$k;L(1)if'd'eq$k;I,if'r'eq$k}mit L 114<=>ord$k if$k=ReadKey -1;. Dies konvertiert nur <r: -1, r: 0,> r: 1, was möglicherweise nicht das ist, wonach Sie suchen. Wenn Sie damit zufrieden sind, können Sie [4] [5] [6] als Schlüssel verwenden mit : L$k<=>5 if$k=ReadKey -1;.
Dom Hastings
1
Sieht auch so aus, als könnten Sie einige if-Blöcke durch eine Postfix- ifPrüfung ersetzen oder durch ternäre ersetzen, um weitere Einsparungen zu erzielen. Dies könnte sich jedoch bei der Verschachtelung als schwierig erweisen. Sie haben einen anderen Block, $d--if$d>6den Sie $d-=$d>6für eine 2-Byte-Speicherung ändern können könnte auch an ein paar weiteren Stellen funktionieren und eine weitere kleine Ersparnis ist ;$p=H.'='x9 .$"statt $p="H========= ". Hoffe, einige davon sind nützlich!
Dom Hastings
1
Danke, froh, dass es dir gefällt. Ihre Tipps haben dazu beigetragen, dass es mit 50 Bytes noch weiter nach unten geht! Dieser Trick mit dem Befehl ist böse. Der Trick $ d - = $ d> 6 sah so komisch aus. Ich habe auch festgestellt, dass beim Drucken von "$ aH" ein Problem vorliegt und "$ {a} H" wie in Bash funktioniert. :)
LukStorms
1
Oh ja! Ein paar Möglichkeiten, um dies zu $}umgehen , indem Sie nicht-alphabetische Variablennamen ( oder etwas anderes) oder Barewords ( $a.H) verwenden. Sie sind sich nicht sicher, ob dies in diesem Fall hilfreich ist oder nicht. Etwas, das mir aufgefallen ist, ist, sub P wenn Sie immer nur ein Argument dafür haben, das Sie print"\e[@_"stattdessen haben könnten, .popda es kein Feldtrennzeichen gibt, über das Sie sich Sorgen machen müssen. Auch, wenn Sie die numpad anstelle von Buchstaben verwenden, müssen Sie nicht verwenden müssen ord, als $kwären 4oder 6so Sie tun können , 5<=>$kstatt.
Dom Hastings
1
Danke noch einmal. Ich hätte nicht gedacht, dass Perl solche Variablen akzeptieren würde O_o. Aber es funktioniert und ein paar Bytes wurden dadurch neu abgerufen. Aber versuchen Sie nicht, ein $ zu verwenden! Variable. Dann passiert seltsames Zeug.
LukStorms
1

JavaScript, 618 Bytes + HTML, 99 Bytes

Nun, hier ist meine Antwort auf Golf-JavaScript, auch wenn dies in anderen Sprachen nicht möglich ist:

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 und -25 für Boni

Eric Vincent
quelle
Hm, das sieht für mich nicht sehr gut aus. Sie könnten immer noch aus zwei Buchstaben bestehende Variablennamen entfernen, ein paar &&Token ersetzen &, viele ;Token entfernen, unnötige Leerzeichen danach entfernen {und sogar einige Anführungszeichen im HTML-Code entfernen. Und wahrscheinlich sogar noch viel mehr. Dies ist nur eine Vermutung, aber Sie sollten versuchen, UglifyJS zu vermeiden und von Hand zu minimieren. :)
Chiru
6
Ganz kryptisch auf diese Weise gepostet. Der Leser muss den 663-Zeichen-Code nach der Schlüsselbehandlung durchsuchen, dann möglicherweise STFW, um herauszufinden, welche Schlüssel die Codes 37 und 39 haben. (Auf jeden Fall gibt es in dem neuesten Firefox, den ich verwende, keine Reaktion auf die linke und rechte Pfeiltaste.) Also Wenn ich es nicht testen kann, werde ich nie herausfinden, für welchen der 3 verfügbaren Boni Sie die -20 verdient haben.
Manatwork