本文的目的

公开滑块拼图AI实验中使用的全部源代码。只有展开文件时才会加载代码。

使用的模型

  • DQN:Stable-Baselines3。观测是4×4的方块编号,动作是空格的上下左右4种移动,奖励是把每个方块到其正确位置剩余的曼哈顿距离相加后取负值。第1篇中的无限反复就是由这个奖励造成的。
  • 模仿学习(BC):先让DQN策略学习人亲手解出的记录和C++教师(A*)生成的解法
  • Planner·Executor:两个PyTorch CNN(卷积32→64通道)。Planner选择下一个要归位的方块,Executor选择移动该方块的一步。用DAgger补充数据,也就是把策略出错的局面重新用教师的答案进行标注。
  • 世界模型:用C++引擎模拟之后的几步,并根据预测盘面进度(0~1)的ValueNet分数来选择着法。
  • VLM:Hugging Face上的Qwen2.5-VL-3B-Instruct。给它拼图盘面图像和可走着法列表,以JSON形式接收下一步。

辅助使用的东西

  • C++教师(PuzzleTeacher·Planner·Executor):用于生成演示和作为评分标准。在研究模式下,不会覆盖智能体给出的着法。
  • agent_loop_guard:当DQN或VLM反复出现同一盘面时,用缩短曼哈顿距离的着法让它跳出来的安全装置
  • 网页游戏中的AI解题:不是训练出来的模型,而是在浏览器内运行的加权A*搜索(曼哈顿距离 + 线性冲突)

重新运行的结果

模仿学习即使重复40次,与教师选择相同着法的比例也停在了71.1%。

模仿学习准确率。教师(A*)解法71.1%,Executor解法63.1%
模仿学习准确率。教师(A*)解法71.1%,Executor解法63.1%

在相同条件下重新运行了打乱80步的盘面。训练出来的模型一局都没能完成,只有用代码写入了环规则的C++ Executor全部解开了。

打乱80步的盘面被完整还原的比例。DQN、曼哈顿、随机0/50,Planner·Executor神经网络0/10,C++ Executor 50/50
打乱80步的盘面被完整还原的比例。DQN、曼哈顿、随机0/50,Planner·Executor神经网络0/10,C++ Executor 50/50

Planner·Executor神经网络在选择下一个方块时与教师的一致率为83%,在选择一步时为40%,连第一行都没能完成。世界模型解开了全部10局,但关掉ValueNet再运行,着法顺序也完全一样。解开盘面的不是ValueNet,而是在其内部运行的C++ Executor。

我们给Qwen2.5-VL-3B盘面图片和可走着法,每一步都直接问它。它连只打乱4步的盘面都解不开。20局全部都是在两个格子之间往返,或者无休止地转动2×2的四个格子。它知道怎么转动环,却不知道什么时候该停下来。

Qwen2.5-VL-3B的反复模式。打乱4步的盘面:往返4、转圈6;打乱10步的盘面:往返2、转圈8;完成0
Qwen2.5-VL-3B的反复模式。打乱4步的盘面:往返4、转圈6;打乱10步的盘面:往返2、转圈8;完成0

文件夹结构

  • src:Qt6/C++拼图引擎、供Python使用的C API、Planner·Executor·Teacher、Qt界面和TCP训练服务器
  • 根目录下的.py:Gymnasium环境、演示生成、DQN·BC·Planner/Executor·世界模型训练、Qt连接客户端、评估模拟
  • web:Next.js网页拼图界面

服务器部署设置、监控与自动化脚本、训练数据和模型权重、拼图图片文件都不在公开范围内。广告等网站运营代码和配置文件、调试用工具也被去掉了,所以部分import和README中的scripts路径指向的是未公开的文件。

完整源代码

73 个文件 · 19,290 行 — 展开文件夹后点击文件即可加载代码。

项目根目录41 个文件
agent_loop_guard.pypython · 275 行 · 9KB

正在加载代码…

CMakeLists.txttext · 64 行 · 2KB

正在加载代码…

dqn_sim.pypython · 257 行 · 9KB

正在加载代码…

engine_world_model.pypython · 256 行 · 8KB

正在加载代码…

generate_executor_demos.pypython · 128 行 · 4KB

正在加载代码…

generate_pe_recovery_demos.pypython · 199 行 · 6KB

正在加载代码…

generate_planner_demos.pypython · 77 行 · 2KB

正在加载代码…

generate_teacher_demos.pypython · 207 行 · 6KB

正在加载代码…

generate_wm_labels.pypython · 101 行 · 3KB

正在加载代码…

local_puzzle_env.pypython · 223 行 · 8KB

正在加载代码…

pe_dagger_collect.pypython · 217 行 · 8KB

正在加载代码…

pe_nets.pypython · 145 行 · 5KB

正在加载代码…

pe_segment_sim.pypython · 159 行 · 5KB

正在加载代码…

