确定性随机与绕开单例缓存:纯端侧数独案例里的两个选择
。前面几篇写的都是端云一体,这次换个方向:鸿蒙案例中心有个「数独小游戏:HarmonyOS + ArkUI 纯端侧开发」,全程离线、不联网、不登录,60 分钟。看起来是个小玩意,但案例页交代的三个做法都挺讲究,尤其两处反直觉的选择值得单独说。
一、题库用确定性 PRNG,不用真随机
案例的做法是「基准解 + 置换 + 盲挖空格」,生成 54 道题,简单、中等、困难各 18 道。关键在于「确定性」三个字:同一个种子必然生成同一套题,每题都有解,结果可复现。如果用 Math.random 那套真随机去挖空格,会踩两个坑——偶尔挖出多解甚至无解的盘面,以及出问题后没法复现(同一个用户报「这题做不出来」,你重跑一遍得到的是另一套题,无从查证)。用固定种子的 PRNG,题库等于一份可版本化的资产:改难度只需调参数,回归测试可以断言「第 37 题的解仍是这个」。
二、逻辑和 UI 分开写,校验用纯函数
行列宫冲突校验、解题判定都用 TypeScript 纯函数实现,跟 ArkUI 界面完全分离。这不是为了好看,是因为棋盘这类交互的校验会在每次输入时触发,纯函数没有状态、没有副作用,输入相同输出必然相同,测试起来不用起界面。声明式 UI 渲染 9×9 棋盘时,界面只负责把校验结果画成红色高亮,判断逻辑一行都不掺进去。
三、进度存档绕开 dataPreferences,直接读文件
这条最有实操价值。案例用 @ohos.file.fs 直接读写进度 JSON,理由写得很明确:规避 dataPreferences 单例缓存的跨页面读旧值问题。也就是说,首页展示的「已通关几题」和游戏页写回的最新进度,如果走 dataPreferences,可能因为内存里的单例还停在旧快照,返回首页看到的还是上一次的数字。直接读文件虽然要多写几行 IO,但读写路径清楚,页面间不会互相欺骗。做小应用时这条很容易被忽略,等发现「数字不刷新」再回头改,往往已经散落在多个页面里了。
四、成果长什么样
案例给的验收标准很具体:三个页面(首页、游戏页、选题列表)能跑通;54 道题每题有解且可复现;填入重复数字即时红色高亮;通关纪录重启后仍在,且能重置。这四条里最容易被跳过的是「每题有解」——它不能靠人眼看,要靠脚本把 54 道题全解一遍。
五、纯端侧的价值在哪
前面写端云一体时反复强调「密钥不放端侧、校验放云端」,那是因为有云端。这个案例反过来证明另一件事:一个不需要账号、不需要同步、不需要统计的单机应用,把数据放在本地文件里就是最优解,多接一层云只会多一处故障点和一个要维护的账号体系。判断标准其实很简单——数据是不是只属于这台设备、只被这个用户看。如果是,端侧就够了。
一句话:这个案例练的是两样本事,用确定性换可复现,用纯函数换可测试。做端侧功能时先把这两条落实,剩下的界面反而是最省事的部分。
- 点赞
- 收藏
- 关注作者
评论(0)