贪吃蛇游戏:历史、玩法策略与计分数学指南

贪吃蛇游戏详解:历史、策略、计分数学,以及我们如何为现代网络重建它

读到这里的几乎每个人都玩过贪吃蛇。在等公交时用诺基亚手机玩过。在一节早已失去意义的课上用图形计算器玩过。在一个本该是电子表格的浏览器标签页里玩过。它是极少数真正跨越世代的电子游戏之一,而且它几乎不向你索取任何东西:四个方向、一条不断变长的线、一块食物。

这种表面上的简单是个陷阱,也正是我们花了这么多时间重建它的原因。贪吃蛇看起来像个新手项目。其实不是。一款手感良好的贪吃蛇——从不吞掉一次指令、从不因为一次执行正确的转向而害死你、从不卡顿、从不因为你屏幕的刷新率而变得更容易或更困难——是一件真正考验功力的工程作品。你在网上找到的大多数版本,至少会在这几点里失手两点。

这篇文章是我们所学一切的详尽版本。它涵盖贪吃蛇的由来、规则的真正含义、我们这个版本背后精确的计分数学、玩得好所需的时序表格、区分 200 分与 2000 分的策略、藏在 21×21 网格里出人意料的计算机科学,以及那些让一个玩具与一件工具产生分野的工程决策。如果你只想把游戏玩得更好,请直接跳到策略部分。如果你想真正理解它,那就从头开始。

贪吃蛇游戏

在你的网站嵌入贪吃蛇游戏的代码:

你刚刚读完了这款游戏的全部架构:让分数在各种屏幕尺寸下都可比较的固定 21×21 网格;三种截然不同的模式(墙壁、传送门,以及带五种轮换布局的迷宫);五档速度,每一档都有自己的加速曲线和下限;带连击倍率、奖励进攻性的计分系统;七秒后过期的金色浆果;每五颗浆果就改变一次局面的升级时刻;以及那些让这个版本感觉灵敏而非仅仅能用的微妙工程决策。你看过策略表格、时序数学,以及关于尾部释放规则为何重要的诚实解释。现在到了实用的部分:把同一个引擎放到你自己的网站上,让你的访客无需离开你的页面就能畅玩。

你可以复制下面的代码并把它嵌入你的网站——放进文章、侧边栏、页脚,或任何你希望访客体验一段专注而讲究策略的游戏时光的地方。游戏完全在浏览器中运行,位于一个隔离容器内,无法读取或触碰周围的页面。没有任何游戏数据被传输、存储或记录。网格计算在本地进行,分数存在访客自己浏览器的存储里,键盘与触摸操作全程无需向服务器往返一次。关闭标签页,整个会话就此蒸发。访客所玩的一切都留在他们那里,而这正是贪吃蛇一贯的运作方式:重要的不是那张网格,而是注视着它的人内心所做的决定。

嵌入代码提供六种界面语言以匹配你的受众:英语 - 西班牙语 - 法语 - 阿拉伯语 - 中文 - 印地语。语言设置控制工具中的标签、按钮与说明,也决定游戏界面以哪种语言显示。游戏本身对世界上每一位访客都是一样的,但它以哪种语言呈现完全取决于访客的选择——在首次访问时从其浏览器自动检测,此后予以记住。对于阿拉伯语,整个版面会切换为从右到左,将界面镜像,让体验显得原生自然。

通过修改网址中的参数来更改界面语言:?lang=zh

可用语言:en - es - fr - ar - zh - hi


1- 隔离式 iFrame 代码(适合文章与页面):

如果你正在发布一篇指南、一份策略分析,或一篇关于游戏设计、压力下决策、最优玩法数学的深度文章——就像你此刻正在读的这一篇——这个方法会把功能完整的游戏直接放进你内容的正文中。隔离式 iFrame 把工具限制在框内,因此你的版面保持整洁,读者无需重新加载页面就能玩上一局。所有功能都会完全按照描述运作:三种模式(墙壁、传送门、迷宫)、五档速度(悠闲、经典、迅捷、狂热,外加一个额外档位)、带连击倍率的计分系统、金色浆果、升级时刻,以及键盘与触摸操作,全都装在你网站上一间小小的、自成一体的房间里。

<iframe data-tooliqo src="https://tools.tooliqo.co/snake-game/?lang=zh" 

title="Tooliqo — snake-game"

  style="width:100%;border:0;height:720px" height="720" loading="lazy" scrolling="no"

  allowfullscreen allow="fullscreen; clipboard-write"></iframe>

<script src="https://tools.tooliqo.co/embed.js" async></script>


2- 灵活脚本(适合侧边栏与模板):

对于侧边栏、页脚或小工具区域,这个更轻量的嵌入方式会按需加载游戏并适配它所在的容器。这是同一个引擎、同样的三种模式、同样的五档速度、同样对六种语言的支持、同样的计分系统、同样的金色浆果、同样的升级机制;只是打包成适合那些 iFrame 可能显得笨重的位置。把它放进你的模板,游戏就会在你想要的地方、在你想要的时候出现。你的访客可以追逐高分、精通迷宫模式,或只是玩上快快一局,全程都不必离开你的网站。

 <div class="tooliqo-tool" data-tool="snake-game" data-lang="zh" 
data-height="720"></div> <script src="https://tools.tooliqo.co/embed.js" async></script>

说明:两种方法加载的是同一款游戏,也就是你刚刚读到其三种模式、五档速度、连击计分、金色浆果、升级时刻与六种语言的那一款。工具会尊重访客设备上的深色模式与减弱动态效果设置。没有水印,没有每日限额,不收集数据。只有游戏,做它该做的事,就在你的网站上。而如果某位访客玩了一局、败给了自己的尾巴、再试一次,并最终打破了自己的纪录,那么这个工具就完成了它被打造出来的使命。剩下的事取决于他,而这一直都是目的所在。

本指南涵盖哪些内容

贪吃蛇的规则,以及它们为何设计得如此精妙

贪吃蛇的完整规则可以用四句话说完。你控制一条由相连格子组成的线。蛇头一次前进一格,从不停下。你可以把它导向上、下、左、右,但绝不能直接向后掉进自己的脖子里。当蛇头够到一块食物,蛇就长一格,另一处会出现一块新食物;当蛇头撞到墙或撞到自己身体的任何部分,这一局就结束。

