ASCII игра в понг


10

Аски Понг

Задача состоит в том, чтобы воссоздать классическую игру «понг» в символах ASCII в кратчайшем возможном коде.

Требования / характеристики

  • «Экран» должен быть 45х25 символов.
  • Пробел на самом деле должен быть пробелом.
  • Весло должно быть 9 знаков равенства: =========и должно быть на самом верхнем и самом нижнем рядах (я знаю, что оригинал воспроизводится из стороны в сторону, а не сверху вниз, но я думаю, что это лучше работает для ascii pong ).
  • Мяч может быть в нижнем или верхнем регистре oили ноль.
  • Две кнопки ввода любого типа (это хорошо, если пользователь нажимает клавишу, которая заставляет букву появляться на входе, что тоже хорошо), чтобы перемещать весло игрока влево и вправо на один или два символа за раз.
  • Мяч должен рикошетить под соответствующим углом при ударе о весло или стену (подсказка: отмените значение разницы x или y).
  • Счет должен отображаться где-то в выводе. Счет - сколько раз игрок ударил по мячу.
  • Если мяч не попал в ракетку, закройте программу.
  • Должен быть какой- то ИИ (даже если весло ИИ просто соответствует значению х шара).
  • Мяч не может двигаться по прямой линии вертикально или горизонтально.

Начальный экран / первый кадр должен выглядеть примерно так:

                  =========                  











                      o                      











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

Подсчет очков Это , поэтому выигрывает самый короткий код ... однако, есть некоторые бонусы, чтобы уменьшить количество ваших персонажей:

  • -30 символов: изменить траекторию мяча в зависимости от того, где он ударяет по веслу
  • -10 персонажей: ускорение игры
  • -20 символов: сделать ИИ побиваемым
  • -20 персонажей: избегайте любых ситуаций, когда игрок остается неподвижным, а игра продолжается вечно без выигрыша или проигрыша (вызванного определенными траекториями и паттернами ИИ)
  • -20 символов: заставить мяч начать двигаться с (полу) случайной траектории
  • -25 символов: добавить опцию сброса

Вот пример без игры в гольф без бонусов в 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>

Пусть игра начнется!


3
Хорошо, может кто-нибудь хотя бы объяснить, почему они отказались от этого? Мне действительно любопытно, потому что я думал, что это будет весело, но у меня мало опыта.
Эрик Винсент

3
Распечатка ASCII-файлов - это нормально, но с клавиатурным взаимодействием нам придется создавать целое приложение. Проблемы такого типа неодобрительны, потому что многие языки не поддерживают такой ввод-вывод. Реализация ИИ, физика. Почти как полномасштабное приложение. Если вы посмотрите на другие проблемы, у них есть одна задача, которая принимает входные данные (или нет) и производит соответствующие выходные данные. Добавление искусственного интеллекта, физики и клавиатурных манипуляций - просто способ многого бросить вызов
Downgoat

1
@vihan AI для понга чрезвычайно прост, он просто должен следовать за значением x мяча. Даже сделать это не так сложно, просто ограничьте скорость вращения ракетки. Единственная реальная проблема с этой концепцией - взаимодействие с клавиатурой, которым можно управлять на разумном разнообразии языков. Краткое изложение, однако, довольно расплывчато и открыто (учитывая, что мы здесь сторонники однозначности и справедливости), и огромное количество бонусов не помогает этому.
Уровень Река Сент


2
Взаимодействие с клавиатурой должно было быть решено и в (Ре) Реализации Тетриса , но это не уменьшило популярность задачи. (Да, я знаю, что на самом деле это был конкурс популярности , это не так.) Единственное, что меня лично беспокоит, так это количество бонусов. Но, конечно, не должно быть на мой вкус.
manatwork

Ответы:


4

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

Консольное решение со всеми бонусами.
Он должен работать на любом терминале, который понимает управляющие коды ANSI (\ e [...). Проверено на Cygwin.

Управление с клавиатуры:
слева: 4,
справа: 6,
сброс: 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
Эй, Лук, любя это! Думаю, я бы поделился несколькими способами, которыми вы могли бы сэкономить больше символов ... Так как вы используете printболее 4 раз, будет дешевле установить новый саб и вызвать его sub p{print@_}. Если вы не возражаете против использования других ключей, а также тех, которые вы указали, вы можете заменить их if(defined($k=ReadKey(-1))){L(-1)if's'eq$k;L(1)if'd'eq$k;I,if'r'eq$k}на L 114<=>ord$k if$k=ReadKey -1;. Это просто преобразует <r: -1, r: 0,> r: 1, что может быть не тем, что вы ищете. Если вы счастливы с этим, вы можете использовать [4] [5] [6] в качестве ключей с: L$k<=>5 if$k=ReadKey -1;.
Дом Гастингс

1
Также похоже, что вы можете заменить несколько блоков if с помощью постфиксовой ifпроверки или заменить на троичную для большей экономии, но это может оказаться сложнее с вложенностью ... У вас есть другой блок, $d--if$d>6который вы можете изменить $d-=$d>6для 2-байтового сохранения, которое может работать и в нескольких других местах, и ;$p=H.'='x9 .$"вместо этого есть еще одна небольшая экономия $p="H========= ". Надеюсь, что некоторые из них полезны!
Дом Гастингс

1
Спасибо, рад, что тебе понравилось. Ваши подсказки помогли увеличить его до 50 байтов! Этот трюк с ордом злой. Трюк с $ d - = $ d> 6 выглядел так странно. Я также обнаружил, что при печати что-то вроде «$ aH» проблема заключается в том, что «$ {a} H» работает так же, как в bash. :)
LukStorms

1
О да! Пару способов обойти это, используя не алфавитные имена переменных ( $}или что-то в этом роде) или используя barewords ( $a.H), не уверен, поможет ли это вам в этом случае или нет. Что-то, что я заметил, в sub P том, что если у вас есть только один аргумент, вы могли бы иметь print"\e[@_"вместо этого, .popпоскольку не будет беспокойства по поводу разделителя полей. Кроме того, если вы используете цифровую клавиатуру вместо букв, вам не нужно использовать ord, как $kбыло бы 4или 6так вы могли бы сделать 5<=>$kвместо этого.
Дом Гастингс

1
Еще раз спасибо. Не думал, что Perl примет такие переменные, как O_o. Но это работает, и несколько байтов были восстановлены этим. Но не пытайтесь использовать $! переменная. Странные вещи происходят тогда.
LukStorms

1

JavaScript, 618 байт + HTML, 99 байт

Хорошо, вот мой ответ JavaScript для гольфа, даже если это невозможно на других языках:

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 и -25 для бонусов


Хм, это выглядит не очень хорошо для меня. Вы по-прежнему можете избавиться от двухбуквенных имен переменных, заменить несколько &&токенов &, исключить множество ;токенов, избавиться от лишних пробелов после {и даже избавиться от некоторых символов кавычек в HTML. И, вероятно, намного больше, даже. Это всего лишь предположение, но вы можете попытаться избежать UglifyJS и минимизировать вручную. :)
Чиру

6
Весьма загадочно выложено так. Читатель должен найти код из 663 символов для обработки клавиш, а затем, возможно, STFW, чтобы выяснить, какие клавиши имеют коды 37 и 39. (В любом случае, в последнем Firefox, который я использую, нет реакции на клавиши со стрелками влево и вправо). не имея возможности проверить это, я никогда не узнаю, за какой из 3 доступных бонусов вы заработали -20.
manatwork
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.