欢迎光临散文网 会员登陆 & 注册

【深圳 IO 攻略】第 14 关:三明治制作机

2022-06-02 15:19 作者:ココアお姉ちゃん  | 我要投稿

本文首发于 B 站《深圳 IO》文集(https://www.bilibili.com/read/readlist/rl569860)。原创不易,转载请注明出处。

关卡展示

本关要求根据小键盘按下的 1/2/3 键制作不同种类的三明治:

  1. 标准三明治,下层面包 + 肉 + 奶酪 + 芥末 + 上层面包

  2. 不加奶酪的三明治,下层面包 + 肉 + 芥末 + 上层面包

  3. 多加芥末的三明治,下层面包 + 肉 + 奶酪 + 两份芥末 + 上层面包

每做完一个三明治,激活“旗”信号三秒钟。

又是一个超多 p 口的关卡,又是 DX-300 大显身手的时候。我们首先二话不说,先在电路板右侧安排上一个 DX-300,令它的 p2、p1、p0 口分别和“肉”、“奶酪”、“芥末”相连。

然后我们注意一下这次的“小键盘”输入。这个输入口是带黄色三角形的,说明需要跟芯片的 x 口相连接。但是这次的 x 口和之前接触到的“无线 rx”输入信号不一样,它和芯片之间传输数据的方式一样,如果你在读数据的时候,输入源并没有提供数据,那你并不会读到 -999,而是会令程序阻塞。所以,我们必须先用 slx 指令“等待唤醒”后,再来读取数据。

我们读取到的数据只有 1/2/3 三种,因此很容易想到用 tcp 三态判断一气呵成。

等来小键盘的信号后(slx x0),我们首先一条 tcp 指令,根据小键盘的值对应激活 + - 号指令(tcp x0 2)。第一片面包(gen p1 1 0),以及肉(mov 100 x3, slp 1),三种三明治都是一样的,只有到了第二步“加奶酪”的时候(mov 10 x3),才需要判断小键盘的值。

因为只有 2 号三明治不加奶酪,所以当准备发送加奶酪信号后,只有小键盘的值是端点值时才休眠一秒(- slp 1, + slp 1),当它是中间值时,跳过两个 slp 1,立刻给 DX-300 重新传 1。我们说过,p 口的信号在同一秒内可以反复修改,最终 p 口的值会定格在本秒内最后一次所赋的值上。因此当小键盘的值是中间值时,【奶酪】端口相当于被赋了 100 后在本秒内立刻被重新赋 0,最终只有最后一次赋值的状态会生效(也就是奶酪信号并没有被激活)。

只有 3 号三明治要加两份芥末,首先三种三明治要在给 DX-300 赋 1 后(mov 1 x3)共享同一个休眠一秒的指令(slp 1)。而 3 号三明治最特殊,在接受了共享的“休眠一秒”指令后,还需要单独再休眠一秒(+ slp 1)。

做完这些后,接下来是三种三明治都一样的 1 秒面包信号(gen p1 1 x3,读 x3 会读到立即数 0,同时清除芥末信号)和 3 秒国旗信号(gen p0 3 0)。

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

优化电量

为了将复杂的逻辑代码压到 14 行以内,我们在以上代码中使用了较多的 gen 指令。而我们知道,gen 指令的第二个操作数是 0 时,其实是有 slp 0 的效率浪费的。为了提高效率,我们很自然会想到将 gen 指令展开,然后去掉无效的 slp 指令。比如将上方的第三行代码

展开成下面这样的三行代码后:

效率上会有不少提升。但问题在于,展开了以后,多了两行代码,代码行数变成 15 行了,一块芯片放不下了啊!

然后我们注意到,mov 0 p1 后面紧跟着一条 mov 100 x3。还记得我反复提到的“一举两得”技巧吗?【读一个只写 p 口,或者连接着若干只写 p 口的 DX-300 时,会得到立即数 0,同时清除这些只写 p 口的信号】。

咱们现在的优化技巧,就是改变一下 p 口和 DX-300 所控制的端口,尽可能多的“一举两得”。比如,我们将 p1 和 DX-300 的 p2 所连接的端口交换一下,p1 控制【肉】,DX-300 的 p2 控制【面包】。然后,我们把代码改成下面的样子:

首先还是等待小键盘输入(slx x1),并对该输入做三态判定,按需激活 + - 号指令(tcp x1 2)。接下来,由于面包信号改为 DX-300 控制了,我们给 DX-300 发送 100 信号并睡 1 秒,将面包信号激活 1 秒钟(mov 100 x3, slp 1)。面包信号激活 1 秒后,我们清除面包信号,并将 p1 口控制的肉信号激活 1 秒钟(gen p1 1 x3)。这里通过读 x3 获得 0 立即数,同时清除 DX-300 的 3 路输出,相当于同时执行了 mov 0 x3 和 gen p1 1 0 这两条指令,一举两得。第 6~11 行代码和上一版方案一模一样。最后,第 12~13 行激活 1 秒面包信号(mov 100 x3, slp 1);第 14 行清除面包信号,并将 p0 口控制的旗信号激活 3 秒钟(gen p0 3 x3)。这里通过读 x3 获得 0 立即数,同时清除 DX-300 的 3 路输出,相当于同时执行了 mov 0 x3 和 gen p0 3 0 这两条指令,一举两得

以上,我们通过调整 p1 口和 DX-300 的分工,成功在代码里梅开二度,两次实现“一举两得”,将电量由 81 减少到了 73。

【深圳 IO 攻略】第 14 关:三明治制作机的评论 (共 条)

分享到微博请遵守国家法律