Skip to main content

Crate egui_numberlink

Crate egui_numberlink 

Source
Expand description

crates.io docs.rs deps.rs CI Rust version License Changelog Live demo Archived

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) and NumberlinkGame::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::colors lets 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-numberlinkegui
0.10.35

§License

Licensed under either of MIT or Apache-2.0 at your option.

Structs§

NumberlinkGame
The Numberlink game state: board dimensions, each number’s fixed endpoints, the player’s drawn paths, and undo/redo history.
NumberlinkWidget
An egui widget that renders an interactive Numberlink board.

Enums§

GameStatus
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 NumberlinkWidget will occupy for game at a given cell_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 into available space — the same auto-sizing formula NumberlinkWidget uses internally when no explicit cell_size is set. Lets a caller pre-compute that fit (e.g. to size a Scene before laying the widget out inside it) instead of duplicating the formula.