在控制台/终端上重新创建“蛇”游戏


25

游戏很有趣

这里的代码高尔夫球是如此有趣,我必须为复杂度相似的其他经典游戏制作一个版本。用Python创建基本太空侵略者游戏的最快捷方法

但是,这一次,请尝试重新创建经典的“蛇”游戏,在这种游戏中,您从小形状开始,不断地移动以收集碎片来增加得分。当您收集一件物品时,您的“尾巴”就会增加,它沿着您所走的道路前进。目的是持续最长的时间而不会撞到自己的尾巴或墙壁上

资格:

  • 您,组成尾巴,墙壁和收集的碎片的角色都应该是不同的角色
  • 显示带有分数的HUD。每收集一件作品,分数就会提高1分
  • 玩家与自己的尾巴或墙壁碰撞时会失败
  • 一件物品被收集后立即在随机区域产生,更不用说在游戏开始时
  • 游戏的速度并不重要,只要它是一致的
  • “单元格”应该是2x1个字符,因为块字符的高度约为宽度的两倍,可以是1x1,因为2x1很难看,我并没有真正想到
  • 更改方向的键分别为awsd,左,上,下,右
  • 起始方向应始终朝上
  • 您必须显示墙的边缘。分数可能与墙重叠

满足上述条件的最短代码将获胜。创造力的虚构奖励积分


吃蛇不应该长大吗?
停止转动逆时针

嗯?“当您收集一块时,您的'尾巴'会长出来,沿着您所走的路。”所以,是的,蛇长了。
西装外套2012年

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))可以解决问题。
乔纳森·里奇·佩平

相关内容:
轻咬

Answers:


32

JavaScript(553512字节)

链接到可玩版本

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.logconsole.clear),但是它闪烁得太多,所以我将其放入类似于控制台的HTML中。它将与此一起工作:

<pre id=x>

我也首先用2x1单元实现了它,但是看起来比1x1还差。不过那将是一个很小的变化。

使用awsd键盘上的键。

更新:

通过改进尾部搜索并进行了更多处理,我能够将其缩减为512个(恰好为0x200)字节。

现在,当一条棋子在您的尾巴中生成时,您将获得2分(这是一项功能)。当蛇咬自己时,我也修复了重叠部分。


1
美丽!没错,1x1比2x1看起来更好。我真正担心的唯一问题是上下移动的速度快于左右移动,但考虑到约束条件,这样做是可行的。我不太在意控制台中的闪烁(请参阅我的太空入侵者程序,它相当闪烁),但我想纯文本网页也可以!一种忧虑...有什么方法可以重新启动而无需刷新吗?:(
Blazer

不适用于awsd
Neal 2012年

@Blazer这将需要更多13个字符:-/ ...而且您仍然拥有F5键。
复制

@尼尔是的,我使用了箭头键,但现在修复了它。
复制

@copy我想我没有要求
Blazer

21

x86机器码(128字节)

就像我提交的有关生成Mandlebrot分形的文章一样,我为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是一种作弊,因为挑战在于使游戏在ascii控制台或终端(而不是dosbox)中运行。另外,代码golf不应该是源代码,而不是二进制代码吗?
西装外套2012年

7
@Blazer:这就是源代码-我使用十六进制编辑器键入了机器代码-这就是我的l337!;-)仅当您的视频驱动程序在模式13图形上遇到问题时才需要DosBox事情(矿卡可以)。做ascii版本并不难(可能也更小)
Skizz 2012年

