电玩圈游戏网 搜一搜

安卓手游去频道 >

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

安卓应用去频道 >

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

游戏视频去频道 >

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

资讯攻略去频道 >

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

专题合集去频道 >

游戏专题 应用专题

排行榜单去频道 >

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

首页>资讯>手游攻略>深圳SHENZHENIO阿瓦隆城第7关钛反应堆攻略

深圳SHENZHENIO阿瓦隆城第7关钛反应堆攻略

作者:佚名来源:百度2022/07/04

深圳IO是一款硬核的编程游戏,有着严谨的游戏内容,那么一起来看看阿瓦隆城第7关钛反应堆状态的攻略吧。

关卡展示

本关要求你实现一个钛反应堆状态显示器。具体的控制方法参考数据手册:

1~5 对应五种错误信号,10~14 对应着能源输出,20~24 对应着温度输出,30~34 对应着操纵杆。

能源/温度在 0~19 时亮一格,20~39 时亮两格,40~59 时亮三格,60~79 时亮四格,80~100 时亮五格。

操纵杆信号为 0 时亮 32、33、34 号方块,信号为 50 时亮 31、32、33 号方块,信号为 100 时亮 30、31、32 号方块。

需要点亮某个部件时,将该部件的编号传入显示器即可;需要熄灭某个部件时,将该部件编号的相反数传入显示器即可。

本关有【错误】、【能源】、【温度】、【操纵杆】四大输入量。最简单的办法就是用四块芯片依次控制这四种输入量。电路图和代码如下:

左上角的 MC4000X 连接着【错误】输入,是 1 号芯片。它的任务比较简单,收到【错误】端口的信号后(slx x0),将对应的信号值直接发给显示器就 OK 了(mov x0 x3)。当然只干这么点活未免没有充分利用这块 MC4000X 的代码容量。我们发现,能源/温度的最低一格的方块,还有操纵杆的最中间的方块是常亮的,因此我们在这块芯片里额外执行三条初始化指令,点亮这三个常亮的方块(@ mov 32 x3, @ mov 20 x3, @ mov 10 x3)。

位于正中央的 MC6000 连接着【电源】输入,是 2 号芯片。第一行的代码(mov -30 x3)是从下方控制操纵杆的 4 号芯片里挪出来的,我们先无视它。

这块芯片的逻辑嵌套比较多,但很容易理解。当电源值在 80~100 范围内时,我们的代码看起来是这样的:

点亮编号为 14、13、12、11 的小方块

当电源值在 60~79 范围内时,我们的代码看起来是这样的:

熄灭编号为 14 的小方块,点亮编号为 13、12、11 的小方块

当电源值在 40~59 范围内时,我们的代码看起来是这样的:

熄灭编号为 14、13 的小方块,点亮编号为 12、11 的小方块

当电源值在 20~39 范围内时,我们的代码看起来是这样的:

熄灭编号为 14、13、12 的小方块,点亮编号为 11 的小方块

当电源值在 0~19 范围内时,我们的代码看起来是这样的:

熄灭编号为 14、13、12、11 的小方块

做完这些后,记得休眠一秒,进入下一个时钟周期(slp 1)。

最靠近显示器的 MC6000 连接着【温度】输入,是 3 号芯片。3 号芯片的代码和 2 号芯片大同小异,只是因为这块芯片控制的是温度显示,不是电源显示,所以操作数的十位数都由 1 变成了 2。同样的逻辑我不再复述。

最后是最下方的 MC4000。这块芯片连接着【控制】输入,是 4 号芯片。这块芯片本应是 10 行代码。可如果使用 MC6000 的话,会把本应送到 3 号芯片的【温度】这路输入给挡住,无法送到 3 号芯片中。因此,这里我选择了将其中一行代码(mov -30 x1)挪到 2 号芯片中。2 号芯片的 x3 口连接着显示器,因此挪过去的代码也相应地产生了变化(mov -30 x3)。这样本芯片就只有 9 行代码了,就能换成 MC4000 了。节省了成本不说,线路板的占用面积也变少了,【温度】这路输入信号就能畅通无阻地送到 3 号芯片中了。

那么我们分析的时候,还是按照完整的 10 行代码来分析。完整的 10 行代码是这个样子的:

一个典型的“三态判定”。【控制】输入只有 0、50、100 三种值,先假设是中间状态,点亮 31、33 号小方块,熄灭 30、34 号小方块(tcp p0 50, mov -30 x1, mov +31 x1, mov +33 x1, mov -34 x1)。此时的状态是 30、34 熄灭,31、32、33 点亮。

当控制输入是 0 时,在以上操作的基础上,熄灭 31 号小方块,点亮 34 号小方块(- mov -31 x1, - mov +34 x1),最终状态变为 30、31 熄灭,32、33、34 点亮。

当控制输入是 100 时,在以上操作的基础上,熄灭 33 号小方块,点亮 30 号小方块(+ mov -33 x1, + mov +30 x1),最终状态变为 30、31、32 点亮,33、34 熄灭。

做完以上操作后,休眠一秒,进入下一个时钟周期(slp 1)。

点击左下角的【模拟】,可以看到显示屏已经能显示出实时的反应堆状态了,非常漂亮:

稍等片刻,便会弹出结算界面:

优化电量

