展示 HN:推箱子 AI 求解器
Show HN: Sokoban AI Solver

原始链接: https://mkornreich.me/projects/sokoban/

推箱子(Sokoban)是一款 1980 年代的经典逻辑益智游戏,玩家需要将箱子推到指定位置。此版本有一个独特的变体:玩家本人也必须停留在目标格上,因此所需的目标格数量比箱子数多一个。 本网页版实现采用了先进的“移动最优宏推 A*”算法,旨在寻找最少的移动步数。为了应对游戏的计算复杂性,求解器采用了多项技术优化: * **状态压缩:** 使用位掩码(bitmasking)将游戏状态表示为紧凑的键,使数百万个状态仅占用极少的内存。 * **高效搜索:** 使用桶队列(bucket queue)和缓存友好、无分配的哈希表来加速寻路。 * **剪枝:** 采用死锁检测来排除无法解决的配置。 虽然求解器能在几毫秒内处理大多数关卡,但复杂的棋盘(如 8 箱迷宫)则需要离线并行处理。本项目是一个高度优化的演示,展示了 A* 搜索技术在经典网格益智游戏中的应用。

关于“推箱子(Sokoban)AI 求解器”的最新 Hacker News 讨论,引发了关于人工智能演进的广泛争论。许多用户指出,虽然现代人工智能已成为大语言模型(LLM)的代名词,但该项目代表了“经典”AI——它依赖于 A* 搜索、启发式算法和优化等技术,而非神经网络。 讨论突出了几个关键主题: * **跨越时代:** 评论者讨论了通过“老派”符号逻辑和本体论来约束大语言模型,从而实现未来突破的可能性,并提出演绎推理与归纳推理是互补的。 * **复杂性与求解器:** 专家们探讨了推箱子(属于 NP-hard 问题)的计算挑战,指出求解器的效率取决于对搜索空间的剪枝(如对可达区域进行泛洪填充),而非仅仅依赖暴力搜索。 * **难度指标:** 除了移动步数外,用户还探讨了“语境切换”(在推动不同箱子之间交替)如何作为衡量人类感知谜题难度的更好指标。 总而言之,对于那些对搜索算法历史以及在生成式 AI 主导的时代下,经典逻辑依然具有重要意义感兴趣的人来说,该项目不仅是一个技术触点,更是一次怀旧之旅。
相关文章

原文
Sokoban. Menachem Kornreich

Sokoban ("warehouse keeper") is a 1980s puzzle: push every box onto a goal. In this variant the keeper must also finish on a goal.

Moves: 0 Optimal: –

Keeper (you) Box Goal Box on goal Wall

How to play & the rules

The warehouse is a grid. On each step the keeper moves one square up, down, left or right. The keeper cannot walk into a wall or a box. It can push a single box if the square just beyond the box (in the push direction) is empty floor or a goal. Only one box moves per step, and a box can be pushed out of a goal again to make room.

  • Controls: arrow keys or W A S D, or the on-screen pad. Undo steps back. Reset restores the board.
  • Goal: the puzzle is won when every movable entity. Every box and the keeper. Is sitting on a goal. That is why each board has one more goal than it has boxes: the last goal is for the keeper.
  • Objective: reach that state in as few moves as possible. For several boards the optimal move count is known and shown above. The AI (with an admissible heuristic) returns an optimal solution on the boards it can search exhaustively.
How the AI solver works

Sokoban is an A* search problem, but a naive version that explores one keeper step at a time explodes on crowded boards. What runs here is a plain-JavaScript port of a native C++ optimal solver I wrote. It returns the provably fewest-moves solution, not just some solution:

  • Move-optimal macro-push A*. Each search edge is a whole box push costed as (the keeper's shortest walk to the push spot) + 1, so the total is the true minimum number of keeper moves, while the search skips over the individual walking steps.
  • Compact bitmask states. The boxes are packed into a 32-bit integer over the board's reachable "live" cells and the keeper into one more number, so a whole state is a single ~8-byte key instead of a ~1 KB object. Millions of states fit in tens of MB.
  • Dial bucket queue + open-addressed hash. The A* frontier is a bucket queue keyed by cost, and the visited set (with the solution's parent links) lives in a flat typed-array hash. Allocation-free and cache-friendly.
  • Deadlock pruning. A static dead-square table (reverse-reachability from the goals) plus a freeze check discard provably-unsolvable positions, guided by a wall-aware push-distance lower bound that keeps A* admissible (hence optimal).

Boards 1–14 are solved live to the proven optimum in milliseconds (the move counts shown as "Optimal" above are exactly what this solver returns). Board 15. The 8-box maze. Is the exception: its optimal search explores ~49 million states and needs >1 GB, which would take far too long to run inside a browser tab. So its optimum (184 moves) was computed offline by the native C++ build of this exact algorithm (a parallel A* search, ~5 s across 24 cores) and verified by replay, and the page simply plays that precomputed solution back. That is why board 15's answer is hardcoded rather than searched here.

Built from my Sokoban solver. About Sokoban →


联系我们 contact @ memedata.com