电玩圈游戏网 搜一搜

安卓手游去频道 >

角色扮演 射击枪战 棋牌卡牌 体育运动 角色扮演 赛车竞速 休闲益智 音乐舞蹈 模拟经营 战棋塔防 推理解谜 策略战争

安卓应用去频道 >

社交通讯 系统工具 影音视听 拍摄美化 效率办公 学习教育 生活服务 旅游出行 资讯阅读 金融理财 网络购物 游戏助手

游戏视频去频道 >

动作冒险 射击枪战 棋牌卡牌 体育运动 角色扮演 赛车竞速 音乐舞蹈 模拟经营 战棋塔防 推理解谜 策略战争 休闲益智

资讯攻略去频道 >

手游资讯 手游攻略 手游问答 游戏资讯 游戏杂谈 游戏攻略 软件教程 软件资讯

专题合集去频道 >

游戏专题 应用专题

排行榜单去频道 >

游戏排行 应用排行
首页 游戏 应用 视频 资讯 专题 榜单

首页>资讯>游戏攻略>深圳SHENZHENIO阿瓦隆城第3关喂猫机攻略

深圳SHENZHENIO阿瓦隆城第3关喂猫机攻略

作者:佚名来源:百度2022/06/29

深圳IO是一款硬核的编程游戏,有着严谨的游戏内容,那么一起来看看阿瓦隆城第3关喂猫机的攻略吧。

关卡展示

本关的要求如下:

1,【标签阅读器】会不定期地发送单数字的数据包,可能是 1、2、3 中的一个。当【标签阅读器】发送数据包时,表示需要让机器给对应号码的小猫喂食。

2,给 X 号猫喂食时,需要一次投喂【数量 X】份【型号 X】类型的食物,向对应类型的食物输出端口发送时长 1 秒的脉冲信号,脉冲值号为该数量值。投喂完毕后,为了防止猫吃撑,需要确保【时间 X】秒内不再给 X 号猫继续喂食,即使收到【标签阅读器】发来的喂食信号,也无视。

这一关我们接触到了一个新的元件——开关元件。这是一个双闸开关,它有 A、B 两个输入量,任何时候,两个输入都一定有一个激活,有一个关闭。如果我们将开关的 A 口接到芯片的 p 口上,那么从 p 口读到 100 时表示开关接在 A 闸上,读到 0 时表示开关接在 B 闸上;反之亦然,如果我们改为将开关的 B 口接到芯片的 p 口上,那么从 p 口读到 100 时表示开关接在 B 闸上,读到 0 时表示开关接在 A 闸上。

本关的常数芯片的数量是整个深圳 IO 的所有谜题之最,一共有 9 块常数芯片,这给我们的布线工作造成了很大的阻碍。布线是本关的最大难点,逻辑上反而不复杂。电路图和代码如下:

左下方的芯片是和【标签阅读器】这个输入端口直接连接的芯片,将其视为 0 号芯片。左上方、中上方和中下方的芯片分别用于接管 1、2、3 号猫的喂食任务,将它们分别视为 1、2、3 号芯片。右下角的芯片用于收到信号时给相应的输出端口发送脉冲信号,将它视为 4 号芯片。

首先,0 号芯片每个时钟周期里都将【标签阅读器】的 x 口同步信号转成 p 口的广播信号,同时发给 3 块任务芯片。读到 -999 时,会自动转成下限值 0(mov x0 p0, slp 1)。为什么要将同步的点对点信号转换为非同步的广播信号呢?这主要基于以下两方面考虑:①同步信号只能被读取一次,而实际上每秒钟 1~3 号芯片都需要判断自己是不是来任务了。转成广播信号后,在相同的时钟周期里,同样的数字能被 3 块芯片都读取到;②题目要求喂一次猫后要在一定时间内无视对同一只猫的喂食请求。无视的最好方法是使用 slp 指令睡眠。而我们观察时序图发现,【标签阅读器】在无数据时会读到 -999。它其实相当于一个 C2S-RF901 元件,也就是只要你不读数据,数据就会一直积压在元件内部。我们睡醒以后再去读数据,读到的都是之前积压的已经过时的【队头】数据。

这个标签阅读器,我们需要让多个芯片在同一秒内读取多次,同时这几块芯片都只关心当下这一秒的数据,不关心历史数据。因此,这个输入量以 p 口的形式给出才是最合理的。可是题目既然没有以 p 口的形式给出这个输入量,我们就只能用 0 号芯片将其转换成 p 口量了。

1~3 号芯片的代码逻辑大同小异,我只挑 1 号讲。首先我们需要空操作一次,等待 0 号芯片将输入信号转换成广播信号(nop)。此时切记不能急于直接读 p0 口的值,因为直接读的话,读到的是上一秒的数据。我们必须要等待一个机器周期,让 0 号芯片消耗一条指令的时间,把这一秒的数据同步到 p0 口上后,1~3 号芯片才能正确读取到本秒 p0 口的值。

