ASCII Game of Pong


10

Ascii Pong

La sfida è ricreare il classico gioco "pong" in caratteri ASCII nel codice più breve possibile.

Requisiti / specifiche

  • Lo "schermo" dovrebbe contenere 45x25 caratteri.
  • Lo spazio bianco dovrebbe in realtà essere spazio bianco.
  • I paddle dovrebbero essere 9 uguali: =========e dovrebbero essere nella riga più in alto e più in basso (so che l'originale viene riprodotto fianco a fianco invece che dall'alto verso il basso, ma penso che questo funzioni meglio per ascii pong ).
  • La palla può essere minuscola o maiuscola oo zero.
  • Due pulsanti di input di qualsiasi tipo (va bene se l'utente preme un tasto che fa apparire una lettera nell'input, va bene lo stesso) per spostare la paletta del giocatore a destra e sinistra di uno o due caratteri alla volta.
  • La palla deve rimbalzare all'angolazione appropriata dopo aver colpito una paletta o un muro (suggerimento: annulla il valore della differenza x o y).
  • Il punteggio deve essere visualizzato da qualche parte nell'output. Il punteggio è quante volte il giocatore colpisce con successo la palla.
  • Se la palla manca la paletta del giocatore, termina il programma.
  • Dovrebbe esserci una sorta di AI (anche se la paletta dell'IA corrisponde solo al valore x della palla).
  • La palla non può viaggiare in linea retta in verticale o in orizzontale.

La schermata iniziale / il primo fotogramma dovrebbe essere simile al seguente:

                  =========                  











                      o                      











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

Punteggio Questo è , quindi vince il codice più corto ... tuttavia, ci sono alcuni bonus per ridurre il conteggio dei personaggi:

  • -30 caratteri: cambia la traiettoria della palla a seconda di dove colpisce sulla paletta
  • -10 personaggi: velocizza il gioco nel tempo
  • -20 caratteri: rende l'IA battibile
  • -20 personaggi: evita qualsiasi situazione in cui il giocatore rimane fermo e il gioco continua per sempre senza vincere o perdere (causato da certe traiettorie e schemi di intelligenza artificiale)
  • -20 personaggi: fai in modo che la palla inizi a muoversi su una traiettoria (semi) casuale
  • -25 caratteri: aggiungi un'opzione di ripristino

Ecco un esempio senza golf senza bonus 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>

Che i giochi inizino!


3
Va bene qualcuno può almeno spiegare perché hanno votato in negativo? Sono sinceramente curioso perché pensavo che sarebbe stato divertente ma non ho molta esperienza.
Eric Vincent,

3
Stampare cose ASCII va bene, ma con l'interazione con la tastiera dovremmo costruire un'intera app. Questo tipo di sfide sono disapprovate perché molte lingue non supportano l'I / O in quel modo. Implementazione di un'intelligenza artificiale, fisica. Quasi come un'applicazione in scala reale. Se dai un'occhiata ad altre sfide, hanno un compito che accetta (o no) un input e produce un output rilevante. L'aggiunta di un'intelligenza artificiale, fisica e tastiera è solo un modo per una sfida
Downgoat

1
@vihan l'IA per il pong è estremamente semplice, deve solo seguire il valore x della palla. Anche renderlo battibile non è poi così difficile, basta limitare la velocità della paletta. L'unico vero problema con il concetto è l'interazione con la tastiera, che può essere gestita in una ragionevole varietà di lingue. Il brief è tuttavia piuttosto vago e aperto (dato che qui siamo pignoli per l'ambiguità e l'equità), e la vasta gamma di bonus non aiuta.
Level River St


2
L'interazione con la tastiera ha dovuto essere risolta anche in (Ri) Implementare Tetris , ma ciò non ha diminuito la popolarità dell'attività . (Sì, lo so, quello era in realtà un concorso di popolarità , non lo è.) L'unica cosa che personalmente trovo inquietante è la quantità di bonus. Ma certamente non deve essere all'altezza dei miei gusti.
arte

Risposte:


4

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

Una soluzione console con tutte le cose bonus.
Dovrebbe funzionare su qualsiasi terminale che comprenda i codici di escape ANSI (\ e [...). Testato su Cygwin.

Controlli da tastiera:
Sinistra: 4
Destra: 6
Ripristino: 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
Ehi Luk, adoro questo! Pensavo di condividere alcuni modi in cui potresti essere in grado di salvare alcuni altri caratteri ... Dato che stai usando printpiù di 4 volte, dovrebbe essere più economico impostare un nuovo sub e chiamarlo sub p{print@_}. Se non ti dispiace altri tasti utilizzati così come quelli che si specifica, è possibile sostituire if(defined($k=ReadKey(-1))){L(-1)if's'eq$k;L(1)if'd'eq$k;I,if'r'eq$k}con L 114<=>ord$k if$k=ReadKey -1;. Questo converte solo <r: -1, r: 0,> r: 1 che potrebbe non essere quello che stai cercando. Se si è soddisfatti con questo, è possibile utilizzare [4] [5] [6], come i tasti con: L$k<=>5 if$k=ReadKey -1;.
Dom Hastings,

1
Sembra anche che puoi sostituire alcuni blocchi if con un ifcontrollo postfix o sostituire con ternary per ulteriori risparmi, ma ciò potrebbe rivelarsi complicato con l'annidamento ... Hai un altro blocco $d--if$d>6che puoi modificare $d-=$d>6per un salvataggio a 2 byte che potrebbe funzionare in un paio di posti troppo e un altro piccolo risparmio è ;$p=H.'='x9 .$"invece di $p="H========= ". Spero che alcuni di questi siano utili!
Dom Hastings,

1
Grazie, felice che ti piaccia. I tuoi consigli hanno contribuito a risolverlo ulteriormente con 50 byte! Quel trucco con l'ord è malvagio. Il trucco $ d - = $ d> 6 sembrava così strano. Ho anche scoperto che quando si stampa qualcosa come "$ aH" è un problema, che "$ {a} H" funziona come farebbe con bash. :)
LukStorms

1
Ah sì! Un paio di modi per aggirare l'uso di nomi di variabili non alfabetici ( $}o qualcosa del genere) o l'uso di parole $a.Hnon consentite ( ), non sono sicuro se ciò ti aiuterà in questo caso o meno. Qualcosa che ho notato è che sub P se avessi solo un argomento a riguardo, potresti avere print"\e[@_"invece di .popnon esserci un separatore di campo di cui preoccuparti. Inoltre, se si utilizza il tastierino numerico anziché le lettere, non è necessario utilizzarlo ord, come $ksarebbe 4o 6come si potrebbe fare 5<=>$kinvece.
Dom Hastings,

1
Grazie ancora. Non pensavo che il perl avrebbe accettato variabili come quella O_o. Ma funziona e pochi byte sono stati recuperati da quello. Ma non provare a usare un $! variabile. Succedono cose strane allora.
LukStorms

1

JavaScript, 618 byte + HTML, 99 byte

Bene, ecco la mia risposta JavaScript golfata anche se non è fattibile in altre lingue:

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 e -25 per i bonus


Hm, questo non mi sembra molto soddisfatto. Potresti comunque eliminare i nomi delle variabili di due lettere, sostituire alcuni &&token &, eliminare un sacco di ;token, eliminare gli spazi non necessari dopo {e persino eliminare alcuni caratteri di citazione nell'HTML. E probabilmente molto di più, anche. Questa è solo una supposizione, ma potresti voler provare a evitare UglifyJS e minimizzare a mano. :)
Chiru,

6
Abbastanza criptico pubblicato in questo modo. Il lettore deve cercare il codice di 663 caratteri per la gestione dei tasti, quindi eventualmente STFW per scoprire quali tasti hanno i codici 37 e 39. (Comunque, non c'è alcuna reazione sul tasto freccia sinistra e destra nell'ultimo Firefox che uso.) Quindi non potendo provarlo non scoprirò mai per quale dei 3 bonus disponibili hai guadagnato il -20.
arte
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.