Lights Out in SwiftUI — with a real solver inside. Tap a light and it toggles together with its four neighbours; turn everything off to win. Spegni is Italian for "turn it off", usually shouted from another room.
Boards from 3×3 to 7×7, per-size best scores, and a hint button backed by linear algebra.
Two facts make Lights Out a linear system over GF(2): pressing a cell twice undoes it, and press order doesn't matter. So a solution is just a set of cells, and "solve the board" becomes solving Ax = b where A says which presses touch which cells and b is the current lights.
Solver.swift does Gaussian elimination over GF(2) (rows are UInt64
bitmasks, so a row XOR is one instruction), finds a particular solution,
then walks the null space — the famous quiet patterns, 5×5 has four —
and keeps the solution with the fewest presses. That gives:
- "Solvable in N" in the UI: the true minimal press count, live after every move
- Hints that are always part of an optimal solution (using one disqualifies the game from setting a record — fair is fair)
- unsolvability detection: on 5×5 only a quarter of light patterns can be switched off at all; the solver proves it instead of guessing
Boards are still generated the cheap way — scrambling from the solved state with random presses, which guarantees solvability without any of the above. Generation and verification meeting in the middle is the fun of this project.
Board.swift— game state, pure logic, no SwiftUISolver.swift— GF(2) elimination + null-space minimizationGameView.swift— the whole UITests/— board mechanics and solver correctness across sizes, including a known-unsolvable position (11 tests)
swift testRuns on iOS 17 / macOS 14. Open the package in Xcode and use the
#Preview in GameView.swift, or drop the sources into an app target
and add @main.
MIT license.