让这成为伟大设计、而不仅仅是简单设计的,是那条反馈回路。在几乎所有其他街机游戏里,玩得越好,游戏就越容易。而在贪吃蛇里,每一次成功都让下一刻更艰难,因为奖励就是障碍。你三分钟前吃掉的那颗苹果,如今成了要绕开的一堵墙。早期游戏设计中,再没有别的东西能把风险与奖励如此干净利落地压进同一个物体。

这里还有第二处更微妙的设计在起作用。由于蛇从不停下,你无法在游戏世界内部停下来思考。每一秒的犹豫,都是一格你未曾计划的前进移动。因此贪吃蛇并不是一款伪装成解谜的反应游戏;它是一款以固定节奏进行的解谜游戏,而后者要罕见和有趣得多。

最后,贪吃蛇有一条几近完美的技巧曲线。一个完完全全的新手可以存活三十秒、吃掉三颗苹果。一个有经验的玩家可以填满棋盘的三分之一。一个理解几何的玩家,原则上可以填满整个棋盘。这些结果之间的差距完全在于知识与规划,而非硬件、运气或金钱。

贪吃蛇的完整历史:从 Blockade 到现代浏览器

1976 年:Blockade,那个没人称之为贪吃蛇的始祖

这一游戏类型始于 1976 年 11 月的一台名为 Blockade 的街机,由圣迭戈的 Gremlin Industries 开发,Lane Hauck 设计,Ago Kiss 负责编程工作。它是黑白的、双人的,而"蛇"这个词在其中任何地方都没有出现。每位玩家用四个方向按钮操纵屏幕上的一个标记;标记身后会留下一道实心轨迹,先撞上墙或轨迹的一方就是输家。

据说这个点子源于 Hauck 用汇编语言对一个简单概念的试验:一个移动的物体,永远无法重新访问它去过的地方。Gremlin 在 1976 年芝加哥的美国音乐操作员协会展会上展出了它,反响极其热烈——热烈到在 Gremlin 能够大批量交付之前,好几家其他厂商就已经把自己的版本推向了市场。第一款重要的贪吃蛇游戏,在发布之前就被克隆了。

1977 至 1982 年:克隆浪潮与单人贪吃蛇的诞生

Atari 于 1977 年为 Atari 2600 主机发行了 Surround,作为该主机的首发作品之一;Sears 以 Chase 之名销售了同一款游戏。在家用电脑上,一个名为 Worm 的版本于 1978 年出现在 TRS-80 上,由 P. Trefonas 编写,通过 CLOAD 杂志发行,随后又有面向 Commodore PET 和 Apple II 的版本。

决定性的转变发生在 1982 年 12 月,Rock-Ola 发行了 Nibbler。那是这一类型变成我们所认识的这款游戏的时刻。Nibbler 是单人的,有三十二个各异的迷宫,而且至关重要的是,它有食物:蛇之所以变长,是因为你在喂它,而不是因为时间流逝。此后几乎所有贪吃蛇游戏都是 Nibbler 的后代,而非 Blockade 的。

Nibbler 还催生了街机史上最伟大的故事之一。它是第一款配备九位数计分器的街机游戏,这意味着十亿分在理论上是可能的,而 Rock-Ola 会向第一位跑到这个分数的玩家赠送一台免费机器。Tom Asaki 在爱荷华州奥图姆瓦的 Twin Galaxies 街机厅逼近了这一目标,一度达到 7.93 亿分,随后摇杆竟被实际玩坏了。1984 年 1 月,Tim McVey 用一枚硬币玩了四十多个小时,最终以 1,000,042,270 分收场:这是电子游戏史上第一个十亿分。奥图姆瓦市将 1984 年 1 月 28 日定为"Tim McVey 日",使他成为第一位拥有以自己名字命名的市政纪念日的电子游戏玩家。整段传奇后来被记录在纪录片 Man vs Snake 中。

1991 年:贪吃蛇逃进了操作系统

当微软于 1991 年发布 MS-DOS 5.0 时,它内含 QBasic,而 QBasic 附带一个名为 NIBBLES.BAS 的示例程序。对于后来成为程序员的极多数人来说,那是他们读到源代码的第一款游戏。这件事的重要性怎么强调都不为过:贪吃蛇不仅成了一款游戏,更成了那个典范式的"第一个真正的程序",是你为了向自己证明你能构建东西而去构建的那样东西。

大约在同一时期,贪吃蛇在图形计算器上蔓延开来。当时主导课堂的德州仪器机器,恰好有足够的屏幕和足够的处理器来运行它,又没有任何会让更雄心勃勃的东西值得一玩的干扰。

1997 年:诺基亚 6110,以及一款游戏有史以来最庞大的受众

1997 年 12 月,诺基亚推出了 6110,一款商务手机,屏幕仅为 84×48 像素的单色屏。诺基亚的市场团队曾请一位名叫 Taneli Armanto 的软件工程师为它做几个小游戏。他做出了三个:Memory、Logic 和 Snake。

Armanto 是在残酷的约束下进行设计的——两种色调、偏绿的 LCD 屏上的深色像素、用数字键盘代替摇杆,以及一颗毫无余裕的处理器。这些约束恰恰是这款游戏得以流传的原因。没有任何东西可以再拿掉了。据估计,最初的贪吃蛇进入了约 3.5 亿台设备;在 1997 至 2007 年间,诺基亚出货了超过 4 亿台预装该游戏的手机。在千禧年之初的一段时间里,地球上在任何一天玩贪吃蛇的人数,都超过了玩任何其他电子游戏的人数。

Armanto 设计中有一处细节值得被更多人知晓,因为我们借用了它的理念。他刻意在撞毁之前引入了一个极小的延迟——短短几毫秒,在这段时间里一个迟来的指令仍能救你一命。这是一处小小的、充满人性的设计,它悄悄承认玩家是一个拥有神经系统的人类,而非一台状态机。

Snake II 于 2000 年登上诺基亚 3310,这款手机售出了超过 1.26 亿部。它加入了大多数现代版本至今仍在照抄的三项功能:一片环绕式的场地,你从一条边出去就会从对面那条边回来;场内的迷宫障碍;以及有时限、值额外分数的奖励食物。我们的传送门模式、迷宫模式与金色浆果,都是 Snake II 的直系后代,我们乐于这样说。

