Scratch少儿编程第二十例:人工智能猜数字

项目介绍

这是一个经典的人工智能猜数字游戏,电脑使用二分查找算法智能猜测玩家心中所想的数字,通过游戏学习算法思维和搜索策略,理解人工智能的基本原理。

学习目标

  • ✅ 掌握二分查找算法原理
  • ✅ 学习搜索策略和优化方法
  • ✅ 理解人工智能决策过程
  • ✅ 培养逻辑思维和算法意识

详细步骤

第一步:创建游戏基础系统

初始化游戏设置:

当绿旗被点击
变量 [猜测次数 v] 设为 [0]
变量 [猜测记录 v] 设为 []
变量 [游戏状态 v] 设为 [准备中]
变量 [猜测下限 v] 设为 [1]
变量 [猜测上限 v] 设为 [100]
变量 [当前猜测 v] 设为 [0]
变量 [算法模式 v] 设为 [二分查找]

列表 [猜测历史 v] 删除全部项目
列表 [反馈记录 v] 删除全部项目

切换背景为 [游戏背景 v]
说 [人工智能猜数字游戏启动!] (1) 秒
等待 (1) 秒
说 [请想一个1-100之间的数字,我会猜出来!] (2) 秒
广播 [开始游戏 v]

第二步:实现二分查找算法

二分查找核心算法:

当接收到 [开始游戏 v]
将 [游戏状态 v] 设为 [思考中]
将 [猜测次数 v] 设为 [0]
将 [猜测下限 v] 设为 [1]
将 [猜测上限 v] 设为 [100]

说 [正在分析最优猜测策略...] (1) 秒
等待 (1) 秒

广播 [进行猜测 v]

当接收到 [进行猜测 v]
如果 <(游戏状态) = [思考中]> 那么
  将 [猜测次数 v] 增加 (1)
  
  如果 <(算法模式) = [二分查找]> 那么
    将 [当前猜测 v] 设为 (四舍五入 (((猜测下限) + (猜测上限)) / (2)))
    说 (连接 (连接 [第] (连接 (猜测次数) [次猜测:])) (当前猜测)) (2) 秒
  else
    如果 <(算法模式) = [随机猜测]> 那么
      将 [当前猜测 v] 设为 (在 (猜测下限) 到 (猜测上限) 间随机选一个数)
      说 (连接 (连接 [随机猜测:] (当前猜测)) []) (2) 秒
    else
      如果 <(算法模式) = [线性搜索]> 那么
        将 [当前猜测 v] 设为 (猜测下限)
        说 (连接 (连接 [顺序猜测:] (当前猜测)) []) (2) 秒
      end
    end
  end
  
  添加 (当前猜测) 到 [猜测历史 v]
  广播 [等待反馈 v]
end

第三步:创建玩家反馈系统

反馈按钮和逻辑:

当角色被点击  // 猜大了按钮
如果 <(游戏状态) = [等待反馈]> 那么
  播放声音 [反馈音效 v]
  说 [好的,我猜大了!] (1) 秒
  将 [猜测上限 v] 设为 ((当前猜测) - (1))
  添加 [大了] 到 [反馈记录 v]
  广播 [分析反馈 v]
end

当角色被点击  // 猜小了按钮
如果 <(游戏状态) = [等待反馈]> 那么
  播放声音 [反馈音效 v]
  说 [明白了,我猜小了!] (1) 秒
  将 [猜测下限 v] 设为 ((当前猜测) + (1))
  添加 [小了] 到 [反馈记录 v]
  广播 [分析反馈 v]
end

当角色被点击  // 猜对了按钮
如果 <(游戏状态) = [等待反馈]> 那么
  播放声音 [胜利音效 v]
  说 [太棒了!我猜对了!] (2) 秒
  添加 [正确] 到 [反馈记录 v]
  广播 [游戏胜利 v]
end

第四步:反馈分析和策略调整

智能分析反馈:

当接收到 [分析反馈 v]
如果 <(猜测下限) > (猜测上限)> 那么
  说 [等等...数字范围出错了!你改变数字了吗?] (2) 秒
  广播 [重新开始 v]
否则
  如果 <(猜测下限) = (猜测上限)> 那么
    说 [我知道了!数字一定是] (1) 秒
    等待 (1) 秒
    说 (猜测下限) (2) 秒
    广播 [最终确认 v]
  否则
    说 [正在重新计算...] (1) 秒
    等待 (0.5) 秒
    广播 [进行猜测 v]
  end
end

当接收到 [最终确认 v]
说 [这是最后的数字吗?] (1) 秒
将 [游戏状态 v] 设为 [确认中]

