Move limits without unsolvable levels
In a swap puzzle the move limit is the only way a level can become unsolvable. How head starts give every deal a swap count known before it is played.
Contents
ASMR Logo Craft Block is a swap puzzle. Thirty-two picture tiles, eight hidden groups of four, four tiles to a row. You drag one tile onto another to swap them, and a row holding four of one group locks. There was no way to lose. You swapped until you won.
I wanted it to be more competitive: a move limit, and lives, the way Candy Crush does it. What stopped me was one worry. Put a move limit on a puzzle game and you can ship unsolvable levels, a stage that no amount of skill can finish because the deal needed more swaps than the limit allows. With 1,000 levels and a fresh random shuffle on every attempt, I had no way of looking at each board and checking.
This is how that worry turned into a number the game knows before the level starts.
Can a move limit make a level unsolvable?
In this game, only the move limit can. Any two tiles can always be swapped, so there are no dead ends of the kind a match-3 board can deal itself into. The board is never stuck. A level becomes impossible in exactly one way: the limit is lower than what the deal needs.
So the first question was what a deal needs. A player who knows every group can always finish a group in at most three swaps: take the row where it already has a tile and bring in the other three, one swap each. Do that for seven groups and the eighth row has nothing left to hold except its own four tiles. So the ceiling is 7 × 3 = 21 swaps, for any shuffle.
The measurement agreed. I played 50,000 random deals across all 1,000 levels with the game's solver, which plays like someone who knows the groups:
| Swaps | |
|---|---|
| median | 15 |
| 90th percentile | 17 |
| 99th percentile | 18 |
| worst | 20 (once in 50,000) |
Nothing reached 21.
A flat limit is generous by construction
The first set of rules Claude Code drafted from that put a fixed limit on each range of levels: 40 moves early on, dropping to 30 past level 60, never below 24. Every one of those numbers is safe. They are also slack on almost every board, because a limit that must survive the worst shuffle (20) is six swaps loose on the median one (15). Read the other way, the limit is a budget for wrong guesses, and a flat limit hands out a big budget on most boards and a small one on a few, at random.
I had asked for competitive and got generous. So the next question was how to give each board a limit that is tight and still safe.
Two options I did not ship
A limit read off the deal. Deal the board, run the solver on it, add a small allowance. Safe, and much tighter. It also leaves the level's difficulty to the shuffle. Across the 50,000 deals the solver needed anywhere from 8 to 20 swaps, and nothing about a level decides where in that range its next deal lands. Two players on the same level get different games, and so does one player on two attempts.
A board built backwards to need exactly K swaps. Start from the solved board and undo it one swap at a time, each undo exchanging two tiles that are both still home, from different rows. After K undos the board can be solved in K swaps, and cannot be solved in fewer, because 2K tiles are out of place and one swap fixes at most two. The prototype checked that against every way of assigning groups to rows and threw away any board that failed:
| K | Boards built (of 300) |
|---|---|
| 8 | 300 |
| 10 | 300 |
| 12 | 92 |
| 13 and up | 0 |
It works up to 12 and stops there: past that a cheaper solution keeps turning up. That covers the real range, since random deals were proven to need at least 7 to 12 swaps, mostly 10 or 11. But it needed every attempt at a level to be the same fixed board, with a proof check run on each one. That is a lot of machinery for one number.
Head starts: the deal decides the count
The simpler idea was mine, and it came from looking at what the shuffle actually produces. Some deals happen to start with two or three tiles of one group already in a row. Those boards are easier. So stop leaving that to chance. Each level says how many groups start with three tiles together and how many with two, and the rest of the deal stays random.
From those two numbers alone the most swaps the board can need is known:
- a group with no head start needs 3 swaps
- a group that starts as a pair needs 2
- a group that starts as a triple needs 1
- the last group completes itself, so the largest term comes off
Two triples, two pairs and four plain groups: 1 + 1 + 2 + 2 + 3 + 3 + 3 = 15 swaps at most, on any random deal with that shape. As code, simplified:
// Simplified example: the most swaps a deal can need, from its head starts.
// headStarts lists, per group that has one, how many tiles start together (3 or 2).
function maxSwaps(headStarts, groups = 8, width = 4) {
const missing = [];
for (let g = 0; g < groups; g++) missing.push(width - (headStarts[g] ?? 1));
missing.sort((a, b) => a - b);
missing.pop(); // the last group fills itself
return missing.reduce((sum, n) => sum + n, 0);
}
maxSwaps([3, 3, 2, 2]); // 15
Two rules make the count hold, and the deal has to enforce both. Each head start gets a row of its own, so no two of them compete for the same space. And no accidental extras: outside the head starts, no row may hold two tiles of one group. Without that second rule a random deal can hand out a free pair the level never asked for, and the board plays easier than designed.
The check that found the solver, not the formula
I checked the count on 70,000 boards: all 1,000 levels, ten random deals each, for seven head-start mixes from none at all to four triples and four pairs. The first run failed. On some mixes more than a fifth of the boards took more swaps than the count allowed:
| Head starts | Count | Over the count, old solver | Over the count, head starts first |
|---|---|---|---|
| none | 21 | 0 | 0 |
| 1 pair | 20 | 0 | 0 |
| 2 pairs | 19 | 1 | 0 |
| 1 triple, 2 pairs | 17 | 182 | 0 |
| 2 triples, 2 pairs | 15 | 712 | 0 |
| 2 triples, 4 pairs | 13 | 2,213 | 0 |
| 4 triples, 4 pairs | 10 | 643 | 0 |
Out of 10,000 boards per row. The count was right and the player was wrong. The game's existing solver sometimes broke up a head start while it built a different group. A player who finishes the head starts first, building the most advanced group before the others, never went over on any of the 70,000. The game's solver now plays that way, and the device tests and the hints both use it.
Building the deal without redrawing it
My prototype dealt boards the lazy way: shuffle, check both rules, shuffle again. The fewer head starts a level asks for, the worse that gets. The slowest board with four triples and four pairs took 64 tries. With no head starts at all the slowest took 999, and 40 of 10,000 boards hit the 1,000-try cap and were never dealt.
The version that shipped builds the deal tile by tile. Head starts go into their rows first. The remaining slots are filled row by row, giving out the groups with the most tiles left first and backing up when a row cannot be completed, in the style of the Gale–Ryser construction. It takes about 0.04 ms per board.
The tests caught one shape the rules cannot deal at all. The daily puzzle has four groups on four rows, and my first setting gave it a triple and a pair:
Error: No board has head starts [3,2] for this level
On four rows, a group with no head start may have only one tile per row, so it needs a tile in every row, the triple's row included. The triple's row has one free slot and two plain groups wanting it. The daily now starts with two pairs.
What shipped
Each level of a ten-level collection has a tier, and the tier fixes the head starts and the allowance for wrong swaps:
| Tier | Head starts | Swaps needed | Wrong swaps allowed | Move limit |
|---|---|---|---|---|
| Relief | 4 triples, 4 pairs | 10 | 8 | 18 |
| Easy | 2 triples, 4 pairs | 13 | 6 | 19 |
| Medium | 2 triples, 2 pairs | 15 | 4 | 19 |
| Hard | 1 triple, 2 pairs | 17 | 3 | 20 |
| Super hard | 2 pairs | 19 | 2 | 21 |
The number on screen barely moves, 18 to 21, while the room for mistakes shrinks from eight to two. Difficulty comes from fewer head starts and a smaller allowance, not from a scarier limit.
The tiers do not climb in a line. Every collection runs relief, easy, medium, medium, hard, easy, medium, hard, hard, super hard, then the next one starts on relief again. The first three collections stop at medium. The pictures themselves still get harder over the game, so the long climb happens without touching moves. Hard levels pay double coins and super hard triple. That sorting-versus-placing argument is the same one I made for a different game in difficulty rates a stage, progression places it; what is new here is that each step of the wave carries a guarantee.
A player who keeps failing gets help, quietly, on the next attempt at the same level. After one fail a pair becomes a triple. After two, a pair is added as well. From the third fail the level deals from the tier below, helped twice, with a free clue. The allowance stays the level's own, so the limit really does loosen, and because the count is recomputed from the new head starts, the guarantee holds at every step.
The rest is Candy Crush's shape:
- 5 lives, one back every 30 minutes, or a refill for 150 coins
- run out of moves and you can buy +5 for 60 coins, then 120, then 200
- the out-of-moves popup says how close you were, since the game can count it
- a win streak of 3 gives a free clue on the next board, 5 gives +2 moves
- 3 stars for finishing within the swaps the board needs, 2 within the limit or with clues, 1 with bought moves
Shuffle is gone. The free Shuffle button rearranged the board mid-level, which breaks up head starts and invalidates the count. Anything that changes the board during play has to be checked against the guarantee, and this one could not pass.
How it is checked
The opening state carrying the difficulty was the lesson of the opening layout is part of the puzzle too, on another game. Here it is also the thing the tests can hold on to.
A test deals every one of the 1,000 levels at every help step (no fails, one, two, three or more), four random deals each, and plays each deal as a player who knows the groups. Every one must win, within the swaps that board needs, so the whole allowance is left over for mistakes. The daily gets the same test for every day of a year. With the tier, economy and streak tests around it, the game's rules suite came to 7,551 tests, all passing.
On an Android emulator, 17 device scenarios pass, four of them new: buy more moves, give up and lose a life, open a level with no lives left, and win with mistakes to spare.
What I have not measured
How often players fail. The game logs a fail event with the level, the tier and the attempt number, and that is what the allowances are meant to be tuned by. I have not read those numbers yet, so the 8, 6, 4, 3 and 2 in the table are a first guess that I have not checked against real players.
What the tests prove is narrower and still worth having: no level, at any step of help, asks for more swaps than the limit gives. Whether the limit is fun is a separate question, and only players can answer it.