pe_sim.pypython · 243 行 · 8KB

正在加载代码…

pe_targets.pypython · 71 行 · 2KB

正在加载代码…

plan_agent.pypython · 310 行 · 11KB

正在加载代码…

plan_obs.pypython · 18 行 · 661B

正在加载代码…

plan_puzzle_env.pypython · 101 行 · 4KB

正在加载代码…

plan_sim.pypython · 262 行 · 8KB

正在加载代码…

planner_obs.pypython · 17 行 · 556B

正在加载代码…

PROJECT_PURPOSE.mdmarkdown · 149 行 · 7KB

正在加载代码…

puzzle_c_bindings.pypython · 193 行 · 7KB

正在加载代码…

qt_dqn_sim.pypython · 293 行 · 10KB

正在加载代码…

qt_pe_client.pypython · 738 行 · 23KB

正在加载代码…

qt_rl_client.pypython · 198 行 · 7KB

正在加载代码…

qt_vlm_client.pypython · 494 行 · 18KB

正在加载代码…

qt_vlm_sim.pypython · 324 行 · 11KB

正在加载代码…

qt_wm_client.pypython · 200 行 · 7KB

正在加载代码…

README.mdmarkdown · 139 行 · 5KB

正在加载代码…

requirements-vlm.txttext · 8 行 · 153B

正在加载代码…

requirements.txttext · 4 行 · 40B

正在加载代码…

segment_plan_ko.pypython · 42 行 · 2KB

正在加载代码…

train_bc_from_demos.pypython · 145 行 · 5KB

正在加载代码…

train_pe.pypython · 327 行 · 11KB

正在加载代码…

train_plan_bc.pypython · 152 行 · 5KB

正在加载代码…

train_puzzle_rl.pypython · 358 行 · 13KB

正在加载代码…

train_world_model.pypython · 135 行 · 5KB

正在加载代码…

wm_nets.pypython · 54 行 · 2KB

正在加载代码…

world_model_agent.pypython · 183 行 · 7KB

正在加载代码…

world_model_sim.pypython · 135 行 · 4KB

正在加载代码…

world_obs.pypython · 38 行 · 1KB

正在加载代码…

src/19 个文件
src/demo_sim.cppc++ · 540 行 · 18KB

正在加载代码…

src/main_window.cppc++ · 2,089 行 · 66KB

正在加载代码…

src/main_window.hc++ · 196 行 · 7KB

正在加载代码…

src/main.cppc++ · 68 行 · 2KB

正在加载代码…

src/puzzle_c_api.cppc++ · 400 行 · 12KB

正在加载代码…

src/puzzle_engine.cppc++ · 546 行 · 15KB

正在加载代码…

src/puzzle_engine.hc++ · 110 行 · 4KB

正在加载代码…

src/puzzle_executor.cppc++ · 519 行 · 19KB

正在加载代码…

src/puzzle_executor.hc++ · 53 行 · 2KB

正在加载代码…

src/puzzle_plan_log.hc++ · 24 行 · 547B

正在加载代码…

src/puzzle_planner.cppc++ · 4,414 行 · 152KB

正在加载代码…

src/puzzle_planner.hc++ · 53 行 · 2KB

正在加载代码…

src/puzzle_solve_waves.cppc++ · 110 行 · 3KB

正在加载代码…

src/puzzle_solve_waves.hc++ · 33 行 · 1KB

正在加载代码…

src/puzzle_teacher.cppc++ · 748 行 · 22KB

正在加载代码…

src/puzzle_teacher.hc++ · 31 行 · 940B

正在加载代码…

src/puzzle_tile_action.hc++ · 95 行 · 3KB

正在加载代码…

src/puzzle_widget.cppc++ · 148 行 · 4KB

正在加载代码…

src/puzzle_widget.hc++ · 47 行 · 1KB

正在加载代码…

web/13 个文件
web/app/globals.csscss · 50 行 · 912B

正在加载代码…

web/app/layout.tsxtsx · 33 行 · 969B

正在加载代码…

web/app/page.module.csscss · 173 行 · 3KB

正在加载代码…

web/app/page.tsxtsx · 95 行 · 3KB

正在加载代码…

web/app/play/page.tsxtsx · 338 行 · 9KB

正在加载代码…

web/app/play/play.module.csscss · 152 行 · 2KB

正在加载代码…

web/components/PuzzleBoard.module.csscss · 27 行 · 396B

正在加载代码…

web/components/PuzzleBoard.tsxtsx · 37 行 · 1KB

正在加载代码…

web/lib/levels.tstypescript · 134 行 · 4KB

正在加载代码…

web/lib/progress.tstypescript · 37 行 · 1KB

正在加载代码…

web/lib/puzzle.tstypescript · 145 行 · 4KB

正在加载代码…

web/lib/solver.tstypescript · 181 行 · 5KB

正在加载代码…

web/package.jsonjson · 25 行 · 557B

正在加载代码…