ASCII Game of Pong

10

Ascii Pong

Le défi est de recréer le jeu classique "pong" en caractères ASCII dans le code le plus court possible.

Exigences / spécifications

  • L '"écran" doit contenir 45 x 25 caractères.
  • L'espace blanc doit en fait être un espace blanc.
  • Les palettes doivent avoir 9 signes égaux: =========et doivent être sur les rangées les plus hautes et les plus basses (je sais que l'original est joué côte à côte au lieu de haut en bas, mais je pense que cela fonctionne mieux pour ascii pong ).
  • La balle peut être un minuscule ou un majuscule oou un zéro.
  • Deux boutons de saisie de toute sorte (c'est bien si l'utilisateur appuie sur une touche qui fait apparaître une lettre dans l'entrée, c'est bien aussi) pour déplacer la palette du joueur à gauche et à droite un ou deux caractères à la fois.
  • La balle doit ricocher à l'angle approprié lorsqu'elle frappe une raquette ou un mur (indice: annuler la valeur de différence x ou y).
  • Le score doit être affiché quelque part dans la sortie. Le score est le nombre de fois où le joueur frappe le ballon avec succès.
  • Si le ballon manque la raquette du joueur, mettez fin au programme.
  • Il devrait y avoir une sorte d'IA (même si la palette de l'IA correspond juste à la valeur x de la balle).
  • Le ballon ne peut pas voyager en ligne droite verticalement ou horizontalement.

L'écran de démarrage / première image devrait ressembler à ceci:

                  =========                  











                      o                      











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

Score C'est , donc le code le plus court gagne ... cependant, il y a quelques bonus pour diminuer le nombre de vos personnages:

  • -30 personnages: changez la trajectoire de la balle en fonction de l'endroit où elle frappe sur la raquette
  • -10 personnages: accélérez le jeu au fil du temps
  • -20 caractères: rendez l'IA battable
  • -20 personnages: évitez toute situation où le joueur reste immobile et le jeu se poursuit indéfiniment sans gagner ni perdre (causé par certaines trajectoires et modèles d'IA)
  • -20 caractères: faire bouger la balle sur une trajectoire (semi-) aléatoire
  • -25 caractères: ajouter une option de réinitialisation

Voici un exemple sans golf sans bonus en 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>

Que les jeux commencent!

Eric Vincent
la source
3
D'accord, quelqu'un peut-il au moins expliquer pourquoi ils ont voté contre cela? Je suis vraiment curieux parce que je pensais que ce serait amusant mais je n'ai pas beaucoup d'expérience.
Eric Vincent
3
L'impression de trucs ASCII est acceptable mais avec une interaction avec le clavier, nous devrons créer une application entière. Ce type de défis est mal vu car de nombreuses langues ne prennent pas en charge les E / S comme ça. Mise en place d'une IA, physique. Presque comme une application à grande échelle. Si vous jetez un œil à d'autres défis, ils ont une tâche qui prend une entrée (ou non) et produit une sortie pertinente. Ajouter une IA, de la physique et une action de clavier est juste beaucoup trop pour un défi
Downgoat
1
@vihan l'IA pour pong est extrêmement simple, il suffit de suivre la valeur x de la balle. Même le rendre battable n'est pas si difficile, il suffit de limiter la vitesse de la pagaie. Le seul vrai problème avec le concept est l'interaction avec le clavier, qui peut être gérée dans une variété raisonnable de langues. Le mémoire est cependant plutôt vague et ouvert (étant donné que nous sommes tenaces à la non-ambiguïté et à l'équité ici), et la vaste gamme de bonus n'aide pas cela.
Level River St
1
pertinent: meta.codegolf.stackexchange.com/q/5521/15599
Level River St
2
L'interaction au clavier devait également être résolue dans (Re) la mise en œuvre de Tetris , mais cela n'a pas diminué la popularité de la tâche. (Oui, je sais, c'était en fait un concours de popularité , ce n'est pas le cas.) La seule chose que je trouve personnellement troublante, c'est le montant des bonus. Mais certainement pas à mon goût.
manatwork

Réponses:

4

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