2016 年起:slither.io 与浏览器时代

2016 年 3 月,一位自学成才的开发者 Steve Howse 为浏览器、iOS 和 Android 发布了 slither.io。他取用贪吃蛇的概念,将其做成大型多人对战,把蛇做成平滑弯曲而非锁死在网格上,并且颠覆了核心规则:当你的头撞上别的玩家时你会死,但你可以自由地与自己交叉。在各大 YouTube 频道的强力推广下,它登顶了应用商店,成为那个夏天访问量最高的网站之一,仅在 Android 上就突破了一亿次下载。

slither.io 证明了关于这一类型的一件要事。贪吃蛇不是一款确定的游戏;它是一种机制——一条不断变长、不得切到任何东西的线——而这种机制能够承载极其多样的设计。经典的网格版本并未消失;它只是变成了那个"典范"版本,是所有浏览器游戏网站、所有搜索引擎彩蛋、所有学编程的教程都会回归的那一个。

时间线一览

贪吃蛇游戏类型历史上的关键里程碑
年份作品或事件平台为何重要
1976Blockade(Gremlin Industries,Lane Hauck 设计)街机创造了会致命的轨迹机制;仅限双人
1977Surround(也以 Chase 之名销售)Atari 2600作为首发作品把概念带进家庭
1978Worm,P. Trefonas 作TRS-80第一个广泛流传的家用电脑版本
1982Nibbler(Rock-Ola)街机单人、靠食物成长、32 个迷宫;真正的范本
1984Tim McVey 在 Nibbler 上跑出 1,000,042,270街机电子游戏史上第一个十亿分
1991NIBBLES.BAS 随 MS-DOS 5.0 中的 QBasic 附送个人电脑成为一代人读到的第一份游戏源代码
1997Snake,Taneli Armanto 作诺基亚 6110约 3.5 亿台设备;开启了手机游戏
2000Snake II诺基亚 3310加入了环绕边界、迷宫与奖励食物
2016slither.io,Steve Howse 作浏览器、iOS、Android大型多人对战的再创造;全球现象级
今天像这款一样的浏览器原生版本任何设备无需安装、无需账号、即时游玩、完整无障碍

我们贪吃蛇游戏的幕后:我们做了什么,以及为什么

我们的版本从零开始,构建成一个自成一体的单一文件,没有外部库、没有网络字体、没有网络请求。这个约束是刻意的。嵌入在文章内部的游戏必须瞬间加载,绝不能拖慢承载它的页面,也绝不能因为某个第三方服务器过得不顺就崩掉。

在视觉上,我们走了一条大多数贪吃蛇游戏不会走的方向。这一类型的默认外观是黑底霓虹绿——一个容易照搬、却难以做得有深度的街机陈词滥调。我们转而构建了一个"生态缸":一片温暖沙色的场地,装在一层深孔雀绿的外壳里,配上一条身躯逐渐收细的翡翠色蛇,它有真正的头、会跟随移动方向的双眼,以及时不时颤动的舌头。食物是一颗带梗、带高光的浆果,而非一个方块。

然而,最大的视觉决策不是颜色,而是移动。在大多数贪吃蛇实现里,蛇会从一格瞬移到另一格,因为渲染器画的正是游戏状态,而游戏状态是一串网格坐标。我们的版本则做了插值:在一次逻辑移动与下一次之间,每一节身体都从它所在之处平滑滑向它将去之处。游戏逻辑仍是严格的网格——这对公平性很重要——但呈现是连续的。这就是原型与成品之间的区别,而它大概只花了三十行代码。

功能概览

工具所包含的内容
领域细节
棋盘在任何屏幕尺寸下都固定为 21 × 21(441 格),让分数保持可比
模式墙壁、传送门、迷宫(五种轮换的迷宫布局)
速度悠闲、经典、迅捷、狂热;每一档都有自己的加速曲线与下限
计分等级奖励、最高五倍的连击倍率、值三倍的金色浆果
纪录为每一种模式与速度的组合分别保存最高分
统计已玩局数、已吃浆果数、最长的蛇、总游玩时间
操作方向键、WASD、AZERTY 键位、屏上方向盘与滑动手势
显示浅色与深色两种主题,真正的全屏,在宽屏上采用双栏布局
语言英语、法语、西班牙语、中文、印地语与支持从右到左的阿拉伯语
音频在浏览器中生成的合成音,默认静音,移动端配有触觉反馈
无障碍可用键盘操作、面向屏幕阅读器的播报、支持减弱动态效果

为什么网格从不改变大小

这是我们争论最多的设计决策,因此值得解释。许多浏览器贪吃蛇游戏会让网格随窗口缩放:更大的屏幕就得到更多格子。这看起来很慷慨。而它实际上并不公平,因为这意味着手机上的 500 分与电脑上的 500 分度量的是不同的游戏。更大的棋盘更容易——腾挪空间更多,在你自己的尾巴变成问题之前的跑道也更长。

我们把网格固定为 21×21,转而缩放格子的大小。在手机上,每一格可能是十六像素;在大显示器上全屏时,每一格可以接近五十。棋盘会占满可用空间,但游戏在任何地方都相同。你的个人纪录在你拥有的每一台设备上都意味着同一件事。

选 21 而非 20 同样是刻意的:奇数的行与列会带来一个真正的中心格,使起始位置对称。而正如我们稍后会看到的,这还有一个相当有趣的数学后果。

完整的计分参考

计分系统中的一切都使用整数运算,这意味着每一个分数都精确可复现,也没有任何浮点意外。以下是整个系统,全部写明。

核心方程

游戏所用的全部公式
方程说明
等级等级 = 1 + ⌊浆果数 ÷ 5⌋浆果自本局开始起计
浆果基础值基础 = 10 + 2 × (等级 − 1)每级增加 2 分,无上限
连击倍率倍率 = min(5, 1 + ⌊连击 ÷ 3⌋)若两颗浆果间隔超过 5 秒,连击清零
所得分数所得 = 基础 × 倍率 × 金色金色浆果为 3,否则为 1
移动间隔步长 = max(下限, 起始 − (等级 − 1) × 递减)两次逻辑移动之间的毫秒数
蛇的速度格/秒 = 1000 ÷ 步长直接由移动间隔换算
穿越棋盘用时秒 = 21 × 步长 ÷ 1000横穿整片棋盘宽度所需的时间
反应距离格 = 反应时间 ÷ 步长你反应时蛇前进了多少
蛇的长度长度 = 3 + 浆果数蛇总是以三格开始