等到 0 号芯片同步完毕后,我们检查 p0 口是不是 1,也就是是否请求给 1 号猫喂食(teq p0 1)。如果需要给 1 号猫喂食,则把食品类型、食品数量依次发给右下角的 4 号芯片,委托它完成喂食任务(+ mov p1 x3, + mov x0 x3)。委托完成后,休眠【时间 1】秒,在这些时间内,一律不接收 p0 口的实时广播信号,不响应任何“给 1 号猫喂食”的请求(+ slp x1)。如果本秒钟里 p0 口的值不是 1,也就是没有请求给 1 号猫喂食,那么就休眠 1 秒,进入下一个时钟周期后,继续监 听是否要给 1 号猫喂食(- slp 1)。

2、3 号芯片的逻辑几乎完全一致,只是改为了判断是否要给 2、3 号猫喂食(teq p0 2/3)。另外,为了布线上的方便,2、3 号芯片改为用 x1 口和 4 号芯片相连;常数芯片的位置也做了调整,“时间”芯片移动到了各自的 x3 口上,“数量”芯片移动到了各自的 x2 口上,仅仅是“型号”开关仍然放在 p1 口上。因此向 4 号芯片发送数据时,以及休眠时,读/写的端口也需要同步进行修改(+ mov p1 x1, + mov x3 x1, + slp x2)。

最后是右下角的 4 号芯片。1~3 号芯片向 4 号芯片发送喂食请求时,一共会发 2 个数字。先发送的是食物类型,后发送的是食物数量。我们的三个双闸开关都接在了对应芯片右侧的 p1 口上,都选择了把 A 端和芯片相连。因此,当 1~3 号芯片从 p1 口读到 100 时,表明需要给自己的猫投喂 A 类型的食物;反之亦然,当 1~3 号芯片从 p1 口读到 0 时,表明需要给自己的猫投喂 B 类型的食物。

现在来看 4 号芯片的代码。首先等待 1~3 号芯片发来唤醒信号(slx x0)。唤醒后,我们收到的第一个数字是要投喂的食物类型,100 为 A,0 为 B。判断第一个数字是 0 还是 100,激活对应的 + - 号指令(tcp x0 50)。判断完成后,我们需要接收第二个喂食量的数字。第一个数字是 0 时,我们将该喂食量发到【食物 B】端口(- mov x0 p0);第一个数字是 100 时,我们将该喂食量发到【食物 A】端口(+ mov x0 p1)。接下来,休眠 1 秒,让该脉冲信号生效(slp 1)。1 秒过后,同时清除两个食物端口的信号,完成本次脉冲信号的发送(mov p0 p1)。

点击左下角的【模拟】,稍等片刻,便会弹出结算界面:

优化成本

以上方案里,1~3 号芯片都只有 6 行代码,且也没用到 acc 和 dat 寄存器。只是因为 2P3X 共 5 个端口都有导线连接,就不得不使用 MC6000,非常可惜。现在我们换一种方案, 1~3 号芯片改为使用 MC4000,4 号芯片改为使用 MC6000,然后我们将原先接在 1~3 号芯片上的“数量”芯片改接到 4 号芯片上。给 4 号芯片发送数据时,之前是发送食物类型 + 食物数量,现在改为发送食物类型 + 猫的编号,由 4 号芯片通过“三态判定”的方式计算数量是多少。若如此做,我们就会有两块 MC6000 被替换成 MC4000,成本上可以节省 4 块钱。电路图和代码如下:

因为我们将两块 MC6000 换成了 MC4000,整体的占用体积变小了,布局也更加灵活自由了。这次我们将 1~3 号芯片摆在了同一个竖排,左边还用导线摆出了 CAT 的字符画,比上一个方案的布局要漂亮多了。

0 号芯片依然是将【标签阅读器】的同步信号转成广播信号(mov x0 p1, slp 1)。

然后是 1~3 号芯片。本方案里,1~3 号芯片除了判断语句外,代码已经完全一样了,因为三块芯片都统一将 x0 口用作通讯端口、p0 口用作广播信号端口、p1 口用作食物类型端口、x1 口用作睡眠时长端口。首先等待 0 号芯片将广播信号同步完成(nop),然后检查 p0 口的数字是不是和自己管理的猫的编号一致(teq p0 1/2/3)。一致时,依次将当前要喂食的猫的编号,以及食物类型发给 4 号芯片(+ mov p0 x0, + mov p1 x0),然后休眠 x1 秒,休眠过程中不响应任何广播信号(+ slp x1)。不一致时,休眠 1 秒,进入下一个时钟周期后,继续监 听是否要给自己的猫喂食(- slp 1)。

最后是 4 号芯片。首先等待 1~3 号芯片的唤醒信号(slx x0)。第一个数字是要喂食的猫的编号,我们对该编号做三态判定,向 acc 中存入正确的喂食量(mov x2 acc, tcp x0 2, - mov x1 acc, + mov x3 acc)。然后我们接收第二个表示食物类型的数字,100 为 A,0 为 B(tcp x0 50)。第二个数字为 0 时,我们向【食物 B】口投入食物(- mov acc p0),否则向【食物 A】口投(+ mov acc p1)。接下来,休眠 1 秒,让该脉冲信号生效(slp 1)。1 秒过后,同时清除两个食物端口的信号,完成本次脉冲信号的发送(mov p0 p1)。

点击左下角的【模拟】,稍等片刻,便会弹出结算界面:

如此,便将成本压缩到了 17 块钱。

评论 (0)

相关阅读
网友评论0条评论

上拉或点击查看更多