SHENZHEN I/O 深圳 I/O 全关卡详细攻略带讲解(个人渣解)

废话

20250727:

这游戏买了也是很久了,当时还是刚用steam,买的最早的几个游戏。在那之后,一般是出去只有老笔记本/新笔记本为了续航只能开核显时,不时的玩一玩。挺好玩的。不知不觉的就玩了160h。前几天把主线打完了,bonus在搞。水团Finale live两日现地了,之前的个人目标基本都是完成了。想着暑假再自己搞点有意义的东西,不如整个带点思路的游戏攻略,顺便优化一下之前的关卡,维护维护AFO后几年没动的博客。写这些废话,顺便也当剧透保护了。

20250801:

挺感谢自己写写这个攻略的。写攻略给自己了一个动力把前面的关卡优化一下,相当于多玩了10块钱的(

20250829:

这几天摸了,打了几天图灵完备和星际拓荒,图灵完备写汇编累了换换这个游戏,继续更

20250831:

把最后几关给通了,最后剧情挺难绷,不过这游戏还是玩编程解题的。之后想打SHENZHEN I/O的时候就多考虑更新一下攻略。

游玩须知

  1. RTFM。Read The Fucking Manual。相信不需要多解释。基础的语法,元件功能,全在这里面。不算特别难懂,不过不少语法糖(?)没写

  2. RTFI。Read The Fucking "Information"。打开关卡后,下面的“信息”页面相当于题面。很不幸,有的时候题面描述的不够清楚,可能需要你去上面的manual里找一些补充信息。有的时候你还得看下面的“确认”界面(相当于样例)去搞明白。读错题目最烦了!一定不要读错题目!

  3. 多做实验。搞不明白手册讲的什么意思的时候,可以自己开个设计试一下,理解透彻。有的时候有一些省代码行的语法规则也需要自己探索。下面会总结一些:(待更)算了我每个关卡用到的地方再说,总结以后再说罢(池沼)

  4. 有些题目数据不够强,或者有隐藏的数据限制,可以利用来骗分出奇迹

攻略说明

  1. 本攻略指着不剧透、不超纲的原则,希望第一次玩的新手也能搞明白。因此,某些秘密指令/高级元器件在解锁之前不会被使用,或者提供多种解答,其中包括新手初见可明白的解答。

  2. 攻略中每一关标题为对应关卡邮件的标题。

  3. 每种解答的成绩都会以【3/60/12】的方式表示,即成本3元,电量使用60,12行代码。我个人游玩时一般追求最低成本,其次是电量使用。代码行基本没做过优化。

  4. 将鼠标悬浮在每个小标题上,旁边的图标可以快速跳转每一个关卡。不建议提前看后面的解答。

  5. 本攻略所有解答均为个人自解,并不一定是某一方面的最优解!

  6. 为了塞进洛谷图床的不占用大小的免费图床,有的关卡裁剪了一部分。

  7. 一般个人习惯e作为结尾的跳转符(end),l作为循环的跳转符(loop)。

  8. 解答尽量不出现电线下穿芯片的情况,如有会额外给一张电线图。


(模拟)安全摄像头

hint:这一关邮件里所谓的“随机闪烁”,其实就是按照一定规律闪烁。可以自己看“确认”面板里的结果找到规律(其实“信息”面板里面也写的显示一组重复的固定信号)。其他的不难,自己看说明书,还有前任的幽默代码就能写得出来。

这一关以及后面几关可以用后面的秘密指令减少代码行。这里不做介绍,相信玩到一定程度时自己就懂了。

【6/60/12】

第一关

工厂模型替换件

没啥好说的

【3/240/4】

第二关

玩一下游戏吧(纸牌游戏)

这个游戏最杀时间的关卡,不会写代码就打这个,赢100次这个的成就比过主线的成就达成率还高

提示按钮里有基本的规则。这里给一些游玩的技巧:

  1. 尽可能的尽早把一种4个的同牌移上去,不然挡着很麻烦。

  2. 搞上去一组同牌后,一般也能搞出一两个底下的空位。利用好这些空位。

  3. 擅长重开。这个纸牌不一定每一次都有解。看到做不下去了可以直接重开。

脉冲发生器

【3/142/5】

第三关

发光标志

【11/202/21】个人初解(适合新手)

【9/211/23】新手最廉价方法(?)

新手版无需说明。这一关就会发现对于这种多个简单输入/输出的问题,瓶颈在于简单输入口不够的问题上。这时候就可以尝试使用DX300,一块钱换3个简单输入输出。

【7/172/14】个人优化版

【8/125/12】个人优化版(专精电量)

容易发现点击0点击1输出始终互反,用一个非门来进行输出,可以减少不少行数从而减少电量。

【8/126/9】个人优化版(专精行数)

就是上一个方法,使用gen来进行控制。但是这样相当于多进行了一行代码,所以电量比上一个多1。

【6/464/13】20250801优化(最低成本)

想办法把【7/172/14】中的两个MC4000换成一个MC6000。问题在于两个动作周期不同,所以得考虑按每个时刻来进行输出。首先是三个喝的动作。我们发现喝的动作周期为10,可以每一个时刻add 1然后用dgt 0来对10取模,再用一系列判断选择出该向DX300输出什么。然后两个点击动作我们利用dat,每个时刻切换dat里的0或者100然后进行输出。

海量男爵!!

提示:减完小于0的时候就给他变回0就行。

【3/268/8】

【5/237/12】

垃圾音频装置

【6/465/11】

(无视上面的垃圾话,小孩子不懂事注释写着玩的)

【6/490/10】

发现这个的成本瓶颈还是在简单输入输出上。依然可以用DX300简化。

【4/285/7】最优解

被动红外感应器

DX300相信已经是不陌生了。简单输入/输出只有0或100时很好的廉价扩充。后面默认都会DX300了。

【6/351/9】

虚拟现实设备报警器

【5/257/13】正常解法(没有优化)

这道题数据较弱,0、1都是交替出现的,所以可以像下面这样乱搞(

【3/146/7】

为新创意建模

可惜我没有创意 😦

帮个小忙?

这题ab一共四个状态对应4个数字,眼尖的可以发现ba状态对应的结果跟二进制很像。若a为100则1的这一位为1反之为0,b为100则2的这意味为1反之为0。可以用dx300来把这个状态转化为十进制的数,再用dgt指令拆位,算出二进制后的结果。最后就是搬运结果了。

【6/260/12】

IT人生-触杀,你完蛋了!

这一关4个简单输入2个简单输出,用DX300可以解决很多问题。而且这一关你的上司都告诉你要用DX300了。你还不用?

首先击中-复活这一对肯定要用同一个DX300进行输入。然后你发现你不太好存储当前是否存活:有可能就是刚好多了几行,一个大芯片放不下。然后你发现既然你输出的东西就有你当前时刻是否存活,而你的存活只跟你是否能不能开枪有关,那你只要把存活状态也作为输入,同装弹、扳机一起用DX300处理即可。这个的代码打的比较鬼畜,能看懂是无用的标行号就行。DX300转简单输入为xbus输入的时候,合理的选择每一个简单输入代表的位数,可以有效减少进行判断的次数。我这个通过添弹放百位(最大,好判断),而且数据也没有换弹同时开枪的情况,从而实现只用判断大于99(有百位)就直接只做换弹的操作。

【7/321/14】

欸我草原来博客园有图床的,还不限量?

超酷老爸!!!!

这题不好用DX300,因为他简单输出不是只有0或100。直接用一个额外的MC4000来当作xbus转简单输出。

图片省略了LED右半部分,反正不影响理解。

【8/230/14】初见做法

事实上由于数据输出会被打断的情况只有时间设为999的情况(一开始只是乱搞来着没想到直接过了……),所以特判一下,其他时候直接slp对应时刻数就直接过去了……有点离谱的。正常做就直接acc存时间然后每时间跳到头就行了

【6/262/17】作于20250728

鉴于上面一个方案下面的芯片代码行数太少,我们让计时和唤醒另一芯片的功能由下面的芯片完成,同时让上面的芯片完成两个输出。这里用了两个语法技巧。一是nop耗点,在下面的注释里面写了不少,本质就是XBus数据包被两个地方同时读取的话,被哪个芯片读取到是随机的,为了确定一个顺序,我们让其中一个芯片多执行一行代码,晚点读取,这样保证顺序。第二个就是一次清空两个简单输出,即上面芯片的mov p0 p1。由于p0导线的输出也是由这个芯片完成的,所以当这个芯片转而从他输出的p0导线这里输入东西,p0的输出清零,此时读取的值也是0,自然mov p0 p1p1也变成0,如此省下两行。

设备2A27

这一关需要掌握嵌套判断的语法。掌握了就不难。不难发现这一关最少也要两个芯片(否则没有足够的简单输入输出口,输入输出不只是0和100没法用DX300),把两个芯片的负担尽可能均摊,才能省下代码行数让两个芯片都只用小芯片就行了。

【6/794/15】

三国铜币

这一关你已经从上一封邮件知道了“秘密指令”gen@,后面就会使用这两个命令了。用DX300把三个钱币输入打包成一个XBus没什么好说的。然后模拟判断

【11/386/22】初见版

【9/373/21】作于20250803

真挺想不到的,在后面某关为了过关想压缩代码行的手法,阴差阳错的能用在这里了(结果那边反而没用上……)。优化原理就是利用代码到头自动回到开始这一操作,代替一个循环jmp那一行。不过条件挺严苛的,毕竟要把程序其他部分装在一个判断的分支(+或者-)上,后面那关就是因此搞不成的。

【三明治合成器??】

依然是用DX300扩充输出。

【6/84/14】

注意这个断开的+。这个游戏在进行类似teq之类的判断后,相当于给你发了一个“通行证”,在遇到下一个判断之前,根据判断结果,所有前面带+或者-的都能正常运行,不带的也一样会运行。碰到下一个判断的时候,“通行证”会重置。我不记得是不是这一关发现的这个机制的了,反正现在是看到我第一次这么用

卡宾枪瞄准照明器

【11/318/25】初见做法

比较垃圾,不想再看,所以没有介绍。

【7/262/14】

同样的用DX300节省简单输入输出口,然后就是分类讨论。由于这里的输出都可以覆盖,所以可以先判1种,然后不用嵌套判断在另外两种内分出来,节省嵌套判断用的jmp行数。

你能保守秘密吗?幽灵娃娃项目

hint:首先你得发现神必芯片必须从有三角形指着的地方才能按照样例那样给出输入数据。

这一关可以说是200P-14只读存储器的教程关了。注意到两种需要的音频长度都为13,加上默认输出50长度则为14。利用存储器指针的自加特性,以及指针到了最后一个会回到第0个的性质,我们只用读取后判断指针是否在0位置就能循环输出一整段音频并且最后回到默认输出上面。

【9/205/14】

定制规格书

随便整点什么就能过……不过整完后又是往创意工坊里面舔了垃圾……

共生环境维护机器人

【11/273/27】初见做法

【8/209/21】

在之前的实现当中发现电机的输出很难搞定:由于有50的默认输出,不能直接gen神启动,得整点。所以我们不妨把电机输出的工作整个的交给一个芯片来做。为了减少代码行数,我们要正向移动和反向移动尽量共用代码。实操一下发现输出50以及判等都能共用。其他的输入和另外两个输出发现都不算难,一个小芯片就能解决。

远程退出开关

hint:这一关首先感觉上应该用DX300处理输出。进一步可以发现0 x1 x操作相当于进行dst x 0或者dst x 1的操作。

【8/315/12】

搞完上面两个操作之后,你发现最大的难点在于同时维护当前向DX300的输出值和目前是第几秒两个。一般情况下两个都需要acc进行计算。这里我们有一种很好的遍历结构:存储器。两种存储器都是读/写内容,地址自加。这种操作只用1行代码,比一般的循环遍历少很多代码,使其可以成为一个很方便的计数/遍历结构。

至于怎么继续压下成本,这关中这种方法必须要用上dat,所以成本压不下去。可能有别的方法。

重要:控制路由器

【10/245/27】初见做法

把情况分为等于和不等于(大于/小于)的情况,两种情况由两个不同的MC6000处理。


亟待优化,,,

袖珍易经预测仪

【15/483/32】初见做法

太垃圾了懒得再看……

【8/220/14】20250801优化做法

其实题目不怎么难,显然显示屏要用DX300输出,可以使用dgt指令将每一单位时间的简单输入转化到对应位数上,制造DX300输出的代码很容易复用,问题在于如何用最少的代码将输入的100/0化成dgt用的1/0。我这里水平菜,只能多花1元成本再用个DX300转换输入了……不然没代码行数了……

精确食品秤

hint:所谓的显示的值不为0时,按按钮显示重量变为0的意思就是以当前重量为皮重,按完按钮显示去皮重量。

这关挺简单,直接看代码就能看懂,没什么特别好说的。

【5/407/12】初见做法

【5/367/10】简单优化

加密货币存储终端

【16/883/32】初见做法(其实还是做了一些简单优化)

很显然这道题要用一个100P-14内存芯片来存下卡号,三个简单输入和前面的三国铜币那一关一样用DX300处理。左侧芯片用来处理输入和通知输出(处理-1输入),下方芯片用来计算钱数,右侧芯片负责输出。于是就得到了初见做法。

【16/881/26】精简代码

重新看了一眼发现左侧负责输入的芯片写的乱麻一样,本质就是要区分输入,要么是-999不用管,要么非负数是卡号一起输入完,要么是-1处理输入。处理卡号的输入没必要用acc来做循环变量,直接jmp回开始冲新处理一边即可。于是我们省下了大量的代码行数,为正解做铺垫。

【11/696/21】精简芯片优化成本

我们发现这个时候负责输入的芯片空荡荡的,甚至可以考虑把负责计算的芯片和输入的芯片二合一了。问题在于,首先直接合起来的话代码行数大概多一两行放不下,而且更难受的是,需要五个Xbus口,而且没有Xbus口能和两个芯片之间传输的Xbus线路共用(都是非阻塞式的)。看上去可能要考虑用简单输入输出了,但是我们发现,两边每次进行完一个完整的操作的话,两边的内存地址应当是一样的,而且进行完一次操作后上一次的卡号不需要关心。所以我们每次可以不把内存地址复位到0,而是直接顺其自然,让地址自然溢出进行覆盖。

污染探测窗

【7/511/10】

很朴素的题,维护最近八个元素以及他们的和,多于八个元素,就删掉最早的元素加上最新的元素,同时和减去最早的元素加上最新的元素。相信学过些基本算法的都很容易想到。就是不知道怎么再压行数了,怎么办才能¥5啊

交通信号

【16/305/23】初见做法

很朴素的思路,下面两个芯片负责把一整个信号灯循环中每个时间需要向DX300输出的值预处理到200P-14上面,然后上面的芯片就照着内存读,遇到紧急信号停止输出地址复原就行了。

【10/250/15】优化内存

在看到上面这个不堪入目的做法之后,我想办法优化,但是按照上面的内存存储方式的话都没法只用一个大芯片来做预处理将数字存进去。我们转而按顺序将每一种向DX300的输出和对应秒数存进去,让进行输出的芯片去做循环来输出。

可以做出这么个做法,这个做法11块钱,也能过,我们后面优化这一个做法。

用从输出端输入的操作来同时清空引脚和acc,同时发现后面的jmp没用(后面没有带+的,直接会到最后的slp语句),改了这两行后发现只有9行代码,只需要用DX300将普通输入换成Xbus,我们就可以用小芯片省钱了。

肉食打印机

【14/111/20】初见做法

非常简单,唯一一个大芯片分类讨论3种情况,再将对应的情况发送给两个不同的小芯片去处理(自己也处理一种情况)

【8/150/14】节省芯片优化价格

不难看出上面的唐氏做法没有一个芯片充足的利用了代码行数,还用了一个只用了一般存储量的芯片。容易想到我们可以将两种情况存进内存从而节省掉一个芯片。事实上我们还可以更进一步的把最简单的第3种情况交给芯片自己去直接输出,其他两种再用内存辅助输出。每种情况恰好需要长度为7的内存,我们可以直接乘7访问每个情况的内存的起点地址(71=7,72=14溢出变成0),这样两种情况输出的代码也能复用。

噩梦般的安全问题

【7/360/14】某种类哈希的极其不安全但的确能过的神人做法

说实话记录这个神人做法可以说是写这个攻略的一大动力

首先这里这个100P-14只作为简易遍历的方式,不存实际有意义的数字。然后我们用我们的妙妙算法(就是a标签和后面跟着带减号的那几行)算出一个针对一种输入值的输出值,如果在学习就存到dat,如果不是那就和dat比对。至于那个代码里的奇妙106常数那是10个9也就是万能钥匙得到的输出。很显然这玩意存在一定很大可能性会重(用远不到999个(实际估计也就100多种情况?)表示 \(9^10\)种情况,实际运用中不重也的确神人)但是反正能过

【13/372/28】另一种也不太安全的初见做法

这次的妙妙算法就是只考虑每个输入包的后9个数的和。其实也挺不安全,跟上面的比半斤八两,权当记录初见做法。

海洋监测系统

【12/568/18】

我们要存储2个简单输入的最近6个数,一共12个数。使用两个内存显然有些浪费。我们就奇偶存储两种输入的数,并且存储当前的开始地址。

防剧透耳机

【11/1800/17】初见做法

朴素做法。每个时刻输入关键数,并且跟内存里存的所有的关键词两个数一一比对。一旦发现是关键词就睡到另一个芯片告诉他截止阻断了。由于DX300是非阻塞式Xbus不能使用slx导致加了一个芯片输出阻塞式的XBus。

【10/1800/17】一眼丁真的改进初见做法

跟上面做法一样,去掉DX300直接判断简单输入输出。

你相信吗?

【22/1250/40】初见做法

这道题个人认为是整个游戏第一道比较工程化(其实就是码量很大,需要很多分工)的题目。

200P-14 ROM芯片每相邻两个内存存储每种颜色的坐标。这个做法里,我们用第0,1号内存代表初始输出的两个坐标,其他在说明书中从上到下第 \(i\) 个颜色用第 \(2i\)\(2i+1\) 号内存存储坐标。

左下角的MC6000芯片负责统计按钮按下时,传感器输入的数字对应的每种颜色分别出现了多少次。看说明书容易发现传感器输出的十位数字决定了该统计入哪种颜色。红色比较特殊,十位数为2或者3都对应红色,其他颜色只有一种十位数对应,所以有一个teq acc 2来判断是不是红色的额外(也就是2)的那种情况。然后我们对对应地址的内存+1。

左上角的MC4000代码量很少,目的就是为了在上一秒按钮100这一秒0时,叫醒右下角的芯片,同时把底下的内存地址放到1方便遍历,总之都是为右下角的芯片节省代码行。右下角的芯片则在唤醒后找到当前最大的数并输出其地址。直接找到当前最大的数以及地址并不是很方便,我们需要三个数的内存,分别存当前遍历到的数,目前最大的数以及其地址。所以我们直接每次找到比当前数大的数都直接输出地址(由于刚才读过了,其实是下一个的地址)给右上角的输出芯片,右上角芯片怎么处理等会再说。然后找完后将内存清空地址归0。

右上角的芯片接到输出后,先地址-1(因为上面输入的是下一个的地址),然后直接输出对应的两个内存。但是,由于上面遍历的操作在一个时间单位内完成,所以每次接到输出都在同一个时间单位内刷新输出,所以最后接受到的输入必定是出现最多的颜色,输出正确性也得到保证。一开始的时候让acc=1是为了能够输出地址在0的默认地址。

航空鸡尾酒调酒器

【17/161/24】初见做法

从电路板就能看出来上下3个输出相当于被分为两组,每组都应用一个DX300方便输出。而且刚好7组酒,\(7\times 2=14\),不禁让我们联想到对于每一组原料,都用一个100P-14内存,存一下对应需要的原料的DX300输出和用时。我们发现除了第两种酒,其他的酒对应到上下每组原料,都是用量相同,也就是说对于这些酒,内存里只用存一个输出一个时间就行了。对于第二种酒,我们输入芯片特判一下,让他直接输出就行了。右边的两个MC4000X就用于处理正常情况,

【15/168/23】简单优化成本

发现上面的方案输入用的MC6000竟然就只用了10行,再削减一行就能用MC4000X了。发现我们用于输出普通情况的小芯片都是有对输出进行清零的,而且就算对他输入2他也不会对特判输出造成影响(毕竟存0,0,输出了也就是当清零了)。我们把MC6000清除特判输出的那一行删了,转而让上面那组的小芯片做这个活,就能省掉一行达到削减成本的作用了。

重要 — 大项目!

孙昊天任务链的最后一个任务。

【12/545/26】初见做法

说实话个人认为我这个初见做法还是有些巧妙在里面的。首先,我们发现同步雷达输出的6种数模14都不同余,这说明我们可以直接将同步雷达输出的数发给一个内存或者ROM的地址接口来存储读取不同的数。在这里我们用一个200P-14 ROM,每个同步雷达输出对应地址存储对应地方ping在 \((50,80)\) 之间的编号。然后再依次特判工业区、港口和中间的大楼,就能得到准确的位置。

另一个大芯片首先读取当前位置。由于这个大芯片每一时刻都要活动所以不用slx(当然上面的芯片也要每时刻输出地址)。然后清空扬声器输出(也用来初始化输出)。接着判断是什么询问种类。2的话跟加密芯片比对一下正确了就输出坐标并不难。如果小于1也就是-999的话跳到slp。注意发现这个slp在代码中间部分。不会有问题吗?没有问题。下一句话是留给1类输入用的。前面的话如果不是1的情况,就会因为mov x0 acc以及sub 1导致acc变-999,两个判断都进不去,满足不了条件。而如果是1的话,这里就被用来作为循环的一部分,acc存的是还剩多少个要输出。每一时刻读入Xbus输出扬声器,再把上面芯片的地址读入然后 slp 1,直到输出完成。这样子1和其他情况都互不干扰。

一封邀请函

通关了前面的所有关卡,(还是做完孙昊天任务链?不记得了)就能解锁。阿瓦隆城大大方方去,去了后之前的关卡也能继续游玩。而且你也能润到公海上没有雾霾的地方(话说这游戏是深圳背景是挺逆天,华强北市区地段还能建高架地铁,还有怪诞古风高楼。更别提还一天到晚雾霾。深圳印象里呆了很久都没见过雾霾)

浅浅剧透,这孙昊天也确实是神人,到阿瓦隆城整的活更大更疯狂更搞笑。

海的礼物

posted @ 2025-07-27 22:20  zimindaada  阅读(169)  评论(0)    收藏  举报