# Piece theft, where solvers die

> A solver fills a few rows for free, then hits a wall in the middle of the board. Here's the mechanism: a scarce piece spent in the wrong place, rows ago.

- Canonical page (with interactive figures/demos): https://eternity2.dev/research/why/piece-theft/
- Updated: 2026-07-01
- Topics: structure, search-space
- Reproduce: `just research-piece-theft`
- Source: Régin 1994, “A Filtering Algorithm for Constraints of Difference in CSPs” (AAAI-94), the all-different reasoning that predicts starvation — https://cdn.aaai.org/AAAI/1994/AAAI94-055.pdf

---
Bar,
  BarChart,
  CartesianGrid,
  ResponsiveContainer,
  Tooltip,
  XAxis,
  YAxis,
} from "recharts";

Fill the board top-left to bottom-right and every new cell already knows two
of its colors: the north color from the piece above, the west color from the
piece to the left. The cell needs an unused piece that can show that exact
pair. Those demands are scarce, with only about three possible pieces on
average, and 47 of them have just one.

So a board that looks healthy, most pieces still in the box, can already be
doomed. Somewhere back up the board, the single piece that could ever serve
an upcoming cell was used for something else. When the solver finally reaches
that cell, there's nothing to place.

## How a cell dies
> **[Interactive: PieceTheftDiagram]** Rendered on the canonical page (link above); not shown in this markdown export.
## How many pieces can serve a demand

<div className="mx-auto grid max-w-2xl grid-cols-3 gap-3 text-center">
  <div className="rounded-lg border p-4">
    <div className="text-3xl font-bold tabular-nums text-red-600">{data.uniqueServerDemands}</div>
    <div className="mt-1 text-xs text-muted-foreground">demands served by a single piece</div>
  </div>
  <div className="rounded-lg border p-4">
    <div className="text-3xl font-bold tabular-nums">{data.meanServers}</div>
    <div className="mt-1 text-xs text-muted-foreground">pieces per demand, on average</div>
  </div>
  <div className="rounded-lg border p-4">
    <div className="text-3xl font-bold tabular-nums">{data.occurringDemands}</div>
    <div className="mt-1 text-xs text-muted-foreground">distinct demands that occur</div>
  </div>
</div>

> **[Figure]** interactive: ServersChart. Rendered on the canonical page (link above); not shown in this markdown export.

## Starve a cell yourself

The engine fills a board to a cell with a single legal supplier; steal that
piece and watch the cell die with the box still full.

> **[Figure]** Interactive: where solvers die to piece theft — interactive: PieceTheftLab. Rendered on the canonical page (link above); not shown in this markdown export.

## Why it matters

A tempting fix is a global check: do the remaining pieces still cover the
remaining cells? It doesn't help. Globally the supply is fine; the failure is
one scarce piece misallocated, not a shortage. So a global lookahead sees
nothing wrong right up until the cell turns out to have no server, which is
why this wall resisted so many attempts to prune it early.

Set this beside [no forced moves](/research/why/no-forced-moves) and the trap
is complete. Every piece has dozens of places it could go, so the solver is
never told where a scarce piece must be saved, yet each scarce piece has
exactly one demand it must be saved for. Freedom to place, no guidance on
where to save.

## Related

- [No forced moves](https://eternity2.dev/research/why/no-forced-moves) — The usual way to crack a logic puzzle is to find a spot where only one piece fits, place it, and repeat. That lever doesn't exist here: every interior piece has between 73 and 137 possible neighbours, and not one is ever pinned to a single option.
- [PRIOR](https://eternity2.dev/research/lab/experiments/raphael-anjou/learning/prior) — Build a board from nothing, breaking ties by where pieces tend to sit in the strong boards we already have. It reaches a high score with no starting board to copy.
