鸿蒙数独小游戏实测:用AI DevSpace问清冲突校验与本地存档的三个关键点

举报
yd_274372260 发表于 2026/11/10 01:19:03 2026/11/10
【摘要】 今天在鸿蒙开发实践中心浏览了“数独小游戏:HarmonyOS + ArkUI 纯端侧开发”案例,又在华为云 AI 开发者空间的 AI Shell 里就这个案例追问了两个实现细节,顺手把学到的东西整理成这篇短文。案例本身很适合入门:一个 9×9 数独,首页有进度卡片和出题入口,点“随机一题”就能进棋盘,全程离线,不依赖云服务。 一、冲突校验:落子就亮红,靠的是状态驱动数独只有三条规则:每行、每...

今天在鸿蒙开发实践中心浏览了“数独小游戏:HarmonyOS + ArkUI 纯端侧开发”案例,又在华为云 AI 开发者空间的 AI Shell 里就这个案例追问了两个实现细节,顺手把学到的东西整理成这篇短文。案例本身很适合入门:一个 9×9 数独,首页有进度卡片和出题入口,点“随机一题”就能进棋盘,全程离线,不依赖云服务。

一、冲突校验:落子就亮红,靠的是状态驱动

数独只有三条规则:每行、每列、每个 3×3 宫格里 1 到 9 都不能重复。案例把棋盘存成一个二维数组,每个格子记录填入的值、是不是题目预设、以及有没有冲突。每次落子后,程序会重新扫描整盘 81 个格子,对每个格子检查它所在的行、列和宫格里有没有相同数字,有就把冲突标记置上。宫格定位有个小技巧:Math.floor(row / 3) * 3 可以算出所在宫格的起始行,比如第 5 行属于从第 3 行开始的那一排宫格。

为什么是全盘扫描而不是只查当前格?因为一个新数字可能让别的格子“从不冲突变成冲突”。比如同行里原来只有一个 5,你又填了一个 5,两个格子要同时变红。全盘扫描 81 格,每格最多比较 27 次,总共两千多次比较,对手机来说毫无压力。

界面层完全不用操心刷新时机。棋盘数据用 @State 修饰,数据一变,ArkUI 的声明式界面会自动重渲染,冲突格子按标记变红。数据流很干净:点数字键改数据,校验函数重算标记,界面按标记上色。

二、进度存档:文件直读,避开缓存读旧值

通关进度存在应用沙箱的 filesDir 目录里,用 @ohos.file.fs 按 open、write、read、close 的流程读写一个 JSON 文件。打开页面时先读文件恢复进度,通关或退出页面时写回文件,重启应用后进度还在,重置则清空文件内容。

这个设计有个值得注意的取舍:案例没有用 dataPreferences,而是直接读文件。原因是 dataPreferences 的单例缓存可能导致跨页面读到旧值,首页进度计数不更新;而文件直读每次都取磁盘最新值,从根上避开了这个问题。文件路径用 context.filesDir 取得,不需要额外申请权限,也不要硬编码外部存储路径。

三、AI DevSpace 里追问到的三个坑

我在 AI Shell 里新建会话,把上面两个问题抛给 AI。它先去查了官方文档,搜索接口当时达到了免 key 的调用上限,但它还是结合已有知识给了完整解答,还提醒了三个容易踩的坑:第一,@State 默认只做浅观察,直接改 board[0][0].value 可能不触发刷新,要用 @Observed 加 @ObjectLink,或者改完重新赋值整个数组;第二,不同 API 版本里 fs.open 的标志常量名字不一样,API 9 以上用 fs.OpenMode 枚举,旧版本用数字;第三,通关判定不能只看“有没有空格”,必须同时满足“无空格且无冲突”。

四、小结:一个案例,四层收获

这次体验下来,数独案例的价值不在游戏本身,而在它把“数据层、校验层、渲染层、持久化层”四层拆得很清楚:状态管数据,纯函数管校验,声明式 UI 管渲染,文件读写管存档,层与层之间只通过标记和文件打交道。下一步我打算在本地把源码跑起来,重点验证冲突校验的固定样例和 54 道题的确定性生成,也就是相同的种子是不是每次都生成同一套题。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。