ASCII Гра в понг


10

Ассі Понг

Завдання полягає в тому, щоб відтворити класичну гру "понг" в символах ASCII в найкоротший термін.

Вимоги / характеристики

  • "Екран" повинен містити 45x25 символів.
  • Білий простір насправді повинен бути білим простором.
  • Весла повинні мати 9 рівних знаків: =========і повинні знаходитися на верхніх і найнижчих рядах (я знаю, що оригінал відтворюється збоку, а не зверху донизу, але я думаю, що це краще працює для ascii pong ).
  • Куля може бути нижньою або верхньою буквою oабо нулем.
  • Дві кнопки введення будь-якого типу (добре, якщо користувач натискає клавішу, яка відображає літеру на вводі, що теж добре), щоб переміщувати лопатку гравця вліво та вправо, одного або двох символів одночасно.
  • М'яч повинен бути рикошетом під відповідним кутом при ударі про весло або стіну (підказка: заперечуйте значення різниці x або y).
  • Оцінка повинна відображатися десь у висновку. Оцінка - скільки разів успішно гравець ударяє м'яч.
  • Якщо м'яч пропустив весло гравця, припиніть програму.
  • Має бути якийсь AI (навіть якщо лопатка AI просто відповідає значенню x).
  • М'яч не може рухатись по прямій вертикалі чи горизонталі.

Початковий екран / перший кадр повинен виглядати приблизно так:

                  =========                  











                      o                      











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

Підрахунок балів Це , тому найкоротший код виграє ... однак, є кілька бонусів, щоб зменшити кількість персонажів:

  • -30 символів: змініть траєкторію кулі залежно від місця попадання на весло
  • -10 символів: зробіть швидкість гри з часом
  • -20 символів: зробіть AI помітним
  • -20 символів: Уникайте будь-яких ситуацій, коли гравець залишається нерухомим, а гра триває вічно, не виграючи або програючи (спричинені певними траєкторіями та моделями AI)
  • -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 добре, але при взаємодії з клавіатурою нам доведеться створити цілий додаток. Цей тип проблем викликає недовольство, тому що багато мов не підтримують введення-виведення подібного. Реалізація AI, фізики. Майже як повномасштабне додаток. Якщо ви подивитесь на інші виклики, у них є одне завдання, яке приймає вхід (чи ні) і дає відповідне висновок. Додавання інтерфейсу AI, фізики та клавіатури - це лише шлях до вирішення проблеми
Downgoat

1
@vihan AI для понг надзвичайно простий, він просто повинен дотримуватися значення х кулі. Навіть зробити його зручним не так вже й важко, просто обмежте швидкість руху весла. Єдина реальна проблема з концепцією - це взаємодія клавіатури, якою можна керувати на різних мовах. Цей короткий огляд є досить невиразним та відкритим (враховуючи, що ми тут дотримуємось однозначності та справедливості), і величезна кількість бонусів не допомагає цьому.
Рівень річки Св.


2
Взаємодія з клавіатурою довелося вирішити і в (Re) впровадженні тетрісу , але це не зменшило популярності завдання. (Так, я знаю, це було насправді популярністю-конкурсом , це не так.) Єдине, що особисто мене вважає тривожним, - це сума бонусів. Але, безумовно, не повинно відповідати моєму смаку.
манатура

Відповіді:


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перевіряють постфіксом або заміняють на потрійну, щоб отримати додаткові заощадження, але це може виявитись складним із вкладенням ... У вас є ще один блок, $d--if$d>6який ви можете змінити на $d-=$d>62-байтове збереження, яке може працювати і в ще декількох місцях, а ;$p=H.'='x9 .$"замість цього ще одна невелика економія $p="H========= ". Сподіваюсь, деякі з них корисні!
Дом Гастінгс

1
Дякую, радий, що тобі це подобається. Ваші поради допомогли ще більше пограти на 50 байт! Цей трюк з ордом злий. Трюк $ d - = $ d> 6 виглядав так дивно. Я також виявив, що при друкуванні чогось типу "$ aH" є проблемою, що "$ {a} H" працює так, як це було б в башті. :)
LukStorms

1
Ага так! Кілька способів цього, використовуючи $}неабетичні назви змінних ( або щось таке) або використовуючи бареври ( $a.H), не впевнені, чи допоможе це вам у цьому випадку чи ні. Щось, що я помітив, полягає в тому, що sub P якщо ви коли-небудь матимете один аргумент, ви могли б print"\e[@_"замість цього, .popоскільки не буде розділювача поля, про який слід турбуватися. Крім того, якщо ви використовуєте numpad замість букв, вам не потрібно використовувати 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. не в змозі перевірити це, я ніколи не дізнаюся, за який з 3-х доступних бонусів ви заробили -20.
манантська робота
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.