第五步:游戏胜利处理

胜利统计和分析:

当接收到 [游戏胜利 v]
将 [游戏状态 v] 设为 [胜利]
变量 [理论最优次数 v] 设为 ([log v] ((100)) / ([log v] (2)))  // log2(100) ≈ 7

说 [=== 游戏统计 ===] (2) 秒
等待 (1) 秒
说 (连接 (连接 [猜测次数:] (猜测次数)) [次]) (2) 秒
等待 (1) 秒
说 (连接 (连接 [理论最优次数:] (理论最优次数)) [次]) (2) 秒
等待 (1) 秒

如果 <(猜测次数) < (理论最优次数)> 那么
  说 [表现超常!运气很好!] (2) 秒
否则
  如果 <(猜测次数) = (理论最优次数)> 那么
    说 [完美表现!达到理论最优!] (2) 秒
  else
    说 [表现良好!接近最优解!] (2) 秒
  end
end

广播 [显示猜测过程 v]

完整代码示例

游戏主控制器:

当绿旗被点击
变量 [游戏状态 v] 设为 [准备中]
变量 [猜测次数 v] 设为 [0]
变量 [猜测下限 v] 设为 [1]
变量 [猜测上限 v] 设为 [100]
变量 [当前猜测 v] 设为 [0]
变量 [算法模式 v] 设为 [二分查找]
变量 [游戏难度 v] 设为 [简单]  // 简单:1-100, 中等:1-500, 困难:1-1000

列表 [猜测历史 v] 删除全部项目
列表 [反馈记录 v] 删除全部项目
列表 [搜索空间 v] 删除全部项目

// 初始化搜索空间(用于可视化)
重复执行 (100) 次
  添加 (i) 到 [搜索空间 v]
end

说 [人工智能猜数字游戏] (1) 秒
等待 (1) 秒
说 [选择一个难度级别] (1) 秒
广播 [显示难度选择 v]

当接收到 [开始游戏 v]
如果 <(游戏难度) = [简单]> 那么
  将 [猜测上限 v] 设为 [100]
否则
  如果 <(游戏难度) = [中等]> 那么
    将 [猜测上限 v] 设为 [500]
  否则
    将 [猜测上限 v] 设为 [1000]
  end
end

将 [游戏状态 v] 设为 [思考中]
将 [猜测次数 v] 设为 [0]
将 [猜测下限 v] 设为 [1]

说 (连接 (连接 [数字范围:1-] (猜测上限)) []) (2) 秒
等待 (1) 秒
说 [请想好你的数字...] (1) 秒
等待 (2) 秒
说 [游戏开始!] (1) 秒

广播 [进行猜测 v]

智能猜测算法完整实现:

当接收到 [进行猜测 v]
如果 <(游戏状态) = [思考中]> 那么
  将 [猜测次数 v] 增加 (1)
  
  如果 <(算法模式) = [二分查找]> 那么
    // 标准二分查找
    将 [当前猜测 v] 设为 (四舍五入 (((猜测下限) + (猜测上限)) / (2)))
    说 (连接 (连接 [第] (连接 (猜测次数) [次猜测:])) (当前猜测)) (2) 秒
    说 [这个数字比你想的数字大还是小?] (2) 秒
  else
    如果 <(算法模式) = [随机猜测]> 那么
      // 在剩余范围内随机猜测
      将 [当前猜测 v] 设为 (在 (猜测下限) 到 (猜测上限) 间随机选一个数)
      说 (连接 (连接 [随机猜测:] (当前猜测)) []) (2) 秒
    否则
      如果 <(算法模式) = [线性搜索]> 那么
        // 顺序搜索
        将 [当前猜测 v] 设为 (猜测下限)
        说 (连接 (连接 [顺序猜测:] (当前猜测)) []) (2) 秒
      否则
        如果 <(算法模式) = [智能调整]> 那么
          // 基于反馈的智能调整
          广播 [智能调整猜测 v]
        end
      end
    end
  end
  
  添加 (当前猜测) 到 [猜测历史 v]
  广播 [更新搜索空间 v]
  广播 [等待反馈 v]
end

当接收到 [智能调整猜测 v]
变量 [调整因子 v] 设为 [0]

// 分析最近的反馈模式
如果 <(反馈记录 v) 的长度 > [2]> 那么
  变量 [最近反馈 v] 设为 ([反馈记录 v] 的最后一项)
  变量 [前次反馈 v] 设为 ([反馈记录 v] 的第 ((反馈记录 v) 的长度 - (1)) 项)
  
  如果 <<(最近反馈) = [大了]> 与 <(前次反馈) = [大了]>> 那么
    将 [调整因子 v] 设为 [-10]  // 连续猜大,更激进地减小
  否则
    如果 <<(最近反馈) = [小了]> 与 <(前次反馈) = [小了]>> 那么
      将 [调整因子 v] 设为 [10]  // 连续猜小,更激进地增加
    end
  end
