Jogo de Pong ASCII

10

Ascii Pong

O desafio é recriar o clássico jogo "pong" em caracteres ASCII no menor código possível.

Requisitos / especificações

  • A "tela" deve ter 45 x 25 caracteres.
  • Espaço em branco deve realmente ser espaço em branco.
  • As pás devem ter 9 sinais de igual: =========e devem estar nas linhas superior e inferior (eu sei que o original é tocado de um lado para o outro em vez de de cima para baixo, mas acho que isso funciona melhor para ascii pong )
  • A bola pode ser minúscula ou maiúscula oou zero.
  • Dois botões de entrada de qualquer tipo (é bom se o usuário pressionar uma tecla que faz com que uma letra apareça na entrada, também é bom) para mover a raquete do jogador para a esquerda e para a direita, um ou dois caracteres de cada vez.
  • A bola precisa ricochetear no ângulo apropriado ao bater em uma raquete ou em uma parede (dica: negue o valor da diferença x ou y).
  • A pontuação deve ser exibida em algum lugar na saída. A pontuação é quantas vezes o jogador bate com sucesso na bola.
  • Se a bola falhar na raquete do jogador, encerre o programa.
  • Deve haver algum tipo de IA (mesmo que a raquete da IA ​​corresponda ao valor x da bola).
  • A bola não pode viajar em linha reta vertical ou horizontalmente.

A tela inicial / primeiro quadro deve se parecer com isso:

                  =========                  











                      o                      











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

Pontuação Este é o , então o código mais curto vence ... no entanto, existem alguns bônus para diminuir sua contagem de caracteres:

  • -30 caracteres: Mude a trajetória da bola dependendo de onde ela bate na raquete
  • -10 caracteres: faça o jogo acelerar com o tempo
  • -20 caracteres: torne a IA imbatível
  • -20 caracteres: evite qualquer situação em que o jogador fique parado e o jogo continue para sempre sem vencer ou perder (causado por certas trajetórias e padrões de IA)
  • -20 caracteres: faça a bola começar a se mover em uma trajetória (semi-) aleatória
  • -25 caracteres: adicione uma opção de redefinição

Aqui está um exemplo sem golfe, sem bônus em 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 os jogos comecem!

Eric Vincent
fonte
3
Ok, alguém pode pelo menos explicar por que votou contra isso? Estou genuinamente curioso porque achei que seria divertido, mas não tenho muita experiência.
Eric Vincent
3
Imprimir coisas ASCII é bom, mas com a interação do teclado, teríamos que criar um aplicativo inteiro. Esse tipo de desafio é desaprovado, porque muitos idiomas não suportam E / S assim. Implementando uma IA, física. Quase como um aplicativo em grande escala. Se você der uma olhada em outros desafios, eles têm uma tarefa que recebe uma entrada (ou não) e produz uma saída relevante. Adicionando um AI, física e knteraction teclado é apenas maneira muito para um desafio
Downgoat
11
@vihan a IA do pong é extremamente simples, basta seguir o valor x da bola. Mesmo torná-lo superável não é tão difícil, basta limitar a velocidade da raquete. O único problema real com o conceito é a interação do teclado, que pode ser gerenciada em uma variedade razoável de idiomas. O resumo é, no entanto, bastante vago e aberto (dado que somos defensores da ambiguidade e justiça por aqui), e a vasta gama de bônus não ajuda nisso.
Level River St
11
relevante: meta.codegolf.stackexchange.com/q/5521/15599
Level River St
2
A interação do teclado também teve que ser resolvida no (Re) Implementing Tetris , mas isso não diminuiu a popularidade da tarefa. (Sim, eu sei, isso foi realmente um concurso de popularidade , não é.) A única coisa que pessoalmente acho perturbadora é a quantidade de bônus. Mas certamente não precisa ser do meu gosto.
manatwork

Respostas:

4

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

Uma solução de console com todo o material bônus.
Ele deve funcionar em qualquer terminal que compreenda os códigos de escape ANSI (\ e [...). Testado em cygwin.

Controles do teclado:
Esquerda: 4
Direita: 6
Reinicialização: 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
fonte
11
Ei Luk, amando isso! Pensei em compartilhar algumas maneiras pelas quais você poderá economizar mais caracteres ... Como você está usando printmais de quatro vezes, deve ser mais barato configurar um novo sub e chamar isso sub p{print@_}. Se você não se importa de usar outras chaves, bem como aquelas específicas, pode substituí-las if(defined($k=ReadKey(-1))){L(-1)if's'eq$k;L(1)if'd'eq$k;I,if'r'eq$k}por L 114<=>ord$k if$k=ReadKey -1;. Isso apenas converte <r: -1, r: 0,> r: 1, o que pode não ser o que você procura. Se você está feliz com isso, você pode usar [4] [5] [6] como as teclas com: L$k<=>5 if$k=ReadKey -1;.
Dom Hastings
11
Também parece que você pode substituir alguns blocos se por uma ifverificação postfix ou substituir por ternário para economizar mais, mas isso pode ser complicado com o aninhamento ... Você tem outro bloco $d--if$d>6que pode ser alterado $d-=$d>6para um economia de 2 bytes que pode funcionar em mais alguns lugares também e outra pequena economia é em ;$p=H.'='x9 .$"vez de $p="H========= ". Espero que alguns deles sejam úteis!
Dom Hastings
11
Obrigado, feliz por você gostar. Suas dicas ajudaram a reduzir ainda mais os 50 bytes! Esse truque com o ord é perverso. O truque $ d - = $ d> 6 parecia tão estranho. Eu também descobri que ao imprimir algo como "$ aH" é um problema, esse "$ {a} H" funciona como no bash. :)
LukStorms
11
Ah sim! Algumas maneiras de contornar isso usando nomes de variáveis ​​não alfabéticos ( $}ou algo assim) ou palavras de barra ( $a.H), não tenho certeza se isso o ajudará neste caso ou não. Algo que eu notei é: sub P se você tiver apenas um argumento, poderá ter em print"\e[@_"vez disso, .popjá que não haverá um separador de campos para se preocupar. Além disso, se você estiver usando o teclado numérico em vez de letras, não precisará usá-lo ord, como $kseria 4ou 6poderia fazer 5<=>$k.
Dom Hastings
11
Obrigado novamente. Não achou que o perl aceitaria variáveis ​​como essa O_o. Mas funciona e alguns bytes foram resqued por isso. Mas não tente usar um $! variável. Coisas estranhas acontecem então.
LukStorms
1

JavaScript, 618 bytes + HTML, 99 bytes

Bem, aqui está a minha resposta JavaScript, mesmo que não seja viável em outros idiomas:

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 para bônus

Eric Vincent
fonte
Hm, isso não parece muito bom para mim. Você ainda pode se livrar de nomes de variáveis ​​de duas letras, substituir alguns &&tokens &, eliminar muitos ;tokens, se livrar de espaços desnecessários depois {e até se livrar de alguns caracteres de aspas no HTML. E provavelmente muito mais, até. Isso é apenas um palpite, mas você pode tentar evitar o UglifyJS e reduzi-lo manualmente. :)
Chiru
6
Muito enigmático postado desta maneira. O leitor precisa pesquisar o código de 663 caracteres para o manuseio das chaves e, em seguida, possivelmente o STFW para descobrir quais chaves possuem os códigos 37 e 39. (De qualquer forma, não há reação nas teclas de seta esquerda e direita no último Firefox que eu uso). não sendo possível testá-lo, nunca descobrirei qual dos três bônus disponíveis você ganhou -20.
manatwork