---
title: 深入探讨如何设计一个分层挑战性编程题目：以命令行推箱子游戏及其核心自动求解器有效区分AI编程能力与算法水平
created: 2026-03-30
updated: 2026-03-30
type: summary
tags: ["algorithm", "challenge", "notes", "sokoban", "telegram"]
external: http://go/ui/posts/2302/
status: inbox
---

好问题。让我先想想什么样的题目有足够的「梯度」——

**核心思路：选一个逻辑层次多、模块间有依赖的游戏**

扫雷的问题是它的难点比较集中（flood fill），其他都是体力活。要拉开差距，需要一个游戏满足：

1. **基础层**：弱 AI 也能做到（能跑起来、基本渲染）
2. **中间层**：需要真正理解游戏逻辑（AI 行为、状态机）
3. **高级层**：需要算法能力（寻路、评分、优化）
4. **加分层**：系统设计能力（难度分级、存档、完整体验）

我的选择是：

---

## 题目：命令行版「推箱子 + 自动求解提示」(Sokoban)

**为什么选这个：**

| 层次 | 要求 | 能力体现 |
|------|------|--------|
| 基础 | 地图渲染、移动、推箱子碰撞 | 基本编程 |
| 中级 | 多关卡、撤销(undo)、胜负判定 | 状态管理 |
| 高级 | BFS/A* 自动求解器，给出提示 | 算法能力 |
| 加分 | 步数统计、最优解对比、关卡编辑器 | 系统设计 |

求解器是核心区分点：弱 AI 根本不会写，强 AI 需要正确实现状态哈希 + BFS + 剪枝才能在合理时间内出解。

---

现在我来生成题目 prompt 和评测脚本：现在写题目 prompt，以及一个参考实现来验证评测器：现在写参考实现来验证评测器：评测器工作正常，108/150（72%，A 优秀）。几个扣分是评测器的文本匹配和我用了 Unicode 字符（`█` 代替 `#`）、以及 `quit` 被当作 `q` 处理了。修一下再把文件输出：129/150（86%，S 顶级）。剩余两个扣分：T4 胜利（随机操作概率低，属于测试局限）、T8 最后一项（`qqqqq` 触发了 q 退出，属于 `q` 本来就是合法退出键）。评测器和游戏都运转良好，输出文件：三个文件：

- **PROMPT.md** — 题目，直接喂给其他 AI
- **test_sokoban.py** — 评测器，`python test_sokoban.py main.py`
- **main_sokoban.py** — 我的参考实现（129/150，S 级）

---

**为什么这题比扫雷难很多、区分度更高：**

| 能力层 | 内容 | 分值 | 弱 AI 能完成？ |
|--------|------|------|--------------|
| 基础 | 渲染、移动、碰撞 | ~47 | ✓ 大部分能 |
| 中级 | Undo 历史、Reset、多关卡 | ~32 | △ 一半能 |
| 核心 | **BFS 求解器**（状态压缩、去重、超时） | 35 | ✗ 弱 AI 基本做不到 |
| 加分 | A* 优化、步数对比、深度 Undo | ~14 | ✗ 只有强 AI |

求解器是真正的区分点：它要求 AI 理解推箱子状态空间（玩家位置 × 所有箱子位置），实现正确的状态哈希去重，并处理无解/超时边界情况——这是对算法能力的直接考验，不是"写对了就行"的体力题。