end

将 [当前猜测 v] 设为 (四舍五入 ((((猜测下限) + (猜测上限)) / (2)) + (调整因子)))
说 (连接 (连接 [智能猜测:] (当前猜测)) []) (2) 秒

搜索空间可视化:

当接收到 [更新搜索空间 v]
清空
将笔的粗细设为 (2)

// 绘制搜索范围
将笔的颜色设为 [#0000ff]
移到 x: (-180) y: (0)
落笔
移动 (360) 步
抬笔

// 标记当前范围
将笔的颜色设为 [#ff0000]
变量 [范围长度 v] 设为 ((猜测上限) - (猜测下限))
变量 [范围比例 v] 设为 ((范围长度) / (100))
变量 [标记宽度 v] 设为 ((范围比例) * (360))

移到 x: ((-180) + (((猜测下限) - (1)) * (3.6))) y: (20)
落笔
移动 (标记宽度) 步
抬笔

// 标记历史猜测点
将笔的颜色设为 [#00ff00]
变量 [i v] 设为 [1]
重复执行直到 <(i) > (猜测历史 v) 的长度>
  变量 [历史猜测 v] 设为 ([猜测历史 v] 的第 (i) 项)
  变量 [x位置 v] 设为 ((-180) + (((历史猜测) - (1)) * (3.6)))
  
  移到 x: (x位置) y: (0)
  落笔
  移动 (10) 步
  抬笔
  
  将 [i v] 增加 (1)
end

// 标记当前猜测
将笔的颜色设为 [#ffff00]
变量 [当前x v] 设为 ((-180) + (((当前猜测) - (1)) * (3.6)))
移到 x: (当前x) y: (-20)
落笔
移动 (20) 步
抬笔

说 (连接 (连接 [搜索范围:] (猜测下限)) (连接 [-] (猜测上限))) (2) 秒

创意扩展

版本一:学习模式

当接收到 [开启学习模式 v]
说 [学习模式开启!我会记住你的反馈模式] (2) 秒
变量 [学习模式 v] 设为 [开启]
列表 [玩家模式 v] 删除全部项目

当接收到 [分析反馈 v]
如果 <(学习模式) = [开启]> 那么
  变量 [反馈模式 v] 设为 (连接 (连接 (当前猜测) [->]) ([反馈记录 v] 的最后一项))
  添加 (反馈模式) 到 [玩家模式 v]
  
  如果 <(玩家模式 v) 的长度 > [5]> 那么
    说 [我发现了你的选择模式!] (1) 秒
    广播 [调整猜测策略 v]
  end
end

当接收到 [调整猜测策略 v]
变量 [偏好分析 v] 设为 [0]
变量 [i v] 设为 [1]

重复执行直到 <(i) > (玩家模式 v) 的长度>
  如果 <([玩家模式 v] 的第 (i) 项) 包含 [小了]> 那么
    将 [偏好分析 v] 增加 (1)
  否则
    如果 <([玩家模式 v] 的第 (i) 项) 包含 [大了]> 那么
      将 [偏好分析 v] 增加 (-1)
    end
  end
  将 [i v] 增加 (1)
end

如果 <(偏好分析) > [2]> 那么
  说 [你倾向于选择较大的数字] (1) 秒
  变量 [猜测偏移 v] 设为 [5]
否则
  如果 <(偏好分析) < [-2]> 那么
    说 [你倾向于选择较小的数字] (1) 秒
    变量 [猜测偏移 v] 设为 [-5]
  end
end

版本二:挑战模式

当接收到 [开始挑战模式 v]
说 [挑战模式!我会尝试在最少次数内猜中] (2) 秒
变量 [挑战目标 v] 设为 (四舍五入 ([log v] ((猜测上限)) / ([log v] (2))))
说 (连接 (连接 [目标:] (挑战目标)) [次以内猜中]) (2) 秒

当接收到 [游戏胜利 v]
如果 <(猜测次数) < (挑战目标)> 那么
  说 [挑战成功!表现优异!] (2) 秒
  播放声音 [挑战成功 v]
否则
  说 [挑战失败,继续努力!] (2) 秒
end

当接收到 [时间挑战模式 v]
变量 [时间限制 v] 设为 [30]  // 30秒限制
重置计时器
说 (连接 (连接 [时间挑战:] (时间限制)) [秒内完成]) (2) 秒

重复执行直到 <<(游戏状态) = [胜利]> 或 <(计时器) > (时间限制)>>
  等待 (1) 秒
  说 (连接 (连接 [剩余时间:] ((时间限制) - (计时器))) [秒]) (1) 秒
end

如果 <(计时器) > (时间限制)> 那么
  说 [时间到!挑战失败] (2) 秒
end

版本三:反向游戏模式

当接收到 [开始反向游戏 v]
说 [反向游戏!现在你来猜我想的数字] (2) 秒
变量 [目标数字 v] 设为 (在 (1) 到 (100) 间随机选一个数)
变量 [玩家猜测次数 v] 设为 [0]
变量 [反向游戏状态 v] 设为 [进行中]

说 [我想好了一个1-100之间的数字] (1) 秒
说 [轮到你来猜了!] (1) 秒

重复执行直到 <(反向游戏状态) = [结束]>
  询问 [请输入你的猜测:] 并等待
  将 [玩家猜测次数 v] 增加 (1)
  
  如果 <(回答) = (目标数字)> 那么
    说 [猜对了!恭喜!] (2) 秒
    说 (连接 (连接 [你用了] (玩家猜测次数)) [次猜中]) (2) 秒
    将 [反向游戏状态 v] 设为 [结束]
  否则
    如果 <(回答) > (目标数字)> 那么
      说 [太大了!] (1) 秒
    否则
      说 [太小了!] (1) 秒
    end
  end
end

// 比较AI和人类的表现
说 [=== 表现对比 ===] (2) 秒
说 (连接 (连接 [AI猜测次数:] (猜测次数)) []) (2) 秒
说 (连接 (连接 [你的猜测次数:] (玩家猜测次数)) []) (2) 秒

高级功能

算法效率分析

当接收到 [分析算法效率 v]
变量 [二分查找次数 v] 设为 (四舍五入 ([log v] ((猜测上限)) / ([log v] (2))))
变量 [线性查找次数 v] 设为 (猜测上限)
变量 [随机查找期望 v] 设为 ((猜测上限) / (2))

说 [=== 算法效率分析 ===] (2) 秒
等待 (1) 秒
说 (连接 (连接 [二分查找理论次数:] (二分查找次数)) []) (2) 秒
等待 (1) 秒
说 (连接 (连接 [线性查找理论次数:] (线性查找次数)) []) (2) 秒
等待 (1) 秒
说 (连接 (连接 [随机查找期望次数:] (随机查找期望)) []) (2) 秒
等待 (1) 秒

// 计算实际效率
变量 [实际效率 v] 设为 (((猜测上限) - (猜测次数)) / (猜测上限)) * (100)
说 (连接 (连接 [本次实际效率:] (实际效率)) [%]) (2) 秒

多算法比较模式

当接收到 [开始算法比较 v]
说 [算法比较模式启动] (2) 秒
变量 [算法1猜测 v] 设为 [0]
变量 [算法2猜测 v] 设为 [0]
变量 [目标数字 v] 设为 (在 (1) 到 (100) 间随机选一个数)

// 算法1:二分查找
将 [算法模式 v] 设为 [二分查找]
将 [猜测下限 v] 设为 [1]
将 [猜测上限 v] 设为 [100]
变量 [算法1次数 v] 设为 [0]

重复执行直到 <(当前猜测) = (目标数字)>
  广播 [进行猜测 v]
  将 [算法1次数 v] 增加 (1)
  等待 (1) 秒
end

说 (连接 (连接 [二分查找用了] (算法1次数)) [次]) (2) 秒

// 算法2:随机查找
将 [算法模式 v] 设为 [随机猜测]
将 [猜测下限 v] 设为 [1]
将 [猜测上限 v] 设为 [100]
变量 [算法2次数 v] 设为 [0]

重复执行直到 <(当前猜测) = (目标数字)>
  广播 [进行猜测 v]
  将 [算法2次数 v] 增加 (1)
  等待 (1) 秒
end

说 (连接 (连接 [随机查找用了] (算法2次数)) [次]) (2) 秒

// 宣布胜者
如果 <(算法1次数) < (算法2次数)> 那么
  说 [二分查找获胜!] (2) 秒
否则
  说 [随机查找获胜!] (2) 秒
end

机器学习优化

当绿旗被点击
列表 [历史游戏数据 v] 删除全部项目
变量 [平均猜测次数 v] 设为 [0]
变量 [学习迭代 v] 设为 [0]

当接收到 [游戏胜利 v]
变量 [游戏数据 v] 设为 (连接 (连接 (连接 [次数:] (猜测次数)) [,模式:]) (算法模式))
添加 (游戏数据) 到 [历史游戏数据 v]

如果 <(历史游戏数据 v) 的长度 > [10]> 那么
  广播 [分析学习数据 v]
end

当接收到 [分析学习数据 v]
变量 [总次数 v] 设为 [0]
变量 [i v] 设为 [1]

重复执行直到 <(i) > (历史游戏数据 v) 的长度>
  变量 [数据项 v] 设为 ([历史游戏数据 v] 的第 (i) 项)
  变量 [次数开始位置 v] 设为 (数据项) 的第 (1) 个 [:]) 的字符位置
  变量 [次数结束位置 v] 设为 (数据项) 的第 (1) 个 [,]) 的字符位置
  变量 [游戏次数 v] 设为 (数据项) 的第 ((次数开始位置) + (1)) 到 ((次数结束位置) - (1)) 个字符)
  
  将 [总次数 v] 增加 (游戏次数)
  将 [i v] 增加 (1)
end

将 [平均猜测次数 v] 设为 ((总次数) / (历史游戏数据 v) 的长度)
将 [学习迭代 v] 增加 (1)

说 (连接 (连接 [经过] (学习迭代)) [轮学习]) (1) 秒
说 (连接 (连接 [平均猜测次数:] (平均猜测次数)) []) (1) 秒

如果 <(平均猜测次数) < [7]> 那么
  说 [AI表现优秀!] (1) 秒
否则
  说 [AI还有优化空间] (1) 秒
end

界面设计技巧

创建直观的游戏界面:

  1. 算法可视化:

    • 数字范围进度条显示搜索空间
    • 历史猜测点标记
    • 当前猜测突出显示
    • 搜索范围动态更新
  2. 控制面板:

    • 清晰的反馈按钮(大/小/正确)
    • 算法模式选择器
    • 游戏难度调节
    • 统计数据显示
  3. 教学元素:

    • 算法原理说明
    • 猜测过程分解
    • 效率对比图表
    • 学习进度展示

交互反馈优化:

当接收到 [等待反馈 v]
// 按钮闪烁提示
重复执行直到 <(游戏状态) ≠ [等待反馈]>
  将 [颜色 v] 特效增加 (20)
  等待 (0.5) 秒
  将 [颜色 v] 特效增加 (-20)
  等待 (0.5) 秒
end

当接收到 [进行猜测 v]
// 思考动画
重复 (3) 次
  切换到造型 [思考 v]
  等待 (0.3) 秒
  切换到造型 [猜测 v]
  等待 (0.3) 秒
end
切换到造型 [等待 v]

当接收到 [游戏胜利 v]
// 胜利动画
重复 (5) 次
  将 [亮度 v] 特效增加 (30)
  将大小增加 (10)
  等待 (0.2) 秒
  将 [亮度 v] 特效增加 (-30)
  将大小增加 (-10)
  等待 (0.2) 秒
end

教学提示

给家长的指导:

  1. 算法思维:帮助孩子理解二分查找的效率原理
  2. 数学概念:介绍对数和指数关系
  3. 策略思考:讨论不同搜索策略的优缺点

学习要点:

  • 算法效率:理解O(log n)和O(n)的时间复杂度差异
  • 问题分解:学习将大问题分解为小问题的策略
  • 优化思维:培养寻找最优解的意识

探索问题:

  • “为什么二分查找比随机查找更快?”
  • “最优猜测次数和数字范围有什么关系?”
  • “如何证明二分查找是最优策略?”

实际应用场景

学习场景:

  1. 算法入门:通过游戏理解经典算法
  2. 数学应用:实践对数和指数概念
  3. 思维训练:培养系统化问题解决能力

技术应用:

  1. 搜索算法:理解数据库索引原理
  2. 人工智能:学习决策树和优化策略
  3. 游戏设计:掌握智能NPC行为设计

调试技巧

常见问题解决:

Q:算法陷入死循环
A:检查边界条件,确保猜测上下限正确更新

Q:猜测次数过多
A:验证二分查找实现,检查整数除法处理

Q:范围显示错误
A:调试搜索空间可视化,确保坐标计算正确

项目成果

完成这个项目后,孩子将拥有:

  • 对二分查找算法的深入理解
  • 算法效率和优化思维
  • 人工智能决策过程的认识
  • 问题分析和解决的能力

扩展创意

鼓励孩子尝试:

  1. 实现其他搜索算法(插值查找、指数查找)
  2. 设计自适应学习算法
  3. 创建算法可视化教学工具
  4. 开发多人算法竞赛游戏

在算法的世界中探索,让每个猜测都成为智慧的火花! 🤖🔢🌟

更多推荐