สร้างเกม 'Snake' ขึ้นใหม่ในคอนโซล / เทอร์มินัล


25

เกมสนุก

codegolf นี้ที่นี่สนุกมากฉันต้องสร้างเวอร์ชันสำหรับเกมคลาสสิคอื่น ๆ ที่มีความซับซ้อนเหมือนกัน วิธีที่สั้นที่สุดในการสร้างเกม Space Invaders ขั้นพื้นฐานใน Python

อย่างไรก็ตามในครั้งนี้พยายามที่จะสร้างเกม 'งู' คลาสสิกขึ้นมาใหม่ซึ่งคุณเริ่มต้นด้วยรูปร่างที่เล็กและเคลื่อนไหวอย่างต่อเนื่องเพื่อเก็บสะสมชิ้นส่วนเพื่อเพิ่มคะแนนของคุณ เมื่อคุณรวบรวมชิ้นส่วน 'หาง' ของคุณจะเติบโตซึ่งตามเส้นทางที่คุณทำ วัตถุประสงค์คือการอยู่ได้นานที่สุดโดยไม่ชนเข้ากับหางของคุณหรือเข้าไปในกำแพง

คุณสมบัติผู้สมัคร:

  • คุณตัวละครที่ประกอบขึ้นเป็นหางผนังและชิ้นส่วนที่คุณรวบรวมทั้งหมดควรเป็นตัวละครที่แตกต่างกัน
  • แสดง HUD ด้วยคะแนน คะแนนเพิ่มขึ้น 1 คะแนนสำหรับแต่ละชิ้นที่คุณสะสม
  • ผู้เล่นเสียเมื่อชนกับหางหรือกำแพง
  • วางไข่ชิ้นหนึ่งในพื้นที่สุ่มทันทีหลังจากรวบรวมชิ้นส่วนไม่ต้องพูดถึงตอนเริ่มเกม
  • ความเร็วของเกมไม่สำคัญตราบใดที่มันสอดคล้องกัน
  • 'เซลล์' ควรเป็นอักขระ 2x1 เนื่องจากความสูงของอักขระบล็อกคือ ~ สองเท่าของความกว้างสามารถเป็น 1x1 ได้เนื่องจาก 2x1 นั้นน่าเกลียดและฉันไม่คิดอย่างนั้น
  • ปุ่มสำหรับเปลี่ยนทิศทางควรเป็นawsd, ซ้าย, ขึ้น, ลง, ขวาตามลำดับ
  • ทิศทางเริ่มต้นควรขึ้น
  • คุณต้องแสดงขอบของกำแพง คะแนนอาจทับผนัง

รหัสสั้นที่สุดที่ตรงกับเกณฑ์ด้านบนชนะ คะแนนโบนัสจินตนาการสำหรับความคิดสร้างสรรค์


งูไม่ควรโตเมื่อกิน?
หยุดหมุนทวนเข็มนาฬิกาเมื่อ

hm? "เมื่อคุณรวบรวมชิ้นส่วน 'หาง' ของคุณจะโตขึ้นตามเส้นทางที่คุณทำ" ดังนั้นใช่งูก็จะเติบโต
Blazer

2
หากไม่มีawsdและstarting direction should always be upข้อกำหนดM-x snakeจะสามารถใช้งานได้
scrblnrd3

