A basket weave in which every crossing is decided by parity — except one, deliberately wrong.
Parity is the weave
if ((col % 2 + row) % 2 == 0)
CrossHorizontalOverVertical(canvas, paint, grid, tile, delta, isMistake);
else
CrossVerticalOverHorizontal(canvas, paint, grid, tile, delta, isMistake);
Every cell holds two short threads crossing at right angles. Which one passes over is
decided by the parity of the cell’s coordinates — nothing else — and alternating that
parity across the grid is exactly what a basket weave is.
There is no simulation of thread, no tension, no physics. A checkerboard of two
drawings, and the eye reads cloth.
A sixth of the cells.
A third. The alternation is what does the work: a field of crossings all in the same
orientation reads as a lattice, and only the alternation reads as woven.
The deliberate flaw
var mistakeRow = (int)Math.Ceiling(rng.NextDouble() * (grid.GridSize - 4)) + 2;
var mistakeCol = (int)Math.Ceiling(rng.NextDouble() * (grid.GridSize - 4)) + 2;
Two random numbers, and they are the only randomness in the entire piece. They pick one
cell whose over-under is inverted.
The + 2 and the − 4 keep it away from the edges, where it would read as a border
effect rather than as a mistake.
This is a real weaving tradition — the humility block in American quilting, the
deliberate irregularity in Persian carpets — and it survives here as two lines of code
producing one wrong crossing in several thousand.
Half. The flaw is already in the drawing.
Three quarters.
The full weave. Finding the flawed cell takes a while, which is the point: it is one
crossing among thousands, and the only thing marking it is the order in which two
strokes were drawn.
Five renderings
| Rendering | Tile | Thread | Stroke | Ink |
|---|
| Weave Coral | 15 | 0.55 | 2 | coral on black |
| Weave Gold | 18 | 0.60 | 2.5 | gold on deep navy |
| Weave Slate | 8 | 0.45 | 1 | steel blue on near-black |
| Weave Rust | 26 | 0.38 | 3.5 | terracotta on near-black |
| Weave Chalk | 13 | 0.70 | 1.8 | white on near-black |
TileSize controls how many cells fill the canvas — Slate has more than twice as many
as Coral, and Rust roughly half as many. ThreadSize against TileSize sets how much
of each cell the threads occupy: Rust’s threads leave wide open space between them;
Chalk’s nearly fill each cell. Each rendering has its own seed, so the flaw is in a
different place in each.
Determinism
SeededRandom — the project’s stable Xoshiro256StarStar — is seeded from the preset
and consumed exactly twice, before any cell is drawn.