常量一览

支配整个游戏的固定值
常量作用
网格大小21 × 21 = 441 格完整的游戏场地
起始长度3 格头部加两节身体
基础分101 级无连击时一颗浆果的价值
等级奖励每级 +2 分与倍率复合叠加
每级浆果数5每 5 颗浆果,等级升 1
连击窗口5000 毫秒保持连击所允许的两颗浆果间最大间隔
连击步进3 颗浆果每连吃 3 颗,倍率升 1
连击上限×5倍率永不超过五
金色浆果加成×3叠加在连击倍率之上
金色浆果寿命7000 毫秒随后淡出并消失
金色浆果频率每 4 颗浆果仅当棋盘上尚无金色浆果时

等级进程

各等级所需浆果、蛇长与浆果价值
等级已吃浆果蛇长浆果基础值×5 连击时的价值×5 时的金色浆果
10–43–71050150
25–98–121260180
310–1413–171470210
415–1918–221680240
520–2423–271890270
625–2928–3220100300
730–3433–3722110330
835–3938–4224120360
940–4443–4726130390
1045–4948–5228140420
1570–7473–7738190570
2095–9998–10248240720
30145–149148–152683401020

连击倍率

连击是大多数玩家忽视的那部分分数,而它比其余所有部分加起来还值钱。每一颗在前一颗之后五秒内吃下的浆果都会延续你的连击。连击中每第三颗浆果都会把倍率提高一,直到五。

连击链长度与由此产生的倍率
当前连击中的浆果数倍率1 级时浆果价值10 级时浆果价值
第 1 至 3 颗×11028
第 4 至 6 颗×22056
第 7 至 9 颗×33084
第 10 至 12 颗×440112
第 13 颗及以后×550140

完整的每颗浆果得分矩阵

一颗普通浆果的得分,按等级与倍率。金色浆果乘以三。
等级×1×2×3×4×5
11020304050
21224364860
31428425670
41632486480
51836547290
620406080100
722446688110
824487296120
9265278104130
10285684112140

一个来自真实对局的算例

在测试完成的游戏时,我们写了一个自动玩家,它直接从渲染出的画面中读取浆果的位置并朝它前进。在一局记录里,它吃了五颗浆果,最终得分恰好是 70,长度为 8,等级为 2。这个数字值得驻足,因为它在一行之内展示了整个系统。

  1. 浆果 1:1 级,连击第 1 位,倍率 ×1 → 10 分(累计 10)
  2. 浆果 2:1 级,连击第 2 位,倍率 ×1 → 10 分(累计 20)
  3. 浆果 3:1 级,连击第 3 位,倍率 ×1 → 10 分(累计 30)
  4. 浆果 4:1 级,连击第 4 位,倍率 ×2 → 20 分(累计 50)
  5. 浆果 5:1 级,连击第 5 位,倍率 ×2 → 20 分(累计 70),随后等级升到 2

注意第四颗浆果的价值是第一颗的两倍,而棋盘上什么都没变。这就是进攻性玩法的全部策略论据:犹豫不仅浪费时间,还会主动把你的收入清零。

分数标杆与理论最大值

下表显示的是:如果你不建立任何连击,一定数量的浆果值多少分——把它们当作下限,而非目标。一个在大半局里都保持五倍倍率的玩家,会达到这些数字的约五倍。

无连击的分数标杆,以及同一局以最大倍率游玩的结果
已吃浆果蛇长达到等级无连击得分持续 ×5 得分
10133110550
252863501750
5053119504750
10010321290014500
20020341980049000
438(完美一局)441(棋盘填满)8842312211560

最后这一行就是上限。棋盘有 441 格,蛇以 3 格起始,所以完美的一局要吃 438 颗浆果,并以蛇占满每一格告终。到那一刻,等级是 88,每颗浆果在倍率之前值 184 分。没有人做到过。如果你哪天做到了,你纪录面板上的"最长"数字会显示 441,而再也没有可以移动的地方了。

速度、时序与反应窗口

每一个难度设置都由三个数字定义:1 级时两次移动之间的间隔、这个间隔每级缩短多少毫秒,以及它永不低于的下限。

四种难度设置的速度档案
设置起始间隔每级缩短最快间隔达到最高速的等级
悠闲170 毫秒6 毫秒110 毫秒11
经典130 毫秒6 毫秒80 毫秒10
迅捷100 毫秒5 毫秒60 毫秒9
狂热78 毫秒4 毫秒45 毫秒10

各等级的移动间隔

每种难度下、每一等级两次移动之间的毫秒数
等级悠闲经典迅捷狂热
117013010078
21641249574
31581189070
41521128566
51461068062
61401007558
7134947054
8128886550
9122826046
10 及以后116 然后 110806045

把毫秒换算成你能感受到的东西

像"每次移动 80 毫秒"这样的数字,在你把它换算成格每秒和穿越棋盘的用时之前,毫无意义。这张表做了这件事,然后又做了更有用的一件事:它显示在一次典型的人类反应期间,蛇前进了多少。成年人的简单视觉反应时间通常在 200 到 250 毫秒左右。我们采用 250 毫秒作为保守数字。

反应时间为 250 毫秒时的速度换算与反应距离
设置与等级间隔格每秒穿越棋盘用时(秒)你反应时移动的格数
悠闲,1 级170 毫秒5.93.571.5
悠闲,最高速110 毫秒9.12.312.3
经典,1 级130 毫秒7.72.731.9
经典,最高速80 毫秒12.51.683.1
迅捷,1 级100 毫秒10.02.102.5
迅捷,最高速60 毫秒16.71.264.2
狂热,1 级78 毫秒12.81.643.2
狂热,最高速45 毫秒22.20.955.6

请仔细读最后一列,因为它包含了整篇文章最重要的想法。在狂热的最高速下,等到你看见了一个问题并动了手指,蛇已经前进了五格多——棋盘宽度的四分之一。你无法靠反应从一条快速的蛇里脱身。你只能靠规划从中脱身。每一个好玩家实际上都在提前两三秒游玩,而可见的当下只是用来确认计划仍然成立。

金色浆果窗口