Une solution console avec tous les bonus.
Il devrait fonctionner sur n'importe quel terminal qui comprend les codes d'échappement ANSI (\ e [...). Testé sur cygwin.

Commandes du clavier:
Gauche: 4
Droite: 6
Réinitialisation: 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
la source
1
Hé Luk, j'adore ça! Je pensais partager quelques façons dont vous pourriez être en mesure d'enregistrer quelques caractères supplémentaires ... Puisque vous utilisez printplus de 4 fois, il devrait être moins cher de configurer un nouveau sous-marin et d'appeler cela sub p{print@_}. Si cela ne vous dérange pas que d'autres clés soient utilisées ainsi que celles que vous spécifiez, vous pouvez les remplacer if(defined($k=ReadKey(-1))){L(-1)if's'eq$k;L(1)if'd'eq$k;I,if'r'eq$k}par L 114<=>ord$k if$k=ReadKey -1;. Cela convertit simplement <r: -1, r: 0,> r: 1, ce qui n'est peut-être pas ce que vous recherchez. Si vous êtes satisfait, vous pouvez utiliser [4] [5] [6] comme les touches avec: L$k<=>5 if$k=ReadKey -1;.
Dom Hastings
1
Il semble également que vous pouvez remplacer quelques blocs if par un ifcontrôle postfix ou remplacer par ternary pour quelques économies supplémentaires, mais cela pourrait s'avérer difficile avec l'imbrication ... Vous avez un autre bloc $d--if$d>6que vous pouvez changer $d-=$d>6pour une sauvegarde de 2 octets qui pourrait fonctionner dans quelques autres endroits aussi et une autre petite économie est ;$p=H.'='x9 .$"au lieu de $p="H========= ". J'espère que certains d'entre eux sont utiles!
Dom Hastings du
1
Merci, heureux que vous l'aimiez. Vos conseils ont aidé à approfondir la lecture avec 50 octets! Cette astuce avec l'ord est méchante. L'astuce $ d - = $ d> 6 avait l'air si bizarre. J'ai également découvert que lors de l'impression de quelque chose comme "$ aH" est un problème, que "$ {a} H" fonctionne comme il le ferait dans bash. :)
LukStorms
1
Ah ouais! Quelques façons de contourner cela en utilisant des noms de variables non alphabétiques ( $}ou quelque chose) ou en utilisant des mots nus ( $a.H), je ne sais pas si cela vous aidera dans ce cas ou non. Quelque chose que j'ai remarqué, c'est que sub P si vous n'avez qu'un seul argument, vous pourriez en avoir print"\e[@_"au lieu de .popcar il n'y aura pas de séparateur de champ à craindre. De plus, si vous utilisez le pavé numérique au lieu de lettres, vous n'avez pas besoin de l'utiliser ord, comme vous le $kferiez 4ou 6vous pourriez le faire à la 5<=>$kplace.
Dom Hastings
1
Merci encore. Je ne pensais pas que perl accepterait des variables comme ça O_o. Mais cela fonctionne et quelques octets ont été récupérés par cela. Mais n'essayez pas d'utiliser un $! variable. Des choses étranges se produisent alors.
LukStorms
1

JavaScript, 618 octets + HTML, 99 octets

Eh bien voici ma réponse JavaScript golfée même si elle n'est pas possible dans d'autres langues:

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 et -25 pour les bonus

Eric Vincent
la source
Hm, ça ne me semble pas très golfé. Vous pouvez toujours vous débarrasser des noms de variable à deux lettres, substituer quelques &&jetons &, éliminer beaucoup de ;jetons, vous débarrasser des espaces inutiles après {et même vous débarrasser de certains caractères de citation dans le HTML. Et probablement beaucoup plus, même. Ce n'est qu'une supposition, mais vous voudrez peut-être éviter UglifyJS et réduire à la main. :)
Chiru
6
Assez cryptique publié de cette façon. Le lecteur doit rechercher le code de 663 caractères pour la gestion des clés, puis éventuellement STFW pour savoir quelles clés ont les codes 37 et 39. (Quoi qu'il en soit, il n'y a aucune réaction sur les touches fléchées gauche et droite dans le dernier Firefox que j'utilise.) Donc ne pouvant pas le tester je ne saurai jamais pour lequel des 3 bonus disponibles vous avez gagné le -20.
manatwork