Expand description
§egui-numberlink
Archived. This project is no longer maintained. The crate remains functional, but the procedural generator never produced genuinely difficult puzzles despite extensive effort — they all play too easy. Use or fork at your own risk.
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 every non-blocked cell of the board ends up covered by exactly one path. Some cells may be permanently blocked (walls no path may ever enter), which is what makes lower-density procedural puzzles genuinely harder rather than merely bigger.
§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, including any blocked (wall) cells - Two ways to build a puzzle:
NumberlinkGame::from_endpoints/from_endpoints_with_blocked(supply your own endpoints and, optionally, blocked cells) andNumberlinkGame::random(procedural, seeded, always has a 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:
[dependencies]
egui-numberlink = "0.1"Then use it in your egui app:
use egui_numberlink::{NumberlinkGame, NumberlinkWidget};
// A curated puzzle from explicit endpoint pairs (number 0's endpoints, then
// number 1's, ...):
let mut game = NumberlinkGame::from_endpoints(
3,
3,
vec![((0, 0), (2, 2)), ((0, 2), (1, 2))],
);
// Or a procedural puzzle, reproducible via a seed: 5 pairs on a 6x6 board,
// with 70% of cells playable (the rest permanently blocked). The generator
// prefers a layout it can verify has exactly one solution, within a bounded
// search.
let mut game = NumberlinkGame::random(6, 6, 5, 0.7, 42);
// Inside your egui update/UI closure:
ui.add(egui_numberlink::NumberlinkWidget::new(&mut game));
// Customize the per-number palette (must be at least one color; cycles if
// shorter than the puzzle's pair count):
use egui::Color32;
let colors = [Color32::RED, Color32::GREEN, Color32::BLUE];
ui.add(egui_numberlink::NumberlinkWidget::new(&mut game).colors(&colors));After each frame you can inspect game.status to check for a win:
use egui_numberlink::GameStatus;
match game.status {
GameStatus::Playing => {}
GameStatus::Won => println!("Solved!"),
}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.
Structs§
- Numberlink
Game - The Numberlink game state: board dimensions, each number’s fixed endpoints, the player’s drawn paths, and undo/redo history.
- Numberlink
Widget - An egui widget that renders an interactive Numberlink board.
Enums§
- Game
Status - The current status of the game.
Constants§
- DEFAULT_
COLORS - A colorblind-safe default palette (the 8-color Okabe-Ito set, plus a 9th
purple so a 9-pair board — e.g. the web demo’s Expert preset — doesn’t
wrap back onto an already-used color), cycled if the puzzle has more
pairs than colors. Overridden entirely via
NumberlinkWidget::colors.
Functions§
- content_
size - The total footprint
NumberlinkWidgetwill occupy forgameat a givencell_size. Lets a caller pre-size a container before laying the widget out. - fit_
cell_ size - The cell size (in logical pixels) that fits
game’s board intoavailablespace — the same auto-sizing formulaNumberlinkWidgetuses internally when no explicitcell_sizeis set. Lets a caller pre-compute that fit (e.g. to size aScenebefore laying the widget out inside it) instead of duplicating the formula.