本文转载自公众号“把科学带回家”(ID:steamforkids)

作者 七君

玩过吃豆人吧。通关过吗?

通关是不可能的,这辈子都不可能的。因为吃豆人根本不可能通关。

不可能通关的秘密,都藏在最后一关里。

吃豆人的最后一关,第256关吧,是不可解的。

基本上,你玩到这一关,就会看到这样的东西——

你没有注意到这个问题,可能是你平时太爱学习了。有些有编程经验的小朋友可能会马上反应过来,是不是256这个数字有问题啊?

的确,这个问题和256有关,不过不是你想的这种关系。

是这样的,在吃豆人游戏刚出来的时候,也就是80年代的时候,大多数微芯片的处理器是8位的。

计算机是2进制的,所以1就是1,2就是10,3就是11,4就是100,以此类推。

8位的意思是,处理器有8个“格子”,每个“格子”只能表示0或1,最多能表示8位的二进制数字。

所以,它能显示的最大数字就是二进制的 1111 1111,也就是十进制的255。

那么此时我让它再加1会发生什么事呢?

因为最多只有8位,不能进1位变成9位,所以处理器就会变成0000 0000,也就是0。这就是整数溢出了。换言之,在8位处理器里,能够表达的最大的数字是255。

可是,吃豆人的死忠粉把它的源代码调了出来,他们发现问题不在于关数上,而是出在了显示的过程中。

是这样的,吃豆人的程序员利用了0来表示第1关,所以第一关的代码实际上是0,第二关是1,第三关是2,…,所以第256关的代码实际上是255,并没有发生整数溢出的问题。

但是,水果有问题。

吃豆人的源代码显示,当初那个程序员可能是最早意识到枸杞保温杯不加班,胜过可乐加冰又加薪的程序员之一。

TA想要在每一关的底部画水果,用水果的个数和种类代表关数。

具体来说,第一关解锁的水果是樱桃,所以第一关底部是1个樱桃。

第二关解锁的草莓,底部是1个樱桃+1个草莓。

第三关和第四关是桃子,第3关的底部是1个樱桃+1个草莓+1个桃子;第4关的底部是1个樱桃+1个草莓+2个桃子。

5和6是苹果,7和8是蜜瓜,9和10是星际战舰,11和12是铃铛,13关及以上是钥匙。

在第7关及以下,显示过去所有关卡解锁的所有水果。

到了第8关及以上,显示的是最近7关获得的手办。

总之这些水果和手办的作用就是显摆你通的关多,不能吃也不能拿来+1up命。

那么,这位养生系的程序员是怎么挑选水果的呢?

TA把所有关卡能够解锁的水果还有手办做成了一个这样的包含20个项目的表格,储存在内存里。

然后在每一关一开始,养生程序员是这样设定的:

查看一下本关关数代码 A。我们刚才说过,第1关的二进制代码是0000 0000,第2关是0000 0001,第256关是1111 1111。

好,把 A+1,变成真正的关卡数 L。

判断一下 L 是否小于8。

如果答案为是,则从水果表格的第1个画到第 L 个为止。

如果答案为否,则从表格的第L-6个画到第 L 个为止(从第19关开始画7把钥匙)。

所以呢,第1关就从表格的第1个画到第1个,也就是画1个水果就可以了。第2关就画2个水果。

那么第256关呢?

第256关储存的代码,也就是A是1111 1111。但是要把 A 加1变成 L 的时候,就出问题了,因为此时就会产生整数溢出的问题,L 变成了0。

既然第256关的 L 是0,所以机器判断,要从水果表格的第1个画到...第0个...

这可怎么画?

实际上,画水果的程序具体是这样的执行的:

先从第一个水果开始画,画好一个+1得到 F,F 再和 L 对比一下。

如果 F = L,就停止不画了。

所以,如果 F = 0,要画多少个水果呢?

其实很简单,因为 F 也会发生整数溢出问题,所以画到256,F 也变成0了。因此在第256关,画256个水果就刚好了。

可是我们还记得,记录水果的表格只有20个项目,没有256这么多啊。那怎么办?

原来,水果表格被储存在内存的$3B08这个地方,往后的数据是背景音乐什么的。

表格里的水果和手办画完以后,机器就开始画内存后面储存的东西,所以画出来的东西就是乱七八糟的,这就好比计算机把它脑子里的胡话全部打印到屏幕上一样。

这就导致,吃豆人在256关吃不完所有的豆子,因为一部分豆子没有显示出来。因为没有办法吃掉所有的豆子,所以这关是永远过不了的。

玩家会在这一关兜兜转转,直到有社恐的圆脸小黄人被四色小妖怪逼到墙角摸来摸去最后摸死了,喵的咪的。

