📦

Sokoban

gameType: "sokoban"

Push-box puzzles where the player must push boxes onto goal positions. GameplayGen generates grids with walls, boxes, and goals, ensuring all empty cells are connected. Difficulty scales via wall density, box count, and required move distance. Every puzzle is validated for solvability with an optimal solution path.

Interactive Example

📦 Sokoban

Push boxes onto goal positions — optimal solution verified

difficulty: 0.55solvable ✓
🧑
Wall🧑 Player Box Goal

Optimal Solution

uurRRDldR9 moves

Grid Size

7×7

Boxes

2

Optimal Moves

9

Difficulty

0.55

Try it

await pf.generate({
  gameType: "sokoban",
  params: { width: 7, height: 7, boxes: 2 },
  count: 5,
  difficulty: { target: 0.50 }
})

API Parameters

ParamTypeRequiredDefaultDescription
widthnumberYes7Grid width. Minimum 4. Typical range 5–20.
heightnumberYes7Grid height. Minimum 4. Typical range 5–20.
boxCountnumberYesautoNumber of boxes (and goals). If not specified, auto-calculated from difficulty: 1 + floor(difficulty × 3). Range 1–10.

Common Request Options

ParamTypeRequiredDefaultDescription
countnumberYesHow many puzzles to generate.
difficulty.targetnumberNo0.5Numeric difficulty (0.0–1.0). Controls wall density (10–25%) and box-to-goal distance.
difficulty.curve"flat" | "ascending" | "descending" | "bell"No"flat"Difficulty distribution across the batch.
seednumberNoSeed for reproducible generation.

Generation Details

The Sokoban generator follows this process:

  1. Initialize grid with wall borders and empty interior
  2. Add internal walls based on difficulty (10–25% density), validating connectivity after each
  3. Place player at a random empty position
  4. Place goals at random empty positions
  5. Place boxes at empty positions, preferring distance ≥ 2 from their corresponding goal
  6. Validate: all empty cells must remain connected via flood fill
  7. Run solver to verify solvability and compute optimal move count

Content Output

ParamTypeRequiredDefaultDescription
widthnumberGrid width.
heightnumberGrid height.
gridSokobanCell[][]2D grid. Cell types: "empty", "wall", "box", "goal", "player", "box-on-goal", "player-on-goal".
playerStart[number, number]Player starting position [row, col].
boxes[number, number][]Initial box positions.
goals[number, number][]Goal positions.
walls[number, number][]All wall positions (border + internal).
boxCountnumberNumber of boxes.

Example Request

bash
curl -X POST https://api.gameplaygen.com/generate \
  -H "Authorization: Bearer gg_live_abc123..." \
  -H "Content-Type: application/json" \
  -d '{
    "gameType": "sokoban",
    "params": { "width": 8, "height": 8, "boxCount": 3 },
    "count": 5,
    "difficulty": { "target": 0.6 }
  }'

Example Response

json
{
  "content": [
    {
      "id": "gg_sok8r3f2",
      "gameType": "sokoban",
      "content": {
        "width": 8,
        "height": 8,
        "grid": [
          ["wall","wall","wall","wall","wall","wall","wall","wall"],
          ["wall","empty","empty","empty","empty","empty","empty","wall"],
          ["wall","empty","empty","box","empty","empty","wall","wall"],
          ["wall","empty","wall","empty","empty","box","empty","wall"],
          ["wall","empty","empty","empty","goal","wall","empty","wall"],
          ["wall","empty","goal","box","empty","empty","player","wall"],
          ["wall","empty","empty","empty","empty","goal","empty","wall"],
          ["wall","wall","wall","wall","wall","wall","wall","wall"]
        ],
        "playerStart": [5, 6],
        "boxes": [[2, 3], [3, 5], [5, 3]],
        "goals": [[4, 4], [5, 2], [6, 5]],
        "walls": [[0,0],[0,1],[0,2]],
        "boxCount": 3
      },
      "metrics": {
        "verified": true,
        "difficulty": 0.58,
        "balance": 0.92,
        "novelty": 1.0,
        "quality": 0.83,
        "solution": ["L","L","U","U","L","D","L","L","U","R","U","U"],
        "notes": ["3 boxes, optimal 12 moves"]
      }
    }
  ],
  "requested": 5,
  "delivered": 5,
  "stats": {
    "totalCandidates": 8,
    "totalValidated": 5,
    "totalRejected": 3,
    "totalTime": 1250,
    "avgDifficulty": 0.58,
    "difficultyRange": [0.45, 0.72]
  }
}

Tips for Game Integration

  • Undo support: Track grid state after each move for undo. The distinct cell types (box-on-goal, player-on-goal) make this straightforward.
  • Move counter: Use the optimal solution length from metrics.solution to show "par" scores.
  • Start small: 5×5 grids with 1–2 boxes for beginners. Scale to 10×10+ with 4+ boxes for experts.
  • Solution replay: The solution array (U/D/L/R) enables hint systems and auto-solve animations.
  • Connectivity guarantee: All empty cells are guaranteed reachable — no isolated rooms.