一颗金色浆果正好活七秒。你能否够到它,完全取决于你当前的移动间隔。在 21×21 的棋盘上,最坏情况是从一角到另一角的行程,即 40 格的曼哈顿距离。

在金色浆果七秒寿命内可用的移动次数
设置与等级间隔7 秒内可用移动次数最坏情况 40 格——够得到吗?
悠闲,1 级170 毫秒41勉强,需要一条完全畅通的路
悠闲,最高速110 毫秒63从容
经典,1 级130 毫秒53可以,还留有绕行余地
经典,最高速80 毫秒87轻松
迅捷,1 级100 毫秒70轻松
狂热,最高速45 毫秒155几乎总能

这引出了一个相当反直觉的结论:金色浆果在最慢的设置下最难拿到。悠闲让你每次移动有更多思考时间,但在固定的七秒计时里给你的移动次数更少。如果你追逐的是奖励分而非生存,那么经典或迅捷是比悠闲更好的猎场。

以移动次数、而非秒数计的连击窗口

同样的逻辑也适用于五秒的连击窗口,而且效应更强。在 21×21 的棋盘上,任取两格之间的平均曼哈顿距离几乎正好是 14 格,所以这就是从一颗浆果到下一颗的典型行程。

五秒连击窗口实际给你多少次移动
设置与等级间隔5 秒窗口内的移动次数相对 14 格平均行程的余量
悠闲,1 级170 毫秒29约 2.1 倍
经典,1 级130 毫秒38约 2.7 倍
迅捷,1 级100 毫秒50约 3.6 倍
狂热,1 级78 毫秒64约 4.6 倍
狂热,最高速45 毫秒111约 7.9 倍

换句话说,快速的设置不仅更冒险——它们也是最高分所在之处,因为它们让持续的五倍倍率变得现实。悠闲是用来学习的设置。它不是用来创纪录的设置。

三种模式

墙壁

1997 年的原始规则集。边界是实心的;碰它就结束这一局。这是这款游戏最纯粹的版本,如果你想与经典作对比,你的分数就应当在这上面度量。墙壁模式惩罚漂移:由于边缘没有逃生口,周界成了棋盘上最危险的地方,而非最安全的。

传送门

承袭自诺基亚 3310 上的 Snake II。从任何一条边出去,你就会从对面那条边回来。这看似让游戏更容易,而在最初的三十秒里,确实如此。随后它会让游戏难上许多,原因是大多数玩家从不曾说清的:在墙壁模式里,你自己的身体和边界构成一道相连的屏障,因此棋盘有一个简单的内部和外部。在传送门模式里,棋盘在拓扑上是一个环面,你的身体可以绕着它缠一圈,而你把自己困住的那个区域要不明显得多。漫长的传送门对局需要真正的空间想象力。

传送门模式也是理论上最高分可能出现的地方,因为边缘不再是危险,而且每颗浆果都可经由两条路线、而非一条到达——有时绕过去的那条路比直行的那条更短,这对保持连击存活至关重要。

迷宫

五种石块布局会随你升级而轮换,排布每五颗浆果就在你脚下变一次。这些布局是对称且确定的——同一等级总是产生同样的墙——因此它们可以被学习,而不只是被承受。有两条规则保护你:石块绝不会被放在棋盘边缘上,而蛇出生的那一中心行始终保持畅通。

迷宫模式改变了受考验的核心技巧。墙壁与传送门关乎管理你自己身体所消耗的空间。迷宫关乎在时间压力下寻找路径,这远比诺基亚在 1997 年所做的,更接近 Nibbler 在 1982 年所做的。

选择一种模式
模式边缘障碍最适合主要风险
墙壁致命学习并公平地对比分数被卡在边界上
传送门环绕漫长对局与高分弄丢自己所在区域的头绪
迷宫致命五种轮换布局路径规划与多样性棋盘在对局中途改变形状

策略:如何真正把贪吃蛇玩得更好

网上大多数贪吃蛇建议归结起来就是"小心点"和"别撞上"。这里有更有用的东西。它们大致按照在你成长的哪个阶段开始变得重要来排序。

1. 别再追着浆果跑

新手会把蛇直直地导向食物。这在蛇约十格长之前有效,然后就开始害死你,因为一条直接路线为当前这颗浆果作了优化,却忽略了你的尾巴接下来会在哪里。中级玩家会问一个不同的问题:不是"我怎么到那里?",而是"等我到了那里,棋盘会是什么样?"。

这条规则的实用版本很简单。在你投入一条路线之前,先确认存在一条能从浆果所在位置出去的路。在死胡同里吃掉一颗浆果,正是好对局收场的方式。

2. 让你的身体贴着边缘

贪吃蛇里的空间不可互换。散落成一个个口袋的一百个空格一文不值;而位于单一开阔区域里的一百个空格,就是一整局。让你的空闲空间保持成一整块的办法,是让你的身体沿着周界、把中心留空,而不是反过来。一条绕着棋盘外围盘起来的蛇,会留下一个大大的洞。一条在中心游荡的蛇,会把棋盘切成碎片。

3. 学会走"之"字

经典的填充空间模式——有时被称为牛耕式转行,源自希腊语"如牛耕地"——是指走完一整行的长度,下移一行,折回来,再重复。它看起来慢,也确实慢,但它保证你能扫过一个区域里的每一格,且永不切断自己的去路。当一颗浆果出现在远处而你的蛇很长时,走"之"字朝它去,几乎总是比走直线更安全。

4. 跟着你自己的尾巴

如果你实在不知道该怎么办,就去追你自己的尾巴。由于每当蛇头移动,尾巴就退开一格,一条跟着自己尾巴的蛇可以无限存活下去。这是应急招法:当棋盘看起来很糟、你又看不到计划时,排到你尾巴后面,在一颗新浆果出现在更好位置之前争取时间。

5. 理解尾部释放规则

这里有一条大多数实现都处理不当、因而大多数玩家从不学会利用的规则。当蛇移动而没有进食时,尾巴会在蛇头进入新格的同一瞬间离开它的格子。这意味着你尾巴末端当前所占的那一格可以安全进入:等你到那里时,它将是空的。

我们的版本正确地实现了这一点。其结果是,你可以完成一些看似不可能的极紧转向,紧贴自己身后一格跟着自己的身体走。但请注意那个例外:如果你在同一次移动中吃了一颗浆果,蛇就会变长,尾巴不会释放。进食时进入你尾巴的那一格是致命的。有经验的玩家把它内化为"紧转向是安全的,除非路上有食物"。