1
@ scrblnrd3 M-: (progn(define-key snake-mode-map"a"'snake-move-left)...(setq snake-initial-velocity-x 0 snake-initial-velocity-y 1)(snake))จะทำเคล็ดลับแล้ว
Jonathan Leech-Pepin

ที่เกี่ยวข้อง: Nibbles Nostalgia
sergiol

คำตอบ:


32

JavaScript ( 553 512 ไบต์)

ลิงก์ไปยังเวอร์ชันที่เล่นได้

c=0;a=b=d=-1;e=[f=[20,7],[20,8]];i=Math.random;~function n(){if(c&&(87==a||83==a
))c=0,d=87==a?-1:1;if(d&&(65==a||68==a))d=0,c=65==a?-1:1;p([j=e[0][0]+c,k=e[0][1
]+d])||!j||39==j||!k||10==k?b+=" | GAME OVER":(e.unshift([j,k]),p(f)?(f=[1+38*i(
)|0,1+9*i()|0],b++):e.pop());for(m=h="";11>h;h++){for(g=0;40>g;g++)l=g+","+h,m+=
!g||39==g||!h||10==h?"X":e[0]==l?"O":p(l)?"*":f==l?"%":" ";m+="\n"}x.innerHTML=m
+b;!b.sup&&setTimeout(n,99)}();onkeydown=function(o){a=o.keyCode};function p(o){
return e.join(p).indexOf(p+o)+1}

ฉันพยายามทำให้มันส่งออกไปยังคอนโซลจริงในตอนแรก (ด้วยconsole.logและconsole.clear) แต่มันกะพริบมากเกินไปดังนั้นฉันจึงใส่มันลงใน HTML เหมือนคอนโซล มันจะทำงานกับสิ่งนี้:

<pre id=x>

ฉันใช้มันกับเซลล์ 2x1 ก่อน แต่มันก็ดูแย่กว่า 1x1 นั่นจะเป็นการเปลี่ยนแปลงเล็กน้อยแม้ว่า

ใช้awsdปุ่มบนแป้นพิมพ์

ปรับปรุง:

ฉันสามารถลดขนาดได้ถึง 512 (0x200 ตรง) โดยปรับปรุงการค้นหาหางและทำเวทมนตร์เพิ่มเติม

ตอนนี้คุณจะได้รับ 2 คะแนนเมื่อชิ้นส่วนวางไข่ที่หางของคุณ ฉันยังแก้ไขการทับซ้อนเมื่องูกัดตัวมันเอง


1
สวย! และคุณพูดถูกมันจะดูดีกว่า 1x1 กว่า 2x1 ความกังวลเดียวที่ฉันมีก็คือการขึ้นลงเร็วกว่าซ้ายและขวา แต่ก็ทำได้เมื่อพิจารณาถึงข้อ จำกัด กระพริบในคอนโซลฉันไม่รังเกียจมาก (ดูโปรแกรมผู้รุกรานพื้นที่ของฉันมันค่อนข้างกะพริบ) แต่ฉันคิดว่าหน้าเว็บข้อความธรรมดาทำงานด้วย! qualm หนึ่งแม้ว่า ... จะมีวิธีการเริ่มใหม่โดยไม่จำเป็นต้องรีเฟรชหรือไม่ :(
Blazer

ใช้งานไม่ได้awsd
Neal

@Blazer นั่นจะใช้เวลา 13 ตัวอักษร: - / ... และคุณมีปุ่ม F5 อยู่ดี
คัดลอก

@Neal ใช่ฉันใช้ปุ่มลูกศร แต่แก้ไขทันที
คัดลอก

@ คัดลอกฉันคิดว่าฉันไม่ได้ทำตามความต้องการ
Blazer

21

x86 รหัสเครื่อง (128 ไบต์)

เหมือนกับที่ฉันยอมสร้าง Mandlebrot Fractalฉันเขียน prod สำหรับเกมงูขนาด 128 ไบต์ มันไม่เป็นไปตามข้อกำหนดของความท้าทายอย่างเต็มที่ (มันเริ่มเคลื่อนไปทางขวาไม่ใช่กำแพงทั้งหมดถูกดึง) แต่ฉันโพสต์มันเพราะฉันคิดว่ามันเป็นทางออกที่น่าสนใจและสร้างสรรค์ คะแนนจะแสดงเป็นเลขฐานสองทางด้านขวาปุ่มลูกศรควบคุมทิศทางของการเคลื่อนไหว 'อาหาร' จะลดลงแบบสุ่มและจะสิ้นสุดลงหากคุณตีตัวเองผนังหรือขอบของหน้าจอ

ลิงก์สำหรับไฟล์เรียกทำงานและซอร์สโค้ด

ภาพหน้าจอ

นอกจากนี้เกี่ยวกับความคิดเห็นก่อนหน้านี้เกี่ยวกับว่าการโกง dosbox ฉันคิดว่ายอมรับได้อย่างสมบูรณ์ตราบใดที่มันอยู่ในโหมดการแสดงผลแบบข้อความเพราะมันเป็นเพียงแค่เทอร์มินัล dos


ทำไม DOSBox ถึงถูกโกง? มันเป็นแพลตฟอร์มที่สมบูรณ์แบบที่สุด
dfeuer

9

16 บิต 8086

526 ไบต์ / 390 ไบต์

ถอดรหัสสิ่งนี้โดยใช้ตัวถอดรหัส Base64และเรียกมันว่า "snake.com" แล้วดำเนินการจากพรอมต์คำสั่งของ Windows ทดสอบกับ WinXP คุณอาจต้องใช้ DosBox เพื่อรับโหมดวิดีโอที่ถูกต้อง ปุ่มควบคุมคือ 'wasd' และพื้นที่ว่างเพื่อออก กด 'w' เพื่อเริ่ม

uBMAzRC5AD+2AOipAb1AAbgAoI7Auf//v4sMsAHzqrgAtLksAfOqg8cU/sx19OgsAYs+8gKwAuj4
ALQAzRpCiRYOA4kWEAPouAC0C80hCsB0IbQIzSG+ygKDxgOAPAB0EjgEdfSLRAGzAP/Qo1cBiB7w
AulqAIEGdAGu/7P+uNECgMMEw7MCuNsCgMMGw4s+8gKLHvACisPolwADv+YCJoo16I0AiT7yAoD+
A775AnREiz70AiaKHbAA6HUAA7/mAok+9AKA/gB0FscGVwHNAoEudAGu/zPJtj/o2QDofQC0AM0a
OxYOA3X2/wYOA+lZ/8YEAE7+BIA8CnT16F4AaOAB6EQAM9K5LQD38YvCweACBQoA9+WL+OguALlL
ADPS9/HB4gKDwgsD+iaAPQB10rADiMRXq4HHPQGrq4HHPAGrq4HHPQGrX8OhEAO62wD34rntf/fx
iRYQA4vCw772Ar8K9bUEshCstACL2AHDi4f6ArMDtwXR+LEAwNEC/smA4Q8miA0p7/7PdevoIQA6
xHQE/st13ugKAP7NdcroAwB1+8O3BSbGBQEp7/7PdfaBx0EG/srDuBAQM9uAwwLNEID7CnX2w7gD
AM0QzSB3dgEgxgIAYYcBZIUBIMYCAHd8AXN+ASDGAgAA+wAF/P8EAAIAH4ofigAAAADRxeD/TJlO
gQPvQrVA4++BVdVjgQ==

นี่คือโหมดตัวละครที่มีความยาว 390 ไบต์:

uAMAzRC4ALiOwLlQADP/uCCf86uzF6u4AA+xTvOruCCfq7LdfCxUPOr6BgBiz5+AqF8Aqu0AM0aQ
okWhgKJFogC6MUAtAvNIQrAdCG0CM0hvlYCg8YDgDwAdBI4BHX0i0QBswD/0KNSAYgefALpdgCBB
m8Bov+z/rhdAoDDBMOzArhnAoDDBsOLPn4Cix58AiaJHQOclgmijUmiR2JPn4CgP4DvoUCdFOLPo
ACJoodJscFAAADv3JYiT6AAoD+AHQkxwZSAVkCgS5vAaL/vwEAudAHJoA9qnUEJsYFzIPHAuLx6F
4AtADNGjsWhgJ19oMGhgIC6Uz/xgQATv4EgDwKdPXoPgBo5wHoIgC5FwD38Wn6oADoFgC5TgD38U
ID0gP6JoA9AHXhJscFA93DoYgCutsA9+K57X/38YkWiAKLwjPSw76CAr8CALkEALSfrAQwq+L6w8
0gd3EBIFcCAGGCAWSAASBXAgB3dwFzeQEgVwIAYP+gAP7/AgACqtAH0AcAAAAA

โหมดตัวละครตัวนี้มีความยาวสามไบต์ (แต่ดีกว่าของงู):

uAMAzRC4ALiOwLlQADP/uCCf86uzF6u4AA+xTvOruCCfq/7LdfCxUPOr6BsBiz6BAibHBQEKtADN
GkKJFokCiRaLAujHALQLzSEKwHQhtAjNIb5ZAoPGA4A8AHQSOAR19ItEAbMA/9CjUwGIHn8C6XgA
gQZwAaD/s/64YAKAwwTDswK4agKAwwbDiz6BAosefwImiR0Dv3VYJoo1JscFAQqJPoECgP4DvogC
dFOLPoMCJoodJscFAAADv3VYiT6DAoD+AHQkxwZTAVwCgS5wAaD/vwEAudAHJoA9qnUEJsYFzIPH
AuLx6F4AtADNGjsWiQJ19oMGiQIE6Ur/xgQATv4EgDwKdPXoPgBo6gHoIgC5FwD38Wn6oADoFgC5
TgD38UID0gP6JoA9AHXhJscFA93DoYsCutsA9+K57X/38YkWiwKLwjPSw76FAr8CALkEALSfrAQw
q+L6w80gd3IBIFoCAGGDAWSBASBaAgB3eAFzegEgWgIAYP+gAP7/AgACqtAH0AcAAAAA

คะแนนสำหรับความคิดสร้างสรรค์ แต่ฉันคิดว่าการใช้ dosbox นั้นเป็นการโกงเพราะความท้าทายคือทำให้เกมทำงานในคอนโซลหรือเทอร์มินัลไม่ใช่ของ dosbox ยังไม่ควรเขียนรหัสกอล์ฟเป็นซอร์สโค้ดไม่ใช่ไบนารี?
Blazer

7
@Blazer: นั่นคือซอร์สโค้ด - ฉันพิมพ์รหัสเครื่องโดยใช้โปรแกรมแก้ไขฐานสิบหก - นั่นคือวิธีที่ l337 ฉันเป็น! ;-) สิ่ง DosBox จำเป็นเฉพาะเมื่อไดรเวอร์วิดีโอของคุณมีปัญหากับโหมด 13 กราฟิก (การ์ดของฉันก็โอเคกับมัน) มันจะไม่เป็นเรื่องยากที่จะทำรุ่น ASCII (อาจจะมีขนาดเล็กเกินไป)
Skizz

รุ่น "390- ไบต์" ถอดรหัสเป็น 388 ไบต์เท่านั้นและหยุดทำงานเมื่อทำงานภายใต้ dosbox ดูเหมือนว่าบางสิ่งอาจสูญหายไปในการส่งสัญญาณ :( ยังมีอีกสองรุ่นที่ยอดเยี่ยมมาก!
Ilmari Karonen

มีโค้ดเวอร์ชันที่ไม่ดีหรือไม่? (ฉันไม่รู้ภาษานี้)
อัล

1
@ n.1: โปรแกรมคือรหัสเครื่อง 8086 คุณสามารถโหลดลงในโปรแกรมดีบั๊ก (D86) และดูรหัสตามที่เขียนแม้ว่าจะไม่มีชื่อฉลาก
Skizz

6

เปลือก / sh, 578 ตัวอักษร

ฉันพยายามที่จะเป็นไปตาม POSIX (การพกพามากที่สุดและหลีกเลี่ยงการ bashisms แม้เครื่องกำเนิดเลขสุ่มไม่จำเป็นต้อง / proc) คุณเช่นสามารถเล่นได้ใน terminal พื้นเมืองของคุณหรือผ่านทาง SSH เซสชั่น: ทำงานกับ 'รีบ -c ./snake' นอกจากนี้ยังมีตัวแปร unuglyfied / อ่านใน ~ 2800 ไบต์ซึ่งสามารถมองเห็นได้ที่นี่

หมายเหตุบางประการ: การเขียนสคริปต์เชลล์ไม่เหมาะสำหรับการเข้ารหัสเกม 8-)

  • เพื่อความเป็นธรรมเราใช้เพียงเรียกว่า 'บิลด์อิน' ซึ่งหมายถึง
    • ไม่มีการเรียกโปรแกรมภายนอกเช่น 'ชัดเจน', 'stty' หรือ 'tput'
    • ด้วยเหตุนี้เราจึงวาดใหม่ทั้งหน้าจอในทุกการเคลื่อนไหว
    • buildins ที่ใช้แล้วเท่านั้น (คำสั่งดั้งเดิม aka) คือ:
      • echo, eval, while-loop, ให้, แบ่ง, อ่าน, เคส, ทดสอบ, ตั้งค่า, shift, alias, แหล่งที่มา
  • ไม่มีตัวสร้างตัวเลขสุ่ม (PRNG) ดังนั้นเราต้องสร้างของเราเอง
  • รับบล็อกการกดแป้นพิมพ์ดังนั้นเราจึงต้องวางไข่หัวข้ออื่น
    • สำหรับการรับเหตุการณ์ใน parent-task เราใช้ tempfile (น่าเกลียด!)
  • งูเองนั้นเป็นรายการซึ่งราคาถูก:
    • แต่ละองค์ประกอบคือ (x, y) -tuple
    • การหลุดหางหมายถึง: เปลี่ยนรายการด้วย 1
    • การเพิ่มส่วนหัว (ใหม่) หมายถึง: ผนวกสตริง
  • กริดนั้นเป็นอาร์เรย์ภายใน แต่ shell / sh ไม่ทราบสิ่งนี้:
    • เรา "emulated" array (x, y) ผ่านการโทร eval ที่น่าเกลียดด้วย vars ทั่วโลก
  • และในที่สุด: เราสนุกมาก!
#!/bin/sh
alias J=do T=let E=echo D=done W=while\ let
p(){ eval A$1x$2=${3:-#};}
g(){ eval F="\${A$1x$2:- }";}
r(){
E $((1+(99*I)%$1))
}
X=9
Y=8
L="8 8 $X $Y"
I=41
W I-=1
J
p $I 1
p $I 21
p 1 $I
p 41 $I
D
p 3 3 :
>L
W I+=1
J
E -ne \\033[H
y=22
W y-=1
J
Z=
x=42
W x-=1
J
g $x $y
Z=$Z$F
D
E "$Z"
D
E $B
. ./L
case $D in
a)T X+=1;;d)T X-=1;;s)T Y-=1;;*)T Y+=1;;esac
g $X $Y
case $F in
\ |:)p $X $Y O
L="$L $X $Y"
case $F in
:)W I+=1
J
x=`r 39`
y=`r 19`
g $x $y
[ "$F" = \  ]&&{
p $x $y :
break
}
D
T B+=1;;*)set $L
p $1 $2 \ 
shift 2
L=$@;;esac;;*).;;
esac
D&
while read -sn1 K
J
E D=$K>L
D

