เกม ASCII of Pong


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
อย่างน้อยใครก็ได้ที่สามารถอธิบายได้ว่าทำไมพวกเขาถึงลงคะแนนเรื่องนี้? ฉันอยากรู้อยากเห็นอย่างแท้จริงเพราะฉันคิดว่ามันจะสนุก แต่ฉันไม่มีประสบการณ์มาก
Eric Vincent

3
การพิมพ์สิ่ง ASCII นั้นใช้ได้ แต่ด้วยการใช้แป้นพิมพ์เราต้องสร้างแอพทั้งหมด ความท้าทายประเภทนี้เกิดขึ้นเพราะหลาย ๆ ภาษาไม่รองรับ i / o เช่นนั้น การใช้ AI, ฟิสิกส์ เกือบเหมือนแอปพลิเคชั่นเต็มรูปแบบ หากคุณพิจารณาความท้าทายอื่น ๆ พวกเขามีภารกิจหนึ่งที่รับอินพุต (หรือไม่) และสร้างเอาต์พุตที่เกี่ยวข้อง การเพิ่ม AI, ฟิสิกส์และแป้นพิมพ์ knteraction เป็นเพียงวิธีการที่ท้าทายมาก
Downgoat

1
@vihan AI สำหรับ pong นั้นง่ายมากเพียงแค่ต้องติดตามค่า x ของลูกบอล แม้การทำให้สามารถเอาชนะได้นั้นไม่ยากเพียง จำกัด ความเร็วในการพายเท่านั้น ปัญหาที่แท้จริงเพียงอย่างเดียวของแนวคิดคือการโต้ตอบของแป้นพิมพ์ซึ่งสามารถจัดการได้ในภาษาที่หลากหลาย อย่างไรก็ตามสั้น ๆ ค่อนข้างคลุมเครือและเปิดกว้าง (เนื่องจากเราเป็นผู้ใช้เล่ห์เหลี่ยมสำหรับความไม่ชัดเจนและเป็นธรรมรอบ ๆ ที่นี่) และโบนัสมากมายไม่ได้ช่วยอะไร
เลเวลริเวอร์เซนต์


2
การโต้ตอบกับคีย์บอร์ดจะต้องแก้ไขใน(เรื่อง) การนำ Tetris มาใช้ด้วยเช่นกัน แต่นั่นก็ไม่ได้ลดความนิยมของงานลง (ใช่ฉันรู้ว่านั่นคือการประกวดความนิยมจริง ๆนี่ไม่ใช่) สิ่งเดียวที่ฉันพบว่าเป็นการรบกวนส่วนตัวคือจำนวนโบนัส แต่แน่นอนว่าไม่ต้องขึ้นอยู่กับรสนิยมของฉัน
จัดการ

คำตอบ:


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;เป็นกุญแจที่มี:
Dom Hastings

1
นอกจากนี้ดูเหมือนว่าคุณสามารถแทนที่สองสามถ้าบล็อกด้วยการifตรวจสอบpostfix หรือแทนที่ด้วย ternary สำหรับการออมเพิ่มเติมบางอย่าง แต่ที่อาจพิสูจน์ได้ว่ายุ่งยากกับการทำรัง ... คุณมีบล็อกอื่น$d--if$d>6ที่คุณสามารถเปลี่ยน$d-=$d>6เป็นประหยัด 2 ไบต์ อาจจะทำงานในสถานที่มากขึ้นน้อยเกินไปและอีกประหยัดขนาดเล็กแทน;$p=H.'='x9 .$" $p="H========= "หวังว่าสิ่งเหล่านี้มีประโยชน์!
Dom Hastings

1
ขอบคุณดีใจที่คุณชอบ เคล็ดลับของคุณช่วยในการตีกอล์ฟให้ไกลขึ้นด้วย 50 ไบต์! เคล็ดลับกับอ๊อดนั้นชั่วร้าย $ d - = $ d> 6 เคล็ดลับดูแปลกมาก ฉันยังค้นพบด้วยว่าเมื่อพิมพ์บางอย่างเช่น "$ aH" เป็นปัญหาว่า "$ {a} H" ทำงานได้ดีเหมือนทุบตี :)
LukStorms

1
ใช่แล้ว! สองสามวิธีในการใช้ชื่อตัวแปรที่ไม่ใช่ตัวอักษร ( $}หรือบางอย่าง) หรือใช้ barewords ($a.H ) ไม่แน่ใจว่าจะช่วยคุณได้ในกรณีนี้หรือไม่ สิ่งที่ฉันสังเกตเห็นคือsub P ถ้าคุณมีข้อโต้แย้งเพียงข้อเดียวคุณสามารถมีprint"\e[@_"แทนที่จะเป็น.popเพราะไม่มีตัวคั่นฟิลด์ที่จะต้องกังวล นอกจากนี้ถ้าคุณกำลังใช้ numpad แทนตัวอักษรที่คุณไม่จำเป็นต้องใช้ordเป็น$kจะเป็น4หรือ6เพื่อให้คุณสามารถทำ5<=>$kแทน
Dom Hastings

1
ขอบคุณอีกครั้ง. ไม่คิดว่า Perl จะยอมรับตัวแปรเช่นนั้น O_o แต่มันใช้งานได้และไม่กี่ไบต์ก็ถูก resqued โดยที่ แต่อย่าลองใช้ $! ตัวแปร. สิ่งประหลาดเกิดขึ้นแล้ว
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 และย่อขนาดด้วยมือ :)
Chiru

6
ค่อนข้างคลุมเครือโพสต์ด้วยวิธีนี้ ผู้อ่านต้องค้นหารหัส 663 ตัวอักษรสำหรับการจัดการคีย์จากนั้นอาจเป็น STFW เพื่อค้นหาว่าคีย์ใดมีรหัส 37 และ 39 (อย่างไรก็ตามไม่มีการตอบสนองต่อปุ่มลูกศรซ้ายและขวาใน Firefox ล่าสุดที่ฉันใช้) ไม่สามารถทดสอบได้ฉันจะไม่พบว่ามี 3 โบนัสที่คุณได้รับ -20
จัดการ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.