6. 玩连击,而非玩浆果

鉴于上面的表格,算术是残酷的。一个每八秒吃一颗浆果的悠闲谨慎玩家,会永远以 ×1 计分。而一个每三秒吃一颗的进攻型玩家,在十三颗浆果内就到 ×5,并从那时起每颗浆果多赚五倍。进攻型玩家会更早死。但他也会以数倍之高的分数收场。

实用法则:一颗浆果一出现,就开始朝它移动。别先兜完你当前那一圈。也别等着看它会去哪里:它哪儿也不去。

7. 顺路带走金色浆果,别为它绕道

一颗金色浆果值三颗普通浆果,这很棒,但它出现在一个随机格里,并在七秒后过期。如果它大致在你的路上,就带走它。如果去拿它会打断你在普通浆果上的连击,就放掉它。三倍的一颗浆果,比不上你会失去的那个五倍倍率。

8. 管理好升级时刻

每五颗浆果,游戏就会加速——而在迷宫模式里,墙也会改变。这一刻是任何对局中最危险的时刻。如果你正接近你的第五、第十或第十五颗浆果,务必让自己抵达时前方有开阔空间,而不是身处一个逼仄的角落。

常见错误及其纠正

是什么害死了大多数对局,以及该怎么做
错误它为何害死你纠正
直线冲向每一颗浆果让你的身体散落在棋盘中心沿周界规划路线,只为收取才进入中心
在一次移动间隔内转两次向第二次转向才是实际发生的;第一次被丢弃每次移动一个果断指令,而非一连串敲击
蛇变长时惊慌惊慌产生短视决策,把棋盘弄碎回退到跟着自己尾巴,直到计划浮现
在角落里吃浆果你抵达时只有一个出口,而你的新身体节堵住了它沿着墙、而非垂直于墙地接近角落
为拿高分而玩悠闲每秒移动更少,意味着连击窗口内的移动更少在悠闲上学习,在经典或迅捷上拿分
忽视升级时刻你正处于机动之中,速度却变了数你的浆果;在开阔空间里抵达每第五颗

贪吃蛇的数学

贪吃蛇看起来像一款反应游戏,行为却像一道图论问题。这一节是可选的,但它包含一个关于我们这块具体棋盘的事实,我们在任何地方都没见过它被讨论,而它会改变一局完美对局应当怎么打。

把贪吃蛇看作网格图

把棋盘建模为一张图:每一格是一个顶点,若两格正交相邻,则两个顶点相连。蛇是穿过这张图的一条路径,每回合前进一步,不能掉头,且每当落在食物上就增长一个顶点。几乎所有关于贪吃蛇的有趣问题,都会变成关于网格图中路径与回路的问题。

为什么"只管跟着一条回路走"是标准的完美策略

保证一条蛇永不死亡的最著名办法,是找到一条哈密顿回路——一条恰好访问每一格一次的闭合环——然后就永远跟着它走。由于这条环覆盖每一格,所有食物最终都会落到你前方;由于它是单一的闭合环,而蛇比这条环短,你永远无法撞到自己。这是完美的,也是慢得让人受不了的,但它总能赢。

为什么我们的 21×21 棋盘没有这样一条回路

这就是有趣的部分。把棋盘像棋盘格那样着色。每一次移动都把蛇从一个浅色格带到一个深色格,或反过来,所以任何闭合环都必须交替颜色——这意味着,只有当浅色格的数目等于深色格的数目时,哈密顿回路才可能存在。

在 21×21 的棋盘上,共有 441 格:一种颜色 221 格,另一种 220 格。它们并不相等,也不可能相等,因为 441 是奇数。因此,在我们的棋盘上根本不存在哈密顿回路。经典的"安全环"策略在这里在数学上是不可能的。

存在的是一条哈密顿路径:一条穿过全部 441 格的开放路线。所以完美的一局仍然可能,但它不可能是一条不动脑的环。任何试图填满棋盘的玩家或算法,要么必须在一块 20×21、共 420 格的子区域内作业(它是偶数,确实容许一条回路),并单独处理剩下那一行;要么规划一条开放路径,并在结尾重新定位。这不是我们设计上的意外;这是任何奇数乘奇数尺寸的贪吃蛇棋盘的性质,包括你在网上会找到的许多棋盘。

棋盘的奇偶性与完美闭合环的可能存在
棋盘总格数颜色分布哈密顿回路可能吗?
20 × 20400200 / 200可能
21 × 21(这款游戏)441221 / 220不——只有开放路径
20 × 21 子棋盘420210 / 210可能
任何奇 × 奇棋盘奇数相差一

正式地说,贪吃蛇有多难?

难到足以让计算机科学家为它发表论文。2016 年,Marzio De Biasi 与 Tim Ophelders 在"趣味算法国际会议"上提交了一篇题为《The Complexity of Snake》的论文,后来在 Theoretical Computer Science 上作了扩展。他们证明,判定一条蛇能否在一张填满的网格图上收取全部食物是 NP 困难的,而在一般网格图上,这个问题是 PSPACE 完全的——就和那个更简单的问题一样,即在棋盘上根本没有食物的情况下,判定一条蛇能否从一种构形转移到另一种构形。

简单地说:没有已知的高效算法能把贪吃蛇玩到最优,而且有充分理由相信没有这样的算法。当你觉得某个局面无解时,你也许在客观上是对的。这个问题还吸引了机器人研究者,因为一条不得撞到自己身体的蛇,是蛇形铰接机器人运动规划的一个合理模型。

关于棋盘的一些数字

21×21 游戏场地的几何
总格数441
周界格数80
内部格数361(一块 19 × 19 的区域)
一局开始时的空格数437(441 减去 3 节蛇身与 1 颗浆果)
两格间的最大曼哈顿距离40
任取两格间的平均曼哈顿距离约 14.0
蛇的最大长度441
完美一局中的浆果数438
完美一局中的最终等级88

深入底层:打造一款不欺骗玩家的贪吃蛇

这一节是给开发者的,也是给任何好奇为什么有些浏览器贪吃蛇手感良好、有些却显得廉价的人的。下面每一点都是一个我们要么修复、要么在设计上刻意规避的问题。

