egui-numberlink
A self-contained Numberlink puzzle game library for egui.
Numberlink is the classic puzzle of connecting matching pairs of numbered endpoints on a grid with a path each, such that no two paths cross and (in this crate's variant) every cell of the board ends up covered by exactly one path.
Features
- Pure game logic struct (
NumberlinkGame) with no egui dependency — usable headlessly or with any renderer - Ready-to-use egui
Widget(NumberlinkWidget) that renders an interactive, numbered board - Two ways to build a puzzle:
NumberlinkGame::from_endpoints(supply your own endpoints) andNumberlinkGame::random(procedural, seeded, always has a full-board solution by construction and prefers one verified unique within a bounded search) - Endpoints are always labeled with numbers, like the original Numberlink — color is an optional, fully customizable skin on top, not a replacement
NumberlinkWidget::colorslets embedding apps supply their own per-number palette; defaults to a colorblind-safe built-in one- Paths are drawn through the interior of each cell (connecting cell centers, turning at a cell's center), never along a cell's border
- Click-and-drag drawing: either endpoint always works to start/redraw a number's path; dragging back over a path's own previous cell retracts it by one; dragging onto a different number's path is rejected; a plain click (no drag needed) also clears/starts a path
- Undo/redo history, one entry per completed drag
- Win banner drawn over the board once solved
Usage
Add the dependency:
[]
= "0.1"
Then use it in your egui app:
use ;
// A curated puzzle from explicit endpoint pairs (number 0's endpoints, then
// number 1's, ...):
let mut game = from_endpoints;
// Or a procedural puzzle, reproducible via a seed, verified to have exactly
// one full-board solution:
let mut game = random;
// Inside your egui update/UI closure:
ui.add;
// Customize the per-number palette (must be at least one color; cycles if
// shorter than the puzzle's pair count):
use Color32;
let colors = ;
ui.add;
After each frame you can inspect game.status to check for a win:
use GameStatus;
match game.status
To start over on the same puzzle:
game.reset;
egui version compatibility
| egui-numberlink | egui |
|---|---|
| 0.1 | 0.35 |
License
Licensed under either of MIT or Apache-2.0 at your option.