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
o
ou 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 código-golfe , 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!
Respostas:
Perl,
760 611 592 535515 (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
fonte
print
mais de quatro vezes, deve ser mais barato configurar um novo sub e chamar issosub p{print@_}
. Se você não se importa de usar outras chaves, bem como aquelas específicas, pode substituí-lasif(defined($k=ReadKey(-1))){L(-1)if's'eq$k;L(1)if'd'eq$k;I,if'r'eq$k}
porL 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;
.if
verificaçã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>6
que pode ser alterado$d-=$d>6
para 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!$}
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 emprint"\e[@_"
vez disso,.pop
já 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á-loord
, como$k
seria4
ou6
poderia fazer5<=>$k
.JavaScript, 618 bytes + HTML, 99 bytes
Bem, aqui está a minha resposta JavaScript, mesmo que não seja viável em outros idiomas:
-20 e -25 para bônus
fonte
&&
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. :)