用固定时间步长,而非 setInterval

运行一款贪吃蛇的幼稚做法,是用一个定时器来调用移动函数。它看起来有效。而它错在三处:浏览器定时器会漂移,在后台标签页里会被节流,而且这个间隔从不与屏幕刷新对齐,于是动画会卡顿。

正确的做法是一个固定时间步长的累加器。在每一动画帧,测量流逝了多少真实时间,把它加进一个累加器,然后执行这段时间所包含的那么多次逻辑移动。游戏逻辑以精确、相同的增量推进,无论帧率如何;只有绘制跟随屏幕。还有两道防护很重要:给流逝时间设上界,好让后台标签页不会在切回来时把蛇加速撞墙;再给每帧的追赶移动次数设上限,好让一台慢设备不会失控狂奔。

定时方式的比较
方式在 144 Hz 显示器上的表现在后台标签页里的表现公平性
setInterval卡顿;移动时序偏离屏幕时序以不可预测的方式被节流速度因设备而异
每帧一次移动以每秒 144 次移动运行完全停止完全不公平
固定时间步长累加器流畅,且移动节奏精确无误受上界约束,随后干净地恢复在任何地方都相同

输入队列,以及那个害死每一次初次尝试的问题

几乎每一款自制的贪吃蛇都含有同一个致命问题。玩家正向右移动,飞快地按上、再按左,于是这两个输入都在下一次移动之前被应用——蛇便掉头钻进自己的脖子,毫无可见缘由地死去。这是"这游戏坏了"这类抱怨最常见的来源,而它并不是玩家的错。

纠正之道是把输入排进队列,而不是立即应用它们。每一次逻辑移动至多从队列里取用一个方向,并拒绝任何与当前方向恰好相反的方向。玩家可以稍微提前缓冲一个转向——这感觉很灵敏——但永远无法意外地把蛇对折。

精确实现的碰撞

正如策略一节所述,在任何不使蛇变长的移动中,尾巴都会释放它的格子。正确的实现会把蛇头的目标与除最后一节之外的所有身体节比较,除非这是一次进食移动,那时每一节都要计入。任一方向弄错,都会产生一款要么显得不公平地苛刻、要么可疑地宽容的游戏。我们在发布前用自动化测试验证了这一行为。

在离散网格上作插值渲染

逻辑在整数格坐标上运行;绘制在分数位置上运行。在两次移动之间,每一节都被画在它曾在之处与它将去之处的一个混合位置上,权重由我们在当前间隔中推进了多少决定。结果是一条滑动而非跳跃的蛇,而对底层网格的公平性毫无妥协。

有一处微妙之处:在传送门模式里,一节身体可能从棋盘的一条边缠绕到另一条,而对这一过渡作插值会在屏幕上画出一道笔直的拖影。纠正之道是检测任何长于一格的跳跃,此时对齐而非混合,并在该处断开所绘身体的描画。

不靠拒绝采样来放置食物

常见做法是随机挑一格,检查它是否被占用,若被占用就重试。这在开始时运作良好,到后期却变得病态:当蛇几乎填满棋盘时,这个循环可能空转数百次,而如果棋盘被完全填满,它永远不会结束。我们会构建实际空闲格子的列表,并从中均匀地挑选。这在最坏情况下既更快,又可证明会终止。

不破坏它所寄居的页面

一款嵌入的游戏对它的宿主负有义务。我们的游戏绝不注册一个会从页面偷走方向键的全局键盘处理器:只有在你确实与游戏交互期间,输入才被捕获,而一旦你点到别处,它就被释放,并在此过程中暂停。当标签页被隐藏、以及当它因滚动而离开视野时,它都会暂停。它所有的样式都被隔离,好让它不会泄漏进周围的文章,而周围网站的任何东西也无法泄漏进来。

我们在测试中发现的两个真实问题

我们会诚实地说说它们,因为像这样的文章通常会假装开发是毫无摩擦地进行的。在最终测试中,一个自动化浏览器发现了两个手动游玩漏掉的问题。

第一个是变量名冲突:一个新加的、指向棋盘元素的引用,遮蔽了同名的渲染循环函数,于是悄无声息地令整个游戏失效。它抛出一条控制台错误,然后什么都不动。这个教训并不光彩,却是普适的:给东西起名要小心,并且要运行你发布出去的那份东西。

第二个更微妙,也更有教益。为了给棋盘定尺寸,我们去测量的,正是我们在设定其宽度的那个元素,这制造出一条反馈回路:棋盘可以收缩,却永远无法再变大。纠正是结构性的:一个元素测量可用空间,且从不被设定尺寸;它内部一个单独的元素才是棋盘,并以像素来定尺寸。如果你从这篇文章里只记住一条架构思想,那就让它是这一条:永远不要去测量一个你自己在控制其尺寸的盒子。

语言、无障碍,以及在任何屏幕上游玩

游戏以六种语言提供,英语为源语言。它会按以下顺序检查来自动检测正确的那一种:页面地址中的一个显式语言参数、游戏元素本身上的一个属性、页面所声明的语言、页面社交元数据中的地区设置、内容的语言声明,以及最后浏览器自己的偏好。如果这些都没能给出一种受支持的语言,它就退回到英语。你随时可以用角落里的选择器覆盖这个结果。

受支持的语言
语言代码该语言中的标题文字方向
英语enSnake从左到右
法语frSnake从左到右
西班牙语esSnake从左到右
中文zh贪吃蛇从左到右
印地语hiस्नेक从左到右
阿拉伯语arلعبة الثعبان从右到左

阿拉伯语会把整个界面切换为从右到左,但有一个刻意的例外:方向盘保持它的物理排布,因为在游戏手柄上,"左"就意味着屏幕上的左,无论你用哪种语言阅读。

在无障碍方面,游戏完全可用键盘操作,每一个操作都是一个带恰当标签的真正按钮,而分数变化与一局结束都会通过一个活动区域向屏幕阅读器播报。如果你的系统被设为减弱动态效果,那么装饰性动画、撞毁抖动与脉动效果都会被关闭,而游戏本身保持完好。

在响应式方面,版面会适配游戏的宽度,而非浏览器的宽度——这很重要,因为一款嵌入在狭窄文章栏里的游戏,即便在一台大显示器上,也应当表现得像一款狭窄的游戏。在横向屏幕上全屏时,它会切换为双栏布局,棋盘在一侧、操作在另一侧,而棋盘可以增大到超过一千像素宽。

