Expand description
§egui-hexweb
A self-contained hexagonal arrow-connection puzzle game library for egui.
The board is a small patch of hexagonal lattice: nodes joined by grid lines in six directions (up, down, and the four diagonals). Fewer pieces than nodes sit on the board, and each piece carries a few arrows pointing along those grid lines. Drag the pieces to any free node, or onto another piece to swap the two until every arrow of every piece is met by the opposite arrow of the piece it points at: a completed web of mutual pairs where nothing points into the void.
Unsatisfied arrows are drawn in an accent color, so the board itself always tells you how close you are.
§Features
- Pure game logic struct (
HexwebGame) with noegui::Uidependency, usable headlessly or with any renderer - Ready-to-use egui
Widget(HexwebWidget) with drag & drop: moving onto empty nodes, swapping onto occupied ones - Procedural, seeded generation (
HexwebGame::random) that always produces a solvable board and verifies, per board, that exactly one placement of the pieces solves it - An exact counting solver (
HexwebGame::solution_count,HexwebGame::solution), exhaustive over the whole placement space, fast enough to run on every generated candidate and after every repair - Mirror-symmetric board shapes of 8 to 16 nodes (
random_symmetric_board, hundreds of holey, notched, or compact shapes per size), plus plainhexagonboards - No losing state and no timer: every move is undone by moving back
- The initial scramble is guaranteed to be neither solved nor solvable in a single move or swap
§Usage
Add the dependency:
[dependencies]
egui-hexweb = "0.4"Then use it in your egui app:
use egui_hexweb::{random_symmetric_board, HexwebGame, HexwebWidget, Params};
// A mirror-symmetric 12-node board with 9 pieces, 2-4 arrows each,
// reproducible from a seed. The seed picks both the board shape (from every
// symmetric connected shape of that size) and the puzzle.
let mut game = HexwebGame::random(
Params {
nodes: random_symmetric_board(12, 42),
pieces: 9,
min_arrows: 2,
max_arrows: 4,
},
42,
);
// Inside your egui update/UI closure:
ui.add(HexwebWidget::new(&mut game));
// Customize the win banner:
ui.add(HexwebWidget::new(&mut game).win_message("Solved!"));Check for a win after each frame:
use egui_hexweb::GameStatus;
match game.status() {
GameStatus::InProgress => {}
GameStatus::Won => println!("Every arrow is connected!"),
}To start over on the same puzzle:
game.reset();To offer a hint, ask the solver where the pieces belong:
if let Some(nodes) = game.solution() {
// `nodes[piece]` is the node piece `piece` occupies in one solution.
}§How generation guarantees a single solution
The generator lays a solved configuration down first: it picks which nodes are occupied, then gives each piece arrows that provably point at other pieces in that configuration, and closes the sets under reciprocity so every arrow is mutually answered. A solution therefore always exists, by construction.
Because the boards are small (8 to 16 nodes), the solver is exhaustive rather than heuristic: it enumerates every possible set of empty nodes and counts the distinct assignments of the pieces that satisfy every arrow, treating identical pieces as interchangeable. The generator counts up to two solutions; if it finds more than one, it adds an arrow pair — a new arrow plus the opposite arrow on the piece it points at — that provably kills one of them (added arrows can never break the configuration it was built from), and recounts, until exactly one remains.
§egui version compatibility
| egui-hexweb | egui |
|---|---|
| 0.4 | 0.35 |
| 0.3 | 0.35 |
| 0.2 | 0.35 |
§License
Licensed under either of MIT or Apache-2.0 at your option.
Structs§
- Arrows
- A non-empty subset of the six directions, as a bitmask.
- Hexweb
Game - The hexweb puzzle: pieces on a hexagonal lattice, moved until every arrow is met by the opposite arrow of the piece it points at.
- Hexweb
Widget - An egui widget that renders an interactive hexweb board.
- Params
- Parameters for
HexwebGame::random. - Piece
- A movable piece. A piece is fully described by its arrows.
Enums§
- Dir
- One of the six lattice directions of the flat-top hex grid, ordered clockwise starting at the top.
- Game
Status - Whether the puzzle is solved. The win is latched: it never reverts.
Functions§
- content_
size - The total footprint
HexwebWidgetwill occupy forgameat a givencell_size. Derived from the actual node centers, so irregular board shapes (a pendant node, a notched hexagon) get a tight box instead of a bounding square. Lets a caller pre-size a container before laying the widget out. - fit_
cell_ size - The cell size (hex circumradius, in logical pixels) that fits
game’s board intoavailablespace — the same auto-sizing formulaHexwebWidgetuses 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. - hexagon
- All nodes
(q, r)with hex distance at mostradiusfrom the center:3·R·(R+1)+1nodes (1, 7, 19, 37, …). - random_
symmetric_ board - A mirror-symmetric board with exactly
nodesnodes, for any count from 8 to 16, picked at random from every such shape.