{"slug": "show-hn-sokoban-ai-solver", "title": "Show HN: Sokoban AI Solver", "summary": "A new web-based Sokoban puzzle solver, built by developer Michael Kornreich, solves boards 1–14 to the proven optimal move count in milliseconds using a JavaScript port of a native C++ A* search algorithm, while board 15's 184-move optimum was computed offline in about 5 seconds across 24 cores and is replayed from a precomputed solution. The solver uses macro-push A*, compact bitmask states, a dial bucket queue, and deadlock pruning to handle millions of states efficiently in a browser.", "body_md": "# Sokoban\n\nSokoban (\"warehouse keeper\") is a 1980s puzzle: push every box onto a goal. In this variant\nthe keeper must *also* finish on a goal.\n\n**0** Optimal:\n\n**–**\n\n## How to play & the rules\n\nThe warehouse is a grid. On each step the keeper moves one square up, down, left or right.\nThe keeper **cannot** walk into a wall or a box. It **can push a single box** if the\nsquare just beyond the box (in the push direction) is empty floor or a goal. Only one box\nmoves per step, and a box can be pushed *out* of a goal again to make room.\n\n-\n**Controls:** arrow keys or`W A S D`\n\n, or the on-screen pad.**Undo** steps back.**Reset** restores the board. -\n**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. -\n**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.\n\n## How the AI solver works\n\nSokoban is an A* search problem, but a naive version that explores one keeper step at a\ntime explodes on crowded boards. What runs here is a\n**plain-JavaScript port of a native C++ optimal solver** I wrote. It returns the\n*provably fewest-moves*\nsolution, not just some solution:\n\n-\n**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. -\n**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. -\n**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. -\n**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).\n\nBoards 1–14 are solved live to the **proven optimum** in milliseconds (the move\ncounts shown as \"Optimal\" above are exactly what this solver returns). Board 15. The 8-box\nmaze. Is the exception: its optimal search explores\n**~49 million states and needs >1 GB**, which would take far too long to\nrun inside a browser tab. So its optimum (**184 moves**) was computed\n*offline* by the native C++ build of this exact algorithm (a parallel A* search,\n~5 s across 24 cores) and verified by replay, and the page simply\n**plays that precomputed solution back**. That is why board 15's answer is hardcoded\nrather than searched here.\n\nBuilt from\n[my Sokoban solver](https://github.com/mkornreich/sokoban).\n[About Sokoban →](https://en.wikipedia.org/wiki/Sokoban)", "url": "https://wpnews.pro/news/show-hn-sokoban-ai-solver", "canonical_source": "https://mkornreich.me/projects/sokoban/", "published_at": "2026-08-17 13:07:00+00:00", "updated_at": "2026-08-17 13:42:12.717073+00:00", "lang": "en", "topics": ["artificial-intelligence", "ai-research", "ai-tools"], "entities": ["Michael Kornreich", "Sokoban", "GitHub"], "alternates": {"html": "https://wpnews.pro/news/show-hn-sokoban-ai-solver", "markdown": "https://wpnews.pro/news/show-hn-sokoban-ai-solver.md", "text": "https://wpnews.pro/news/show-hn-sokoban-ai-solver.txt", "jsonld": "https://wpnews.pro/news/show-hn-sokoban-ai-solver.jsonld"}}