完整操作参考

游戏接受的每一种输入
输入动作说明
方向键转向标准布局
W、A、S、D转向用于 QWERTY 键盘
Z、Q、S、D转向用于 AZERTY 键盘
空格暂停或继续也可从标题画面开始一局
R重开立即开始新的一局
F全屏开启与关闭
M静音声音默认为静音
Enter确认激活当前卡片的按钮
Esc退出全屏浏览器的标准行为
在棋盘上滑动转向连续滑动无需抬指即可识别
轻触棋盘开始或继续就像往街机里投一枚硬币
屏上方向盘转向在触摸设备上自动出现

常见问题

谁发明了贪吃蛇游戏?

没有任何一个人独自发明,而这正是这个问题不断得到不同答案的原因。这套机制由 Lane Hauck 在 Gremlin Industries 为 1976 年的街机 Blockade 创造。我们如今称为贪吃蛇的那种单人、吃食物的形式,由 Rock-Ola 的 Nibbler 在 1982 年确立。让它闻名全球的那个版本,由 Taneli Armanto 在诺基亚为 1997 年的 6110 编写。这三个答案都站得住脚;它们是对不同问题的回答。

这款游戏里可能的最高分是多少?

211560,通过吃掉全部 438 颗可用浆果、同时自始至终保持五倍倍率、并无视金色浆果达成。实际上,金色浆果会把一局理论上完美的对局推得更高。一局非常出色的人类对局在经典模式下通常落在 2000 到 10000 之间的某处。

游戏会永远加速吗?

不会。每一种难度都有下限。经典模式在 10 级达到每次移动 80 毫秒的最小值,此后不再更快;狂热模式的最小值是 45 毫秒。此后到来的一切之所以更难,纯粹是因为你的蛇更长了,而这是诚实的那种难度。

更长的蛇值更多分吗?

间接地值。长度本身不计分,但长度跟随已吃浆果,已吃浆果决定你的等级,而等级会把此后每颗浆果的基础值抬高两分。至于倍率,则与长度毫无关系:它纯粹关乎你吃得有多快。

为什么我在悠闲上的分数比在经典上低?

因为连击窗口是以秒、而非以移动次数来度量的。更慢的蛇在五秒内覆盖的地面更少,所以连击链断得更频繁。悠闲更容易存活,也更难拿分。这几乎让所有人都感到意外。

我的分数与统计会被发送到某处吗?

不会。一切——各模式的最高分、已玩局数、已吃浆果、最长的蛇、总时间——都存储在你自己的浏览器本地。没有账号、没有服务器、没有排行榜,也没有追踪。清除你浏览器的数据会清掉你的纪录,而纪录面板上的重置按钮也刻意做同样的事。

我能在手机上用键盘玩,或在笔记本上用触摸玩吗?

两者都能。方向盘会在触摸设备上自动出现,但只要连着一个键盘,键盘就保持有效,而带触摸屏的笔记本可以在棋盘上滑动。

为什么我点击页面别处时游戏会暂停?

这是刻意的。一款在你已转去阅读文章之后仍继续消耗你方向键的嵌入游戏,是一种滋扰。当你与游戏之外的东西交互时,游戏会释放键盘并暂停,好让你不会回到一条死掉的蛇跟前。

变强最快的办法是什么?

在墙壁模式下用经典速度玩二十局,并在每一局里强迫自己沿周界、而非穿中心地规划路线。这会感觉更慢,你最初的分数也会下降。到第十局时,它们会比之前更高,因为你已经不再把棋盘弄碎了。

术语表

本文以及更广泛的贪吃蛇社区中所用的术语
术语含义
刻(Tick)蛇的一次逻辑移动,向前一格
移动间隔两刻之间以毫秒计的时间
固定时间步长以精确、相同的时间增量运行游戏逻辑,无论帧率如何
插值把一节身体画在它上一格与当前格之间的中途处,以获得流畅移动
输入队列一小段待处理转向变更的缓冲,每刻取用一个
尾部释放那条规则:在任何不是进食的移动中,最后一节都离开它的格子
连击链在五秒窗口内接连吃下的浆果
传送门或环绕模式一片场地,从一条边出去会把你从对面那条边带回来
网格图顶点为网格格子、边连接相邻格子的图
哈密顿回路恰好访问每一格一次的闭合路线
哈密顿路径恰好访问每一格一次的开放路线
牛耕式转行(Boustrophedon)一种来回扫掠的模式,填满一个区域而不困住自己
曼哈顿距离两格之间水平步数加垂直步数之和
NP 困难至少与那些可在多项式时间内验证的最难问题一样难
PSPACE 完全可用多项式量级内存求解的最难问题之列

我们为何仍在打造这样的东西

这篇文章有一个以怀旧作结的版本,而它不会是错的。贪吃蛇在这个十年里满五十岁。极多数人都有一段与它相连的具体记忆:一部具体的手机、一间具体的教室、一块具体的偏绿屏幕。

但怀旧并不是这款游戏至今仍值得被好好打造的原因。贪吃蛇之所以留存,是因为它是极少数规则完全可见、而深度完全隐藏的游戏之一。没有任何东西对你隐瞒。没有解锁,没有元进程,没有一项没给你看过的统计。抵达一局完美对局所需的一切,从第一秒起就在屏幕上——而你依然做不到,因为难度从来不在信息里,它在规划里。

这是一种罕见而诚实的游戏设计,它值得一个固定时间步长、一条正确的碰撞规则、一个尊重玩家的输入队列,以及一条滑动而非跳跃的蛇所付出的努力。这篇文章里的一切——每一张表、每一个公式、每一毫秒——之所以存在,是为了让你在输的时候,知道是你的决定输了。

现在,去在经典模式里突破 2000 分吧。沿着边缘规划路线。别为金色浆果停下来。

َAdmin
Written by َAdmin

As a digital content enthusiast, I dedicate myself to sharing my personal insights and documenting the knowledge I gain from the web. My goal is to create valuable, purpose-driven content that informs, inspires, and delivers real benefits to others.

ON
enabled: true page: /p/redirect.html protect: true in_post: true new_tab: true delay: 5
enabled: true shape: solid scope: standalone
enabled: true title: Rate this article