DEV Community

Cover image for Material vs locked: the rule that lets 2048 and Sudoku share a board
Ayoola Solomon
Ayoola Solomon

Posted on

Material vs locked: the rule that lets 2048 and Sudoku share a board

I've always loved Sudoku and 2048. They're the puzzles I open instead of scrolling. For a long time I wanted a mashup that felt like both, not a gimmick with two logos stuck on one grid.

Play Number Merge Sudoku (Daily or Endless). What follows is the design decision that made it playable.

Why mashups usually fail

Sudoku says: every digit appears once per row, column, and box.

2048 says: equal neighbors merge into the next value, and duplicates are the whole point of the economy.

If every tile on the board counts as a Sudoku digit the moment it appears, merges die. You can't keep two 2s in the same row long enough to make a 4. If you ignore uniqueness until the end, you don't have Sudoku; you have a merge game with a checkbox at the finish line.

The interesting problem isn't "can I render a grid in React." It's: when does a number start counting?

The contract: material vs locked

Every occupied cell holds a tile in one of two states:

  • Material: may share its value with other material tiles in the same row, column, or box. Material tiles can merge. They do not count toward Sudoku uniqueness.
  • Locked: counts as a Sudoku digit. Locked tiles cannot merge. A value may appear at most once as locked in each row, column, and box.

You only ever spawn 1s, and they always spawn as material. Merge two equal material neighbors and you get the next value, still material, on the survivor cell. No auto-chains. No Sudoku check on merge.

Seal is the verb that turns material into locked, in place. Seal is illegal if that value is already locked in the same row, column, or box. Until you seal, the board is allowed to look "illegal" by Sudoku standards. That's intentional. Duplicates are fuel.

Win condition: every cell is occupied by a locked tile, and every row, column, and box contains each digit of the board's alphabet exactly once. Easy is 4×4 (digits 1–4). Medium and Hard are 6×6 (digits 1–6).

One sentence version: Sudoku uniqueness applies only to locked digits.

That single sentence is the whole product.

Three moves, three jobs

The run is empty at the start. No seeded givens. You build the puzzle by playing it.

  1. Spawn: put a material 1 on any empty cell. Always legal. No uniqueness check.
  2. Merge: two orthogonally adjacent material tiles of equal value become one material tile of the next value on the survivor; the other cell clears. Max digit is terminal (4 on Easy, 6 on Medium/Hard). Locked tiles never merge.
  3. Seal: convert one material tile to locked, if uniqueness still holds for locked digits.

UI-wise it's two-tap merge and tap-empty to spawn. The mental model is what matters: merge builds value; seal commits it to the Sudoku layer.

Color follows the same contract. Each digit has a fixed hue. Material uses a softer treatment; locked uses a denser one. Color never encodes "legal move" or hints. Digits stay readable. Hue is state, not advice.

Soft-locks aren't bugs

You can fill yourself into a corner where no spawn, merge, or seal remains, even with empty cells left. That's a Loss: a soft-lock.

I almost treated that as a failure of the ruleset. It isn't. It's the tax of a merge economy living under a uniqueness ceiling. If soft-locks couldn't happen, the puzzle would be too forgiving to feel like either parent game.

So Difficulty isn't "how many givens." There are no givens. Difficulty chooses board size, alphabet, undo budget, and hint budget:

Difficulty Board Digits Undos Hints
Easy 4×4 1–4 5 3
Medium 6×6 1–6 3 2
Hard 6×6 1–6 1 1

Undo reverts the last successful spawn, merge, or seal. It stays available through a soft-lock so you can dig out. After a Win, the run auto-finalizes; undo and hint close.

Hint is a legality nudge, not a solver. It reveals one currently legal move and leaves you to play it. Prefer merges that don't crowd the survivor's house with the result digit, then spawns that set up merges, then seals of unique material values. It does not claim a path to win. Spending a hint locks Difficulty for the run the same way the first real move does.

Daily as the habit loop

Daily: one run per UTC day. Leave mid-board and it resumes. Pick Difficulty until the first successful spawn, merge, seal, or hint; then it's fixed for that day. Elapsed time starts on the first real move (not on staring at an empty board, not on hint alone), pauses when the tab is hidden, and freezes on win.

Endless: same rules, as many runs as you want. No Daily share.

On Daily win, you get a board snapshot (digit hues intact) plus a caption: game name, UTC date, difficulty, win, undos used, hints used, elapsed time, and a clean link back to the play page. Share is opt-in after finalize. Losses aren't share artifacts. Soft-locks are for learning, not for the timeline.

I built the thing I'd open with coffee. The Daily is how that intention shows up in the product.

What I deliberately didn't do

  • No seeded puzzle of the day. The day is a label and a lock, not an RNG board. You and I start from the same empty grid; the run diverges with play.
  • No solver-as-hint. Hint answers "what is legal right now," not "what would a SAT solver do."
  • No React tutorial. The shell is Remix, TypeScript, and a small domain core with tests. The novel work was the state machine for material vs locked, not the component tree.
  • No "place any digit" mode. If you can drop a 6 wherever you like, you're back to Sudoku with extra steps. The merge ladder is the constraint that makes the board feel like 2048.

Try it

If you have a few minutes:

  1. Open Number Merge Sudoku.
  2. Start on Easy if you want the rule to click fast; Medium if you want the real Daily shape.
  3. Spawn 1s, merge equals, seal only when uniqueness allows.
  4. Soft-lock once on purpose. Undo. Notice what you learned.

When you win a Daily, share the board if you want. I'd rather see your soft-lock stories in the comments than a stack screenshot.

The mashup only works because uniqueness waits. Everything else is choreography around that one contract.


Play: ayoolasolomon.com/play/number-merge-sudoku

Project notes: ayoolasolomon.com/projects/number-merge-sudoku

If this was useful, the follow-ups worth writing are soft-locks as a feature, and a hint engine that reveals without playing. Tell me which one you want next.

Top comments (3)

Collapse
 
raknaos profile image
Raknaos

"Sudoku uniqueness applies only to locked digits" is doing all the work here, and the reason it holds is that it names the invariant on the value rather than on the cell. Most mashups die precisely because they enforce the rule at spawn time, when merges still need duplicates in the row to be legal — deferring it to a seal move keeps the two rule sets from fighting each other.

The part I'd expect to bite is the board's solvability, not its legality. Since the run starts empty and you build the puzzle by playing it, a sealed tile can leave a row with no legal completion for the remaining alphabet while still being legal at the moment of sealing — that's the classic dead end, except here the player caused it and can't undo without unwinding the run.

How is the win condition checked: a full validate on every seal (cheap, immediate feedback, but tells the player nothing until it's too late), or a forward check for cells that still have at least one candidate digit? For a daily puzzle the second one seems worth the cost.

Collapse
 
ayoolasolomon profile image
Ayoola Solomon • Edited

Thanks. That’s a cleaner framing: the invariant sits on the value once locked, not on the cell the moment it’s occupied. Deferring uniqueness to seal is what stops spawn and merge from fighting Sudoku.

v1 only checks legality, not solvability. Seal asks whether this digit would duplicate a locked tile in the same row, column, or box. Win is a full validation when every cell is already locked. Loss is no legal spawn, merge, or seal left. There is no candidate or forward check after seal.

That dead end is real and intentional here. You can seal a board that is locally legal and globally doomed; undo is the recovery. I left forward checking out on purpose, so soft-locks stay part of the merge economy instead of sliding the game toward a solver. A “warn on doomed seal” assist is interesting for Daily later

Some comments may only be visible to logged-in visitors. Sign in to view all comments.