· engineering· 约 24 分钟精读
端侧离线教育沙盒的迷你游戏判定引擎工程:参数分区、命中容差与多套判定口径
九十六关里,每一次"这步操作算不算对"都由设备上的判定引擎回答。本文以密旋科技 QubitLab 的两台迷你游戏引擎为样本,逐层量出这条判定链路的四段:可调参数、本机物理模型、命中容差窗、阶段闸门;把十四个关卡的实际容差抄成一张可核对的台账;并把同一个条件上同时并存的多套判定口径摆在一起,说明它们为什么不是同一件事。
一、九十六关背后的八台判定引擎
QubitLab 是密旋科技面向 iOS 端的量子物理与 STEM 启蒙沙盒:九十六关闯关、布洛赫球面态矢进动、双比特逻辑门拼装与测量坍缩演示,全部在本机运行。关卡目录里每一关都带一个引擎标记,八种引擎把九十六关分完:光学装置打靶十关,原子光谱十四关,其余六台各十二关。
| 引擎 | 关数 | 学生能拧的那几个旋钮 |
|---|---|---|
| 光学装置打靶 | 10 | 小孔高度、镜面倾角、棱镜转角、水门宽度、双水滴间距、缝宽、缝距、波频、偏振角 |
| 原子光谱 | 14 | 入射波长、轨道序数、偏置电压、散射角 |
| 比特黑客 | 12 | 逻辑门次序与态矢角度 |
| 猫态救援 | 12 | 观测频率与低温温度 |
| 隧穿跑者 | 12 | 势垒高度与宽度 |
| 纠缠连线 | 12 | 两端测量角 |
| 窃听者捕捉 | 12 | 诱骗态强度与基矢选择 |
| 线路算法 | 12 | 线路上的门位排布 |
这些旋钮长得不一样,回答的问题却只有一个:学生把参数拧到某个位置之后,这一步到底算不算过。这件事落在每台引擎内部,由一串纯本机计算给出结论。本文只做一件事——把”算不算过”这条判定链路拆开,逐个环节量清楚。
二、判定链路的四段
先给一张链路图。以第一关”手电筒—小孔—靶星”为例,从学生手指按下开始,到屏幕上弹出成功提示为止,中间经过四段。
第一段是可调参数。第一关只有一个量:小孔在竖直导轨上的高度,初始值零点八二,走的是一个十到九十厘米刻度的滑杆。参数在视图里就是几个私有的状态量,改动一次就回调一次,回调只做一件事——把本局的步数加一。
第二段是本机物理模型。引擎按直线传播算出光束穿过小孔后落在竖直屏上的纵坐标,算完即用,不落盘。这一段决定了”参数变了,现象怎么变”。
第三段是命中容差窗。把落点纵坐标与靶心的纵坐标相减,取绝对值,与一个窗口比较。窗口之内算命中,窗口之外算未命中。
第四段是三态分区与阶段闸门。未命中时不是简单回一句”错了”,而是按偏差方向给出可执行的提示;命中时不只是点亮靶子,还要把这一关从”发现规律”推进到”用规律做预测”。
四段都在本机完成,没有一处需要联网。这一点在本篇里不是修辞:判定链路里没有任何远端调用,也没有把学生的操作序列送出去的地方。
三、分区而不是布尔
判定结果在工程里落成三个状态,而不是两个。枚举只有三个成员:偏低、命中、偏高,配色也只在定义处写一次——偏低橙色、命中绿色、偏高红色,其余所有界面引用同一份定义。单一真相源在这里的价值很实际:同一关的提示气泡、读数面板、靶面着色都取同一套颜色,学生看到的橙色始终指同一类偏差。
三态并不总是全用到。窗口型判定天然双侧:镜面倾角四十五度是目标,四十三度与四十七度都是错的,方向不同,提示也不同。阈值型判定则天然单侧。光电效应那一关问的是”单光子能量够不够越过逸出功”,能量越大越没问题,所以它的分区只会在偏低与命中之间切换,永远不会给出偏高。引擎在这一关没有把”能量过高”编成一种错误,这一点与物理事实一致。
与分区同时出现的还有一条进度读数。它是给进度条用的显示量,不是判定量:遏止电压那一关的进度按偏差除以三伏折算,光电阈值那一关按光子能量除以逸出功折算并截在一。把它当判定量读会读出错的结论——进度到一只是说明离目标近了,是否算过仍由窗口决定。
四、命中容差的台账
把光学装置引擎里每一关的显式验证窗口抄下来,得到一张可以逐行核对的表。这些窗口的单位各不相同,跨行比较没有意义,有用的是它们各自的松紧。
| 关卡 | 可调量 | 显式验证使用的窗口 | 单位 |
|---|---|---|---|
| 第 1 关 | 小孔高度 | 落点距靶心小于 28 | 画布像素 |
| 第 2 关 | 镜面倾角(发现阶段) | 四十五度正负 4 | 度 |
| 第 2 关 | 镜面倾角(预测阶段) | 三十一度正负 5 | 度 |
| 第 3 关 | 棱镜转角 | 绝对值不超过 5 | 度 |
| 第 4 关 | 水门宽度 | 不超过 22 | 厘米 |
| 第 5 关 | 双水滴间距 | 二十八正负 4 | 厘米 |
| 第 6 关 | 单缝缝宽 | 不超过 16 | 纳米 |
| 第 7 关 | 双缝缝距 | 二十六正负 3 | 纳米 |
| 第 8 关 | 观察灯开关 | 必须处于关闭 | 布尔 |
| 第 77 关 | 波频(发现阶段) | 四正负 0.4 | 赫兹 |
| 第 77 关 | 波频(预测阶段) | 五正负 0.4 | 赫兹 |
| 第 78 关 | 偏振角(发现阶段) | 绝对值不超过 6 | 度 |
| 第 78 关 | 偏振角(预测阶段) | 九十正负 6 | 度 |
这张表里有两处值得单独说。
一是窗口宽度按物理量级走。缝宽与缝距的量级是纳米,窗口给到十六与二十六正负三;水门宽度与水滴间距的量级是厘米,窗口给到二十二与正负四;角度类窗口统一在正负三到六度之间。这不是为了好过关,而是因为这几个量在画布上的可比分辨率本来就不同——纳米缝宽在画面上是十几像素的一条缝,厘米水门是几十像素的一段开口,把两者的容差换成同一个数字反而失真。
二是同一关的两个阶段,窗口未必对称。第二关发现阶段的窗口是四十五度正负四度,预测阶段是三十一度正负五度。预测阶段的窗口略宽,因为它考核的是”方向预测是否正确”——学生要判断镜子该放平还是该立起,而不是复现一个已知终点。
五、同一个条件上的多套口径
第四节那张表来自显式验证那条路径。引擎里实际上不止一条路径能改变判定结果,把它们摊开以后,同一个物理条件上同时存在多套口径。
| 口径出处 | 第一关预测阶段比的是什么 | 具体取值 |
|---|---|---|
| 屏幕读数窗 | 小孔高度的归一化值与一个中心比 | 零点三八正负零点零六 |
| 画布徽章窗 | 小孔高度的归一化值与一个中心比 | 零点四四正负零点零四 |
| 显式验证 | 光束落点与靶心的画布纵坐标之差 | 小于 28 像素 |
| 被动积分 | 光束落点与靶心的画布纵坐标之差 | 小于 26 像素 |
| 自动化测试钩子 | 小孔高度的归一化值与一个中心比 | 零点四四正负零点零五 |
五套口径测的是同一次对准,结论并不保证一致。屏幕读数窗的中心是零点三八,画布徽章窗与测试钩子的中心是零点四四;后两者的窗口宽度也不相同,一个是正负零点零四,一个是正负零点零五。落点口径与高度口径更不是一回事:高度是滑杆上的归一化值,落点是光束打到屏上的位置,两者之间隔着一个由入射方向推出的斜率,只在某一段区间里近似成线性关系。
这些差异不都是缺陷。显式验证用的是落点,因为它要判的是”光有没有照到星星”,这是屏幕上真实画出来的现象;屏幕读数窗用的是高度,因为它要给的是一句人话方向的提示,用归一化值算最省事。被动积分比显式验证紧两像素,因为被动这条路径没有学生确认这一步,收紧窗口是在替他把抖动滤掉。
但差异需要被写下来。工程上可接受的口径分离,前提是分离的双方各自有明确用途,并且没有哪一处把两套口径的结果混着用。上面这张表就是分离清单,它同时说明了一件事:学生看到的”已对准”与引擎认定的”已通过”是两个判断,前者不蕴含后者。
六、阶段闸门:先看出规律,再做一次预测
每一关不是一个终点,而是两个。第一个阶段考”看出规律”,第二个阶段考”用规律做预测”,两次都成立才算这一关物理部分通过。
推进方式是改题面,不是改判据。第一关发现阶段的靶心在正中央,命中之后靶心挪到高处,同一个操作方式要推出斜射的落点;第二关发现阶段照正上方的靶心,预测阶段把靶心挪到右侧,要判断镜子该放平一点还是立起来一点;第九关发现阶段用逸出功两点三电子伏的钠板,预测阶段直接换成四点五电子伏的铜板,刚才能打出电子的波长随即失效;第十关发现阶段把遏止电压调到光电流归零,预测阶段把入射波长换成更短的二百六十纳米,电子跑得更快,刹车电压要重新找;玻尔跃迁那几关在预测阶段把目标轨道抬高一级。
也有关卡用合取条件把关,条件是”物理量到位”与”已经动过手”同时成立。弗兰克–赫兹那一关要求加速电压落在共振窗内,并且本局步数至少为一;普朗克量子假说那一关要求波长不高于五百二十纳米,并且步数至少为一;德布罗意驻波那一关要求轨道序数不低于二、波长不高于五百纳米,并且步数至少为一。步数在这里只当”学生确实调过”的存在性证明,不参与打分。
七、物理模型里的常数与阈值
第二台引擎把判定建在几个可以逐项核对的物理量上。第一组是光电效应:光子能量按一千二百四十除以波长(纳米)折算成电子伏,逸出功是各关自带的常数——钠板两点三、铜板四点五、另有二点五、四点九与三点二几处,红限波长由一千二百四十除以逸出功反推;遏止电压取最大初动能的相反数,判定窗口是零点二五伏。一次发射只在能量越过逸出功时产生四个电子,判定要求累计电子数不少于四,也就是能量与”确实发了”两个条件一起满足。
第二组是弗兰克–赫兹碰撞:共振窗口是四点九伏正负零点四,而电压滑杆的可调范围在遏止电压那一关是负三伏到零点五伏,在弗兰克–赫兹那一关是零到六伏。窗口落在滑杆量程的哪一段,决定了学生能不能靠一个滑杆走进命中区。
第三组是康普顿散射。这一关的判定建在一条角度轴上,值得单独画一张图。
位移按电子康普顿波长二点四二六三皮米乘以一减余弦求出,角度滑杆走零到一百八十度,默认二十五度。判定为成功需要同时成立三件事:已经按下记录、角度落在证据窗内、波长位移大于零点零五皮米。证据窗的上下限在源码里是一个私有常量,界面上不显示,学生拿不到”应该调到多少度”这个答案,只能自己看现象——角度小的时候散射波长几乎不动,角度大起来波长明显变长,拐点需要自己找。
这一关还有一处结构上的分离值得抄下来:预测值与实测值是两个量。滑杆一移动,界面上的预测值实时刷新,但它不构成证据;只有按下记录、被写下来的那一次采样才进入成功判定,也才成为屏幕上那几行读数的来源。两个值分开存的意义在于,学生不能靠拖动滑杆去”刷”出一个漂亮数字——数字好看不等于记录成立。
顺带记一处细节:常量在同一份工程里有两种写法。光电那一组用一千二百四十这个取整值折算光子能量,康普顿那一组用一千二百三十九点八四一九八四这个更精确的值。两者相对偏差约等于万分之一点三,各自在自己的关卡集合内保持一致;把它们并列写出来,是因为这正是工程台账该有的样子——用什么值、值从哪来、有没有混用,比”常数就是常数”更接近事实。
八、哪些数字真的进了判定
判定链路上有几个数字看起来像成绩,实际不进判定,值得逐条说清。
第一是步数。引擎内部维护本局步数,每次调参加一,并把它随通关回调交回上层;上层在写入进度时传的是一个常量一,不是回调里那个数。关卡档案里另外声明了两个步数标准——一个是三星标准步数,一个是步数上限——但当前视图层没有任何地方读取它们。进度模型里还留了一个按关卡记录最佳步数的字段,写入逻辑完好,读它的地方没有。三个数字,一个被常量顶替,一个无人引用,一个只写不读。
第二是进度条比例。上一节说过它按偏差或比值折算,只驱动显示。
第三是星级。物理部分通过只给两颗星,第三颗星锁在导读页的概念题上,写在进度写入函数内部——调用方即使请求三颗星,也会被压回两颗,除非这一关的概念题已经答对。
把这些清完,判定引擎真正读的输入就剩三样:当前可调参数、本机物理模型算出的现象量、以及一个容差窗口。判定简单到这个程度,是刻意的——它让”哪里没对上”可以反过来讲成一句具体的话。
九、能力边界
把这条链路写清楚之后,还要把它的边界一起写清楚。
第一,容差窗口不是测量精度。窗口是教学设计参数,说的是”学生拧到这个范围内就算他掌握了这条规律”,它跟仪器精度、数值方法的误差都没关系。表里的正负四度、正负三纳米不能读成”这个模型的精度是四度”。
第二,本机物理模型是教学近似。直线传播、玻尔能级、康普顿位移都是各自范围内成立的简化模型,用于让学生在一个可把握的装置上看到因果关系。它们不是测量级仿真,也不做实验数据拟合。
第三,单次命中不等于理解。判定只回答”这一次调参是否落在窗口内”,两个阶段都通过也只说明装置上的两个任务完成了;学生是否真把规律迁移走,判定引擎给不出答案。
第四,多套口径这件事必须留在台账里。它们各自的用途成立,但两套口径的结论在边界附近不一致是可能的——也就是学生看到”已对准”而引擎判”未通过”。这类不一致不会造成数据错误,但会造成解释困难;把它写下来、把两侧用途写清楚,比假装只有一套口径可取。
第五,判定全在本机,代价是没有任何操作数据离开设备。行为分析、卡点热力图、容差窗口的实测分布,这类按数据驱动调参的做法在这里是做不了的。这是端侧离线这条路线的固定代价:把学生的操作留在他的设备上,就得靠人工审读与装置设计经验来定窗口。
十、结语
九十六关、八台引擎、一张容差台账,这套判定引擎的工程量不在算法的复杂度上,而在把”算不算过”拆成可核对的事:参数是什么、现象怎么算出来、和哪个窗口比、命中之后进入哪一阶段。四段各自简单,串起来之后,学生按下的每一次调节都能得到一句方向明确的回答。
密旋科技在这套端侧教育沙盒里选择把判定留在设备上。写这篇的目的不是替它宣称这套机制处处可控,而是把机制本身的形状交代清楚:窗口是可以被抄出来的数字,口径是可以被列出来的分叉,边界是可以被写下来的条款。判定引擎能证明的是”这一次操作落在窗口内”,证明不了的是”这个学生已经懂了”——后者要继续靠人。
参考文献
[1] Apple Developer Documentation. SwiftUI — TimelineView. https://developer.apple.com/documentation/swiftui/timelineview
[2] Apple Developer Documentation. SwiftUI — State. https://developer.apple.com/documentation/swiftui/state
[3] Apple Developer Documentation. Human Interface Guidelines — Feedback. https://developer.apple.com/design/human-interface-guidelines/feedback
[4] Apple Developer Documentation. Accessibility — Inspecting and testing your app. https://developer.apple.com/documentation/accessibility
[5] NIST. CODATA Internationally Recommended 2022 Values of the Fundamental Physical Constants. https://physics.nist.gov/cuu/Constants/index.html
[6] NIST. Atomic Spectra Database. https://www.nist.gov/pml/atomic-spectra-database
[7] W3C. Web Content Accessibility Guidelines (WCAG) 2.2. https://www.w3.org/TR/WCAG22/
[8] ISO. ISO/IEC 25010:2023 — Systems and software Quality Requirements and Evaluation. https://www.iso.org/standard/78176.html