我们的第一版设计方案里,耗电量达到了 1.5K。这是因为我们每秒钟都在刷新显示屏。实际上我们并不需要这么频繁地刷新,只需要在输入量产生变化时刷新即可。输入量未产生变化时对显示屏的一切操作都是【空操作】。

除连接【错误】输入信号的 1 号芯片外,其余芯片都可以用 acc 寄存器记录前一秒的状态。仅当本秒的状态和前一秒不一致时,才需要刷新显示屏。本方案较上一版方案的改动较大,我需要从头开始重新分析一遍所有的逻辑。电路图和代码如下:

此时,为了布线上的方便,1 号芯片从左上角的位置挪到了上方居中的位置,芯片型号由原先的 MC4000X 换成了 MC4000,和显示器连接的端口变成了 x1。因此该芯片上一版代码中的 x3 全部替换成 x1。同时,这块芯片的初始化部分还增加了两条指令(@ mov 34 x1, @ mov 33 x1),将操纵杆部分初始化为了【控制】输入为 0 时的状态。任何芯片的 acc 寄存器的初始值都是 0,这里等于是假设第 0 秒前的第 -1 秒,【控制】输入是 0。

这里我们先看连接着【控制】输入的 4 号芯片。这次,因为代码量的增加,这块芯片换成了 MC6000,这样我们就能把原先挪到 2 号芯片的那行代码(mov -30 x1)挪回来了。到达新的一秒后,首先检查【控制】输入的值是否和上一秒一致(teq p0 acc)。一致时,直接跳到最后睡觉,无需刷新这部分的显示(+ jmp d)。不一致时,先将本秒的【控制】值写入 acc,供下一秒使用。接下来是和上一版方案完全一致的“三态判定”的过程。这里要注意,芯片换成 MC6000 后,和显示器通讯的端口变成了 x3,因此这块芯片上一版代码中的 x1 要全部替换成 x3。

最复杂的部分在于控制【电源】和【温度】显示的 2 号、3 号芯片。上一版方案里,2 号、3 号芯片已经占用掉了 14 和 13 行代码,已经无法再容纳“将本秒的状态值和 acc 做比较”、“按需跳过刷新过程”以及“将本秒状态存入 acc 供下一秒使用”这样三行代码了。本方案里,我们使用了循环结构来刷新【电源】和【温度】的显示,且听我详细道来。

电源值和要点亮的小方块呈如下的映射关系:

我们可以看到,电源值和要点亮的小方块的最大编号间的关系满足如下数学公式:

这里面仅当 power 为 100 时是例外情况。当 power 为 100 时,max = 15。然而我们的显示器上并没有编号为 15 的方块,向显示器传入 15 相当于【空操作】,不会产生足以影响结果的 bug。

我们的 2 号、3 号芯片正是围绕着这个公式做循环的。现在我们来看 2 号芯片的代码。

首先检查本秒的状态值和上一秒是否一致(teq p0 acc)。一致时,关闭所有的 - 号指令,直接跳到最后睡觉。不一致时,则将本秒的状态值 ×5 后取百位,相当于除以 20 后向下取整(- mov p0 acc, - mul 5, - dgt 2),并加上 11 后发给右边的 5 号芯片(- add 11, - mov acc x1),然后再发一个 -15 给右边的 5 号芯片(- mov -15 x1)。做完这些后,为了方便下一秒钟和本秒钟的状态做比较,将本秒的状态值放入 acc(- mov p0 acc)。然后,我们就可以安心休眠了(slp 1)。

3 号芯片的逻辑和 2 号芯片大同小异,只是所有操作数的十位数都由 1 变成了 2。

2 号、3 号芯片的代码里,向右边的 5 号芯片发送了 max+1,以及 -15/-25 这两个值,其实是委托右边的芯片用循环的方式,将【11/21 ≤ 编号 < max+1】的灯点亮,将【max+1 ≤ 编号 < 15/25】的灯熄灭。这就是 max+1 及 -15/-25 两个数的意义。我们来分析一下右侧 5 号芯片的代码:

首先等待左侧的芯片将自己唤醒(slx x1)。唤醒后,我们将收到的 max+1 放入 dat(mov x1 dat),然后将该值复制一份放入 acc,并将个位置 1(mov dat acc),准备完成“将【11/21 ≤ 编号 < max+1】的灯点亮”这部分任务。当 acc < max+1 时(tcp acc dat),我们将对应的灯点亮(- mov acc x3),然后令 acc +1 以切换到下一个灯继续判断,直到 acc = max+1 为止(- add 1, - jmp 5)。

此时我们要注意一下,熄灭一个灯要传入对应灯编号的相反数。所以“将【max+1 ≤ 编号 < 15/25】的灯熄灭”这样的任务其实要做的是“循环给显示屏传送 -max-1 ~ -14/-24 范围内的值”。这里,我们将 max+1 乘以 -1,变成 -max-1(mul -1),并从 x1 口接收第二个数 -15/-25(mov x1 dat),准备完成“将【max+1 ≤ 编号 < 15/25】的灯熄灭”这部分任务。当 acc > -15/-25 时(tcp acc dat),我们将对应的灯熄灭(+ mov acc x3),然后令 acc -1(绝对值 +1)以切换到下一个灯继续判断,直到 acc = -15/-25 为止(+ sub 1, + jmp b)。

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

电量由之前的 1.5K 骤降到 761,效率几乎提升了一倍!

评论 (0)

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

上拉或点击查看更多