ป้อนคำอธิบายรูปภาพที่นี่


ใช้งานได้จริงหรือ ถ้างูไปทางขวาและคุณกดaมันหยุด แปลก.
gniourf_gniourf

ใช่เพราะคุณกัดตัวเองนั่นคือวิธีที่มันจะต้องเป็น IMHO เราคุยกันว่าภายในและทุกคนเห็นด้วยกับเรื่องนี้
Bastian Bittorf

echo -nไม่พกพาอย่างแน่นอน หากตัวถูกดำเนินการแรกคือ -n หรือถ้าตัวถูกดำเนินการตัวใดตัวหนึ่งมีอักขระเครื่องหมายทับขวา ('\') ผลลัพธ์จะถูกกำหนดโดยการนำไปปฏิบัติ การใช้เสียงสะท้อนเพื่อสิ่งอื่นที่ไม่ใช่ข้อความโดยไม่มีสวิตช์ใด ๆ จะไม่สามารถพกพาได้ pubs.opengroup.org/onlinepubs/009604599/utilities/echo.html
nyuszika7h

nyuszika7h: ความคิดใด ๆ วิธีการ circument นี้?
Bastian Bittorf

nyuszika7h: ฉันพบวิธีลบการโทร 'echo -n' หลัก - ดังนั้นจึงเหลือการโทรเพียงครั้งเดียว กำลังเรียกลำดับการหลบหนีสำหรับ 'go to home-position (0,0)'
Bastian Bittorf

4

Ruby 1.9 / Windows เท่านั้น / ( 354 337 355 346 ไบต์)

require'Win32API';G=(W=Win32API).new g="crtdll","_getch",t=[],?I
B=(c=?#*39+h="#
#")+((S=' ')*38+h)*20+c;n=proc{c while B[c=rand(800)]!=S;B[c]=?*;S}
n[h=760];k={97=>-1,100=>1,119=>d=-41,115=>41}
(B[h]=?O;system'cls';$><<B<<$.;sleep 0.1
d=k[G.call]if W.new(g,"_kbhit",[],?I).call>0
t<<h;B[h]=?o;B[h+=d]==?*?B[h]=n[$.+=1]:B[t.shift]=S)while B[h]==S

เล่นในกระดานขนาด 20x40 ในคอนโซล windows คะแนนแสดงอยู่ใต้บอร์ด ใช้WASDเพื่อควบคุมงูปุ่มอื่น ๆ เพื่อออก (แรง!) แก้ไขเวลาพักเครื่องในตอนท้ายของบรรทัดที่ 5 เพื่อควบคุมความเร็ว (หรือบันทึกอักขระ 10 ตัวและทำให้เล่นไม่ได้เกือบโดยการลบโหมดสลีปโดยสิ้นเชิง!)

คุณสมบัติโบนัส: สุ่มล้มเหลวในการเริ่มต้น (เมื่อชิ้นแรกถูกสร้างขึ้นในตำแหน่งของงู)

ฉันต้องการ ~ 100 ตัวอักษรเพื่อหลีกเลี่ยงการไม่มี getchar ที่ไม่ปิดกั้น เห็นได้ชัดว่า Ruby 1.9.3 มีไลบรารี่ "io / console" ซึ่งจะบันทึกได้ครึ่งหนึ่ง และวิธีนี้เป็นวิธีเฉพาะของ Windows มีวิธีแก้ไขที่เผยแพร่เพื่อทำสิ่งเดียวกันในระบบ * nix แต่ฉันไม่ได้ทดสอบเพื่อเปรียบเทียบจำนวนตัวอักษร

แก้ไข:

ต้องเพิ่ม 18 ไบต์หลังจากที่ฉันรู้ว่าหางเติบโตหลังจากกินเท่านั้นไม่ใช่หลังจากแต่ละขั้นตอน

แก้ไข 2: (อาจเป็นไปได้) แก้ไขปัญหาการชนบันทึก 9 ไบต์ด้วยการ จำกัด รายการอาหารหนึ่งรายการ


ฉันชอบความคิดของรายการอาหารหลายรายการในครั้งเดียว แต่มีปัญหาใหญ่: หางควรย้ายไปพร้อมกับผู้เล่นเพียงเติบโตโดยตัวละครตัวเดียวสำหรับอาหารทุกชิ้นที่คุณรวบรวม
Blazer

คุณเพิ่มความคิดเห็นในขณะที่ฉันกำลังแก้ไขมันอยู่ ... ถ้ามีเพียงชิ้นเดียวเท่านั้นฉันสามารถลบ9.times{}ตัวอักษรที่บันทึกไว้ออกได้ 9 ตัว
AShelly

ข้อกำหนดเพียงอย่างเดียวคือมีชิ้นส่วนอาหารครั้งละ 1 ชิ้นหรือมากกว่าดังนั้นคุณสามารถทำทีละชิ้นได้ครั้งละหนึ่งตัวเพื่อประหยัดอักขระบางตัว
Blazer

เกมชนกับฉันแบบสุ่มที่ ~ 140 คะแนนไม่แน่ใจว่าทำไม แต่อย่างอื่นดีมาก
Blazer

แก้ไขข้อผิดพลาดฉันคิดว่า หากเกิดปัญหาอีกครั้งโปรดแจ้งให้เราทราบข้อผิดพลาดทับทิม
AShelly

4

Applesoft พื้นฐาน - 478 (462)

นี่คือรหัสกอล์ฟครั้งแรกของฉัน แต่มันเขียนกลับในปี 1989 และส่วนใหญ่ใช้เกมงูตามที่ร้องขอ (แต่ไม่มีอาหารงูเติบโตอย่างต่อเนื่องและเป็นผู้เล่นสองคนไม่ใช่หนึ่งคน) โดยใช้เพียงสองบรรทัด Applesoft พื้นฐาน

มีการแข่งขันรายการสองบรรทัดในเวลาเช่นในวารสาร Dr. Dobbs ฉันใช้เวลา 6 เดือนหาวิธีที่จะทำให้มันพอดีกับสองบรรทัดที่มีความยาวไม่เกิน 255 ตัวอักษร (และมีเพียงหนึ่งสาขา)

ข้อมูลเพิ่มเติมได้ที่: http://davesource.com/Projects/SpeedWaller/

โปรแกรมที่พิมพ์เป็นสองบรรทัด:

1ONSCRN(X,Y)<>7ANDB<>0ANDSCRN(U,V)<>7GOTO2:HOME:GR:X=10:Y=20:U=30:V=Y:I=201:J=202:K=203:M=205:W=215:A=193:S=211:Z=218:O=1:Q=-1:P=49152:COLOR=7:HLIN0,39AT0:HLIN0,39AT39:VLIN0,39AT0:VLIN0,39AT39:VTAB22: ?"WASZ IJKM  "C:ONB=0GOTO2:CALL-678:RUN
2PLOTX,Y:PLOTU,V:B=PEEK(P):G=B<>ZANDB<>W:H=B<>AANDB<>S:O=G*(O*H+(B=S)-(B=A)):L=H*(L*G+(B=Z)-(B=W)):G=B<>IANDB<>M:H=B<>JANDB<>K:Q=G*(Q*H+(B=K)-(B=J)):R=H*(R*G+(B=M)-(B=I)):X=X+O:Y=Y+L:U=U+Q:V=V+R:FORN=1TO99:NEXT:C=C+1:VTAB22:HTAB12:?C:GOTO1

รายการเมื่อจัดรูปแบบมีลักษณะเช่นนี้:

1 ONSCRN(X,Y)<>7 AND B<>0 AND SCRN(U,V) <> 7 GOTO 2: HOME : GR :
  X=10 : Y=20 : U=30 : V=Y : I=201 : J=202 : K=203 : M=205 : W=215 :
  A=193 : S=211 : Z=218 : O=1 : Q=-1 : P=49152 : COLOR=7 : HLIN 0,39
  AT 0 : HLIN 0,39 AT 39 : VLIN 0,39 AT 0 : VLIN 0,39 AT 39 : VTAB 22 :
  ? "WASZ IJKM  "C : ON B=0 GOTO 2 : CALL -678 : RUN
2 PLOT X,Y : PLOT U,V : B=PEEK(P) : G= B<>Z AND B<>W: H=B<>A AND B<>S :
  O=G*(O*H+(B=S)-(B=A)) : L=H*(L*G+(B=Z)-(B=W)) : G=B<>I AND B<>M :
  H=B<>J AND B<>K : Q=G*(Q*H+(B=K)-(B=J)) : R=H*(R*G+(B=M)-(B=I)) :
  X=X+O : Y=Y+L : U=U+Q : V=V+R : FOR N=1 TO 99 : NEXT : C=C+1 :
  VTAB 22 : HTAB 12 : ? C : GOTO 1

เกมดังกล่าวเป็นผู้เล่นสองคนและมี "คำแนะนำ" ที่ด้านล่างของหน้าแสดงปุ่มเช่นเดียวกับตัวนับเพื่อให้คุณสามารถดูจำนวนขั้นตอนที่คุณรอดชีวิต เป็นตัวอักษร 478 ตัว 16 ตัวเป็นคำแนะนำและตัวนับผลลัพธ์ดังนั้น 462 หากคุณต้องการกำจัดมัน


4

C # .NET Framework 4.7.2 คอนโซล ( 2,456 2,440 2,424 2,408 2,052 1,973 1,747 1,786 1,686 ไบต์)

สนุกดี แต่ฉันต้องคิดจริงๆว่าตัวแปรคืออะไรเพราะมันเป็นเพียงจดหมายฉบับเดียว

using m=System.Console;using System;using System.Collections.Generic;using System.Threading;class s{static void Main(){m.CursorVisible=0>1;new s()._();}int l;Action<string> w=(x)=>m.Write(x);Action<int,int>n=(x,y)=>m.SetCursorPosition(x,y);(int x,int y)d,c,a;int h,u;List<(int x,int y)>p;void _(){while(1>0){f();h=25;u=25;p=new List<(int x,int y)>();l=0;d=(0,-1);c=(u/2,h/2);e();m.SetWindowSize(u+4,h+4);m.SetBufferSize(u+4,h+4);while(1>0){k();if(t())break;g();r();}f();m.SetWindowSize(u+4,h+6);m.SetBufferSize(u+4,h+6);n(1,h+3);w("        Game over,\n   press any key to retry.");f();m.ReadKey(1>0);m.Clear();}}private bool t(){if(c.x<0||c.y<0||c.x>=u||c.y>=h){r();n(c.x+2,c.y+2);w("X");return 1>0;}for(i=0;i<p.Count;i++){for(int j=0;j<i;j++){if(p[i].x==p[j].x&&p[i].y==p[j].y){r();n(c.x+2,c.y+2);w("X");return 1>0;}}}return 0>1;}private void e(){a=(z.Next(u),z.Next(h));l++;}void f(){while(m.KeyAvailable)m.ReadKey(1>0);}int i;void k(){var b=DateTime.Now;while((DateTime.Now-b).TotalMilliseconds<230)Thread.Sleep(10);if(!m.KeyAvailable)return;var a=m.ReadKey(1>0).Key;switch(a){case ConsoleKey.A:if(d.x==0)d=(-1,0);break;case ConsoleKey.W:if(d.y==0)d=(0,-1);break;case ConsoleKey.S:if(d.y==0)d=(0,1);break;case ConsoleKey.D:if(d.x==0)d=(1,0);break;}f();}void g(){c.x+=d.x;c.y+=d.y;p.Add((c.x,c.y));while(p.Count>l)p.RemoveAt(0);if(c.x==a.x&&c.y==a.y)e();}void r(){n(1,1);w("/");w(new string('-',u));w("\\");n(1,h+2);w("\\");w(new string('-',u));w("/");for(i=0;i<h;i++){n(1,i+2);w("|");n(u+2,i+2);w("|");}for(i=0;i<h;i++){for(int j=0;j<u;j++){n(i+2,j+2);w(" ");}}n(a.x+2,a.y+2);w("@");for(i=0;i<p.Count;i++){n(p[i].x+2,p[i].y+2);w("#");}n(2,0);w("Score:"+l);}Random z=new Random();}

ภาพหน้าจอบางส่วน:

งูมีคะแนน 10 งูชนกับคะแนน 4

ไบนารี: https://github.com/wooden-utensil/snakeCodeGolf/releases/tag/v1.0.0.0

ที่เก็บ GitHub: https://github.com/wooden-utensil/snakeCodeGolf

การเปลี่ยนแปลง: https://github.com/wooden-utensil/snakeCodeGolf/releases


1
Console.Write("Score:"+l);Console.WriteLine()->Console.WriteLine("Score:"+l)
Stephen

1
คุณลองสิ่งอันดับเหมือนกัน(int X,int Y)d; ...; d=(0,-1)ไหม? นั่นอาจช่วยประหยัดไบต์ ฉันยังไม่สามารถดูว่าทำไมคุณกำลังทำแทนVector2 d;Vector2 c;Vector2 a; Vector2 d,c,aฉันคิดว่าคุณยังสามารถเก็บฟังก์ชัน Console.SetCursorPosition เป็นAction<...>ตัวแปรตัวอักษรเดียว คุณสามารถลบ DateTime ด้วยตัวดำเนินการ - นอกจากนี้คุณยังสามารถประกาศตัวแปรลูปทั่วโลกและเพียงแค่ปล่อยให้เป็นศูนย์เมื่อจำเป็นโดยไม่ต้องประกาศพวกเขา
สรรพนามของฉันคือ monicareinstate

1
[คำแนะนำดำเนินการต่อ] คุณสามารถใช้1>0หรือเก็บไว้trueในตัวแปรแทนที่จะใช้คำหลัก คุณอาจสามารถใช้โอเปอเรเตอร์อันรุ่งโรจน์ในลูปได้ ในDateTime b = DateTime.Nowส่วนที่สามารถb varคุณอาจจะหรืออาจจะไม่สามารถบันทึกบางไบต์ใช้dynamic(มักจะช่วยให้คุณรวมประกาศที่แตกต่างกันพิมพ์)
คำสรรพนามของฉันคือ monicareinstate

1
ดึงm.write(String)เข้ามาเป็นของตัวเองหนึ่งตัวอักษรฟังก์ชั่นยาวอาจจะประหยัดตัน
Veskah

1
นอกจากนี้ยังมีบล็อกบางส่วนที่ใช้งานb.widthและb.heightจำนวนมากที่อาจถูกบันทึกไว้ในอีกชื่อหนึ่งว่า var local
Veskah

3

Python 3 - 644

from curses import *
import time
from collections import deque
from random import randrange as R
N,W,S,E=z=119,97,115,100
t=tuple
u=0,0
def m(s):
 a=lambda o,y,x:y.addch(o[0],o[1],x);q=lambda:(R(L-2),R(C-2));L,C=s.getmaxyx();curs_set(0);s.nodelay(1);s.border();s.refresh();r=newwin(L-2,C-2,1,1);n=deque();y,x=[L-2,0];d=N;n.append(u);c=N;p=q();a(p,r,N);a(u,s,48)
 while 1:
  if c in z:d=c
  if d==N:y-=1
  if d==S:y+=1
  if d==W:x-=1
  if d==E:x+=1
  l=n.pop()
  if (y,x) in n:return
  if (y,x)==p:p=q();a(p,r,N);n.append(l);s.addstr(0,0,str(len(n)))
  n.appendleft((y,x));a((y,x),r,S);a(l,r,32);r.refresh();time.sleep(.2);c=s.getch()
wrapper(m)

ไม่เลิกอย่างเรียบร้อย ชิ้นส่วนอาจหายไปหากวางไข่ที่ด้านบนของงู


1

Bash (ตัวอักษรมากเกินไป: ca. 1522)

t=tput
tc="$t cup"
tr="$t rev"
ts="$t sgr0"
ox=5
oy=5
((w=$($t cols)-2-2*ox))
((h=$($t lines)-2-2*oy))
trap "$t rmcup
stty echo
echo 'Thanks for playing snake!'
" EXIT
$t smcup
$t civis
stty -echo
clear
printf -v hs %$((w+2))s
printf -v v "|%${w}s|"
$tc $oy $ox
printf %s ${hs// /_}
for((i=1;i<=h+1;++i)); do
$tc $((oy+i)) $ox
printf %s "$v"
done
$tc $((oy+h+2)) $ox
printf %s ${hs// /¯}
dx=0
dy=-1
hx=$((w/2))
hy=$((h-2))
l=2
xa=($hx $hx)
ya=($hy $((hy+1)))
$tr
for((i=0;i<${#xa[@]};++i)); do
$tc $((ya[i]+1+oy)) $((xa[i]+1+ox))
printf \ 
done
$ts
print_food() {
$tc $((fy+1+oy)) $((fx+1+ox))
printf "*"
}
nf() {
rf=1
while((rf))
do
rf=0
((fx=RANDOM%w))
((fy=RANDOM%h))
for ((i=0;i<${#ya[@]};++i))
do
if((ya[i]==fy&&xa[i]==fx))
then
rf=1
break
fi
done
done
print_food
}
nf
ps() {
s="SCORE: $l"
$tc $((oy-1)) $((ox+(w-${#s})/2))
printf "$s"
}
ps
while :
do
read -t 0.2 -s -n1 k
if (($?==0))
then
case $k in
w|W)((dy==0))&&{ dx=0;dy=-1;};;
a|A)((dx==0))&&{ dx=-1;dy=0;};;
s|S)((dy==0))&&{ dx=0;dy=1;};;
d|D)((dx==0))&&{ dx=1; dy=0;};;
q|Q)break;;
esac
fi
((hx=${xa[0]}+dx))
((hy=${ya[0]}+dy))
if((hx<0||hy<0||hx>w||hy>h))
then
go=1
break
fi
for((i=1;i<${#ya[@]}-1;++i))
do
if((hx==xa[i]&&hy==ya[i]))
then
go=1
break 2
fi
done
$tc $((ya[-1]+1+oy)) $((xa[-1]+1+ox))
printf \ 
$tr
$tc $((hy+1+oy)) $((hx+1+ox))
printf \ 
$ts
if((hx==fx&&hy==fy))
then
((++l))
ps
nf
else
ya=(${ya[@]::${#ya[@]}-1})
xa=(${xa[@]::${#xa[@]}-1})
fi
ya=($hy ${ya[@]})
xa=($hx ${xa[@]})
done
if((go))
then
$tc 3 3
echo GAME OVER
read -t 3 -s -n1
fi

ภาพหน้าจอ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.