当在dosbox下运行时,“ 390字节”版本仅解码为388字节并挂起。看起来好像有些东西在传输中丢失了。:(尽管如此,其他两个版本仍然非常酷!
Ilmari Karonen 2012年

有没有完整版本的代码?(我不会说这种语言)
AL

1
@ n.1:该程序是8086机器代码,即使没有标签名称,您也可以将其加载到调试器(D86)中并按编写的代码查看代码。
Skizz 2014年

6

shell / sh,578个字符

我试图与POSIX兼容(尽可能多地移植并避免bashisms,即使随机数生成器也不需要/ proc)。您可以例如在您的本机终端或通过SSH会话播放它:使用'dash -c ./snake'运行还有一个〜2800字节的未经修改/可读的变体,可以在此处看到。

一些注意事项:shell脚本不适用于编写游戏代码8-)

  • 公平地说,我们仅使用了所谓的“ builtins”,这意味着:
    • 无需外部调用“ clear”,“ stty”或“ tput”之类的程序
    • 因此,我们在每次移动时都会重新绘制整个屏幕
    • 唯一使用的内置命令(又称本地命令)是:
      • 回声,评估,while循环,让,中断,读取,案例,测试,设置,移位,别名,源
  • 没有随机数生成器(PRNG),所以我们必须构建自己的
  • 得到一个按键块,所以我们必须产生另一个线程
    • 为了在父任务中获取事件,我们使用了一个临时文件(丑陋!)
  • 蛇本身就是一个清单,很便宜:
    • 每个元素都是一个(x,y)元组
    • 松开尾巴意味着:将列表移动1
    • 添加(新)头意味着:追加一个字符串
  • 网格在内部是一个数组,但是shell / sh不知道这一点:
    • 我们通过带有全局变量的丑陋的eval调用来“模拟” array(x,y)
  • 最后:我们玩得很开心!
#!/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

是的,因为您咬自己,这就是恕我直言的方式。我们在内部进行了讨论,每个人都对此表示同意。
巴斯蒂安·比托夫

echo -n绝对不是便携式的。如果第一个操作数是-n,或者任何一个操作数包含反斜杠('\')字符,则结果是实现定义的。在没有任何开关的情况下,将回声用于文字文本以外的其他任何东西都是不可移植的。pubs.opengroup.org/onlinepubs/009604599/utilities/echo.html
nyuszika7h 2014年

nyuszika7h:知道如何绕行吗?
巴斯蒂安·比托夫

nyuszika7h:我找到了一种删除主要“ echo -n”呼叫的方法-因此只剩下一个呼叫。它称逃逸序列为“转到起始位置(0,0)”
起始

4

红宝石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

在Windows控制台中以20x40的板子播放。分数显示在面板下方。使用WASD来控制蛇,任何其他键退出(强制!)。在第5行的末尾编辑睡眠时间以控制速度。 (或者保存10个字符,并完全消除睡眠,使其几乎无法播放!)

奖励功能:随机无法启动(在蛇的位置生成初始棋子时)。

我需要约100个字符来解决缺少无阻塞getchar的问题。显然,Ruby 1.9.3包含一个“ io / console”库,该库大约可以节省一半。而且此解决方案是Windows特定的。在* nix系统中,已经发布了解决方案来执行相同类型的操作,但是我尚未测试它们是否可以比较字符数。

编辑:

我意识到尾巴只会在进食后才长出来,而不是在每一步之后才长出来,所以必须增加18个字节。

编辑2 :(可能)修复了崩溃问题,通过限制一个食品项保存了9个字节。


我喜欢一次吃多个食物的想法,但是有一个大问题:尾巴应该随玩家一起移动,每次收集的食物只能增加一个角色。
西装外套2012年

您在我修复它时添加了评论...如果只应该是一条,我可以删除9.times{},节省9个字符。
AShelly 2012年

唯一的要求是一次只能有1个或更多的食物,所以是的,您可以一次只做1个,并保存一些字符
Blazer 2012年

游戏随机以约140点的速度撞向我,不知道为什么。但除此之外非常好
Blazer 2012年

我认为,已修复崩溃问题。如果再次崩溃,请让我知道ruby错误消息。
AShelly 2012年

4

Applesoft Basic-478(462)

这是我第一次打高尔夫球,但是它写于1989年,它主要按照要求实施蛇游戏(但没有食物,蛇就在不断成长,实际上是两个球员,而不是一个人),只使用两行Applesoft基本版。

当时有许多两线节目竞赛,例如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,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很多块可以保存到另一个1字母的本地
变量中

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

重击(字符过多:大约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

屏幕截图

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.