游戏中的算法与计算思维 07:按难度保存最佳成绩

课程首页 · 全部知识课程 · 返回专题主页

本系列第 7/8 课,建议 45–60 分钟(估算)。先完成上一课。

下载本课完成工程 .aia

这课解决什么

最佳成绩先比较步数,再比较耗时。不同难度使用不同 TinyDB 标签,不能让四对的成绩覆盖六对。成绩文本用于展示,步数和秒数分别保存供比较。

先预测,再运行

四对 4 步 20 秒、六对 6 步 10 秒,谁更好?

先记下自己的答案,运行起始工程与完成工程比较;答案见文末。

开始实战

以上一课完成工程为起点,先导入并运行,再另存为本课作业。

完成工程可以查看答案;独立作业请保留自己的修改。

新增或调整的组件

实例名 组件 本课配置
标签_标题 标签 Width=Fill parent;FontSize=24;TextColor=#183153;Text=记忆翻牌 · 第 7课
微数据库1 微数据库 Namespace=MemoryC07
标签_最佳 标签 Width=Fill parent;FontSize=16;TextColor=#183153;Text=尚无最佳成绩

逐步搭建

  1. 加入微数据库和最佳标签,标签键包含当前对数。
  2. 胜利时读取旧步数、旧秒数;步数更少,或相同步数更快时写新纪录。
  3. 新局显示当前难度最佳,重启按默认难度读取。
  4. 更差成绩不覆盖;切换难度显示不同记录;关闭 APK 再开成绩仍在。

记忆翻牌游戏第7课运行状态布局预览

图来自本课最终工程执行积木后的状态,为 HTML 近似预览;不是手机截图。

核心积木与数据流

下面是本课完成工程中的核心代码,包含所需全局变量和过程。可在块图中追踪数值,再回到工程对照完整事件;合并到已有工程时,同名事件合并处理。

global 牌 = []
global 翻面 = []
global 第一 = 0
global 第二 = 0
global 锁定 = false
global 已配对 = 0
global 步数 = 0
global 开始时刻 = 0
global 秒数 = 0
global 对数 = 4
global 宽 = 70
global 高 = 100

procedure 绘制() {
宽 = 画布1.Width / 4
高 = 画布1.Height / ceil(length(牌) / 4)
画布1.Clear()
for i = 1 to length(牌) {
var 列 = (i - 1) % 4
var 行 = floor((i - 1) / 4)
画布1.PaintColor = choose(翻面[i] = 2, -14575216, choose(翻面[i] = 1,-24576,-14268949))
画布1.DrawShape(list(list(列 * 宽 + 2,行 * 高 + 2),list((列 + 1) * 宽 - 2,行 * 高 + 2),list((列 + 1) * 宽 - 2,(行 + 1) * 高 - 2),list(列 * 宽 + 2,(行 + 1) * 高 - 2)),true)
画布1.PaintColor = -1
画布1.DrawText(choose(翻面[i] = 0,"?",牌[i]),(列 + 0.5) * 宽,(行 + 0.5) * 高)
}
}

when 画布1.Touched(x, y, touchedAnySprite) {
if x >= 0 and y >= 0 and x < 画布1.Width and y < 画布1.Height {
var i = floor(y / 高) * 4 + floor(x / 宽) + 1
if i <= length(牌) and not 锁定 {
if 翻面[i] = 0 {
翻面[i] = 1
if 第一 = 0 { 第一 = i }
else {
第二 = i
步数 = 步数 + 1
if 牌[第一] = 牌[第二] {
翻面[第一] = 2
翻面[第二] = 2
已配对 = 已配对 + 1
第一 = 0
第二 = 0
标签_状态.Text = join("已配对 ",已配对," / ",对数)
if 已配对 = 对数 {
锁定 = true
标签_状态.Text = "全部配对成功"
计时器_计时.TimerEnabled = false
秒数 = floor((计时器_计时.SystemTime() - 开始时刻) / 1000)
var 旧步 = 微数据库1.GetValue(join("步数",对数),1000000)
var 旧秒 = 微数据库1.GetValue(join("秒数",对数),1000000)
if 步数 < 旧步 or (步数 = 旧步 and 秒数 < 旧秒) {
微数据库1.StoreValue(join("步数",对数),步数)
微数据库1.StoreValue(join("秒数",对数),秒数)
微数据库1.StoreValue(join("最佳",对数),join(步数," 步 / ",秒数," 秒"))
标签_最佳.Text = join("最佳:",步数," 步 / ",秒数," 秒")
}
}
} else {
锁定 = true
计时器_翻回.TimerEnabled = true
标签_状态.Text = "不匹配,稍后翻回"
}
}
}
绘制()
标签_成绩.Text = join(步数," 步 / ",秒数," 秒")
}
}
}

中途检查与排错

本课以下控制与数据流已执行最终归档中的真实积木检查。请在伴侣或安装的 APK 中按相同场景操作,记录实际结果;自动检查通过不代表手机已实测。

  1. 开局8张卡片。
  2. 边界不越界。
  3. 洗牌/初始化保留每种两张。
  4. 重复点同牌不计分。
  5. 不匹配延时锁、禁止第三张。
  6. 新局停止旧延时。
  7. 完整配对、一次胜利。
  8. 六对难度与真实耗时。
  9. 四对最佳成绩重启恢复。

排查时先确定出错的是输入、状态、数据读取还是显示;用标签暂时显示关键值,每次只改变一个条件。

界面图是积木执行后的画布近似预览;计时器、绘制与系统控件在设备上的实际表现仍需运行检查。

两个理解题与独立改造

  1. 四对 4 步 20 秒、六对 6 步 10 秒,谁更好?
  2. 为什么不能只保存“4 步 / 20 秒”这个文本用于比较?

独立改造: 把规则改为先比时间,再比步数,写出比较条件。

先完成自己的工程,再对照答案。检查成功路径,也检查空数据、重复操作和取消;写出你改动的规则。

查看预测与练习参考答案

预测: 本课不跨难度比较;各自保留自己的最佳。相同难度先比步数,再比耗时。

追踪: 比较规则需要独立数值。直接按文本比较会得到字典序,并混淆难度。

改造思路: 新秒<旧秒,或秒相等且新步<旧步时保存。同步修改提示和测试卡,避免代码与规则不一致。

完成与下一步

保存自己的工程并导出 .aia;给文件命名以区分本课作业和参考源码。请用自己的话解释本课知识,并展示一次失败输入的处理。

上一课 · 下一课:数据驱动的毕业游戏

文档反馈