2010年5月21日的谷歌涂鸦就还原了这个梗,玩到第255关结束,屏幕上就会跳出“Game Over”。

也因为第256关永远过不了,所以吃豆人也有了官方认证的理论最高分——3333360。

第一个拿下这个分数的,是一位叫做 Billy L Mitchell 的选手,记录创建时间为1999年7月3日。

比利同志也被吃豆人的制作方——南梦宫创始人中村雅哉颁发了“世纪玩家”的头衔。

南梦宫创始人中村雅哉(左男)和 Billy L Mitchell(右男)

比利小哥为什么能拿满分?人家的手速为1秒的160分之一。拥有这个手速是什么样的体验,大家可以自行感受一下——

Billy L Mitchell 的手速为1/160秒

@greatbigstories

顺便说一句,其实当时程序员可以在内存里分配更多的空间来储存关卡数(关卡的计数器),你看总分就被分配了21位,所以可以计到3百万嘛。

那么这位养生程序员为什么没有这么做呢?大概TA根本瞧不起碳基生物的手速,认为正常人类不可能打到256关吧,毕竟比利发现第256关秘密的那年,离吃豆人首发已经过去了整整19年。

实际上,比利小哥后来在接受采访时表示,南梦宫是收到了他发过去的截图后,才知道原来自家游戏的第256关长这样。原来你们不仅瞧不起游戏宅的手速,还根本就没有debug过啊,坟蛋!

(╯‵□′)╯︵┴─┴.

其实,不光吃豆人的第256关有整数溢出问题,我们还可以用整数溢出问题的设定去吓唬里面那个粉红色的小鬼Pinky。

在官方设定里,Pinky 会走到吃豆人前方埋伏玩家,所以 Pinky 的官方的名称叫做“埋伏者”。

从源代码来看,Pinky 的设定是走到吃豆人前方16个像素,也即是2个身位的地方伏击它。

可是 Pinky 也会遇到整数溢出的问题。如果吃豆人朝上,Pinky 就会走到吃豆人左边4个身位+上方4个身位的地方。而且,因为 Pinky 的设定是走在吃豆人前面伏击,所以如果吃豆人向着它跑,它就会逃走。

利用这一点,就可以调戏 Pinky 了。

你大概觉得整数溢出问题只存在于二维世界。但实际上,整数溢出问题也存在于三维世界。

比如...在瑞士,法律规定火车不能有256根车轴。

为什么呢?

因为瑞士联邦铁路(SBB)使用的计轴器,就是在铁路上计算经过的火车的车轴数量的仪器也是8位的,它记到了256就会溢出变成0。

0轴就是没有火车通过,所以这个傻乎乎的计轴器就会报告明明有256根车轴的小火车不存在。emmm,原本开往幼儿园的车可能就会开往天堂。

计轴器

@wikipedia

总之,在机器寿命大大超过人均寿命的瑞士,大家并不想换计轴器,那就干脆立法规定不允许火车有256根车轴好了,棒呆!(๑•̀ㅂ•́)و✧

瑞士联邦铁路规定,火车不能有256根车轴。从2012年7月1日开始执行。

图片来源:Ausführungsbestimmungen zu den, Fahrdienstvorschriften, AB FDV Infrastruktur, Neuausgabe

看完吃豆人的故事我们明白,如果你觉得生活欺骗了你,生活中充满了bug永远也看不到获胜的希望,可能是这个宇宙的程序员没有料到你这么能打,还能来到这个关卡吧。恭喜你啦!

无标注图片来自网络。

参考资料储存于石墨:

https://shimo.im/docs/G0G7AGXzqiYuDOuI/

来源:把科学带回家

编辑:Major Tom

近期热门文章Top10

↓ 点击标题即可查看 ↓

1. 为什么品客薯片不容易碎,但乐事薯片容易碎?

2. 学物理能做什么?

3. 听说高考数学全国卷三考了朵云……

4. 6÷2(1+2) 到底等于 1 还是 9?

5. 可达鸭为啥脑壳痛?

6. 两千多度时,冰变成了黑色

7. 4.6692……:一个比圆周率更神秘的常数

8. 人类突然消失之后,世界会变成什么样子?

9. 为什么洗澡水砸不死蚊子?

10. 中国哪里的地铁最拥挤

点此查看以往全部热门文章

java吃豆人代码讲解_在吃豆人的这一关里,隐藏着来自程序员的深深恶意相关推荐

  1. 程序员python代码打招呼方式_某编程少年说他是Python大神,神级程序员不用一行代码教他做人!...

    听君一席话,胜读十年书. 1.扎实的python基础 个人的技术基础知识是否扎实,决定了个人是否能够做的工作层次. 比如某些Python半吊子,只能够纸上谈兵,和Python小白谈谈人生理想,而只要涉 ...

  2. 什么样性格的人适合科研_什么性格的人更容易得癌症?科学研究这么看

    除了少数已知的致癌因素(例如抽烟诱发肺癌.嚼槟榔诱发口腔癌)外,大部分癌症的原因仍不清楚. 但当一个人得了癌症后,周遭的人常会感叹:"这样的好人怎么得癌症?"接着还是讨论是否患者工 ...

  3. 年增代码 12.9 亿行,每天完成需求近 4000 个,鹅厂程序员秘密大爆料!

    整理 | 伍杏玲 出品 | 程序人生(ID:coder_life) 封图 | 程序人生付费下载于视觉中国 2019年,腾讯员工两次以"壕无人性"喜提热搜:网友根据腾讯第一季财报算出 ...

  4. 一个代码托管平台居然公开拒招中国人,谁给了你歧视中国程序员的勇气?

    今天,有不少人吃了一个"代码界"的瓜. 由谷歌投资的全球第二大开源代码托管平台GitLab(第一大是GitHub)在其官网上发布了一项声明,称他们决定为有权访问客户数据的团队成员启 ...

  5. tail怎么写中文_为什么不能用中文进行编程,而英文却可以?程序员的分析很透彻...

    很多人都认为程序员很厉害,而且心中对他们有一丝敬佩,那这么复杂的程序,他么究竟是怎么写出来的呢?不知道大家有没有注意一个细节,那就是编程都是英文,如果用中文去编译的话,那就是出现很多"bug ...

  6. 如何避免自己写的代码成为别人眼中的一坨屎 (摘自微信公众号,顶级程序员)...

    从微信公众号上读到一篇文章,记录下来提醒自己也分享给大家~ 一.注释 不要给不好的名字加注释,一个好的名字比好的注释更重要: 不要"拐杖注释",好代码 > 坏代码 + 好注释 ...

  7. 程序员口中的demo是什么意思_怎样让5分钟的曲子不重样播放450天?程序员:用马尔可夫链...

    乾明 发自 凹非寺 量子位 报道 | 公众号 QbitAI 程序员要是喜欢上一个东西,指不定会搞出什么"疯狂"事情来. 今天要说的,是特别喜欢一首曲子的程序员贝特(Alex Bai ...

  8. 苹果挂端口方法_苹果新系统遭吐槽!SSH 默认规则被破坏,程序员无法登录 Web 服务器......

    公众号关注 "GitHubDaily"设为 "星标",每天带你逛 GitHub!转自量子位苹果电脑最新的 10.15.4 系统,你更新了吗?如果你不幸升级,而且 ...

  9. 前端页面加水印插件_没用过这7款浏览器插件,你一定是假的程序员

    谷歌Chrome浏览器,几乎是每个程序员必备的浏览器,除了速度快之外,还有非常丰富的插件可以使用,今天我们来细数程序员最常用的7大插件,可以极大地提升你的效率. 1.AdBlock,必备神器,全球超过 ...

最新文章

  1. SQL获取刚插入的记录的自动增长列ID的值
  2. Python程序开发——Python实现可增删改查的员工管理系统
  3. python 二维数组长度_谈一谈多维数组
  4. linux系统上手工建库步骤,Linux下Oracle手工建库过程
  5. android语音识别
  6. Knockout应用开发指南 第二章:监控属性(Observables)
  7. STM32F103使用硬件i2c作为从机模式
  8. 反向题在测试问卷信效度_关于调查问卷的信度和效度检验
  9. Verilog 锁存器 触发器 寄存器区别
  10. 谷歌生物医学专用翻译_翻译软件的六大测评,请专家来支招
  11. erp系统服务器电脑配置,erp软件服务器电脑配置
  12. 图形 1.3 纹理的秘密
  13. BASH SHELL ls -l 输出了什么
  14. 【读论文】一种半监督文本分类方法:MixText
  15. 小程序账号注册完整流程
  16. IVX低代码平台——小程序微信红包的应用的做法
  17. k-means像素聚类
  18. android,手机 遥控,
  19. 计算机文化基础期末考试复习
  20. 给你100万条数据的一张表,你将如何查询优化?

热门文章

  1. 51单片机8X8点阵滚动显示温度--C51源代码
  2. linux shell学习(一)第一个hello world
  3. koa2 mysql_koa2+vue+mysql 全栈开发记录
  4. Python:isinstance()和type()
  5. jquery easyUi的学习笔记{一头扎进EasyUI}
  6. List列表的万能的适配器
  7. vb程序和python哪个简单_vb能配合python写程序么?
  8. html仿命令行界面,HTML仿命令行界面具体实现
  9. 为什么手机上传图片这么慢 前端_解决BootStrap Fileinput手机图片上传显示旋转问题_心病_前端开发者...
  10. Blazor服务器应用程序中使用EF Core的多租户