View: Multi-Page Single Page

HamiltonianGenerator

Static public entry point. Namespace SimpleHamiltonian.

MemberReturnsNotes
Generate(settings)PuzzleDataInstant, always solvable. Solution count stays Unknown.
GenerateVerified(settings)PuzzleDataSolvable + uniqueness-checked; hunts for a unique board in Fixed + RequireUnique. Stamps a 1–5 Difficulty, and rolls toward settings.TargetDifficulty when it's set.
GenerateVerifiedAsync(settings)Task<PuzzleData>Background thread; await resumes on the main thread.
GenerateBatch(settings, count)List<PuzzleData>A pack of count verified puzzles, deterministic seeds.
GenerateBatchAsync(settings, count, progress)Task<List<PuzzleData>>Background batch; IProgress<int> reports 1..count.

HamiltonianRules

Static, stateless play rules. Feed your path; it tells you what's legal and whether you've won.

MemberReturnsNotes
IsLegalStep(puzzle, path, next, out reason)boolWalkable, no revisit, adjacent (topology-aware), Fixed-mode start rule.
IsSolved(puzzle, path, out reason)boolCovers every cell; Fixed also checks start/end + checkpoint order.
CheckpointsInOrder(puzzle, path)boolCheckpoints visited so far are in numbered order.
Validate(puzzle)ValidationResultIs the puzzle data well-formed (importers / editors).

Each predicate has a no-reason overload.

Solver

SolutionVerdict v = Solver.Verify(puzzle, nodeBudget: 400_000, budgetSeconds: 2.5);
// v.Count    -> SolutionCount.One / Multiple / Unknown
// v.Verified -> proven (not cut off by a budget)
// v.IsUnique -> Count == One && Verified
// v.Found    -> lower bound on solutions found (capped)
// v.Nodes    -> solver search nodes expanded (the difficulty signal)

Topology-aware (square & hex), bounded by node and wall-clock budgets — a call can never hang.

Difficulty

Rate a verdict 1 (easiest) .. 5 (hardest) from the solver's search effort. Only verified-unique boards are rated; anything else returns 0.

int stars = Difficulty.Stars(v);   // 1..5, or 0 if not verified-unique

Bigger, more open boards score higher; heavy constraints (many checkpoints, sparse coverage) shrink the search and score lower. GenerateVerified stamps this on PuzzleData.Difficulty for you.

PuzzleData

The serializable puzzle unit.

FieldTypeMeaning
Width / HeightintGrid size.
Mode / ShapeenumFree/Fixed · Square/Hex.
SeedstringThe seed that produced it.
Start / EndCellEndpoints (Fixed).
Walkable / ObstaclesList<Cell>Cells the path may enter / blocked cells.
CheckpointsList<Cell>Ordered; index 0 is checkpoint "1".
SolutionList<Cell>The intended cover-all path.
IsUnique / SolutionCountbool / enumThe solver's verdict.
DifficultyintRating 1–5 from the solver's search effort; 0 = unrated (not verified-unique).

Plus computed helpers: CellCount, WalkableCount, ObstacleCount, SolutionLength, CheckpointCount, HasCheckpoints.

Enums & structs

TypeValues / shape
GridShapeSquare · Hex
PuzzleModeFree · Fixed
SolutionCountUnknown · One · Multiple
Cellint X, Y grid coordinate
SolutionVerdictCount, Verified, Found, Nodes, IsUnique
ValidationResultIsValid, Errors, Warnings

ScriptableObjects

TypePurpose
HamiltonianPuzzleOne PuzzleData as an asset. .Puzzle reads it.
HamiltonianPuzzlePackMany puzzles (a level set). .Puzzles reads them.
IPuzzleProviderImplemented by both — AppendTo(list); a single list can mix packs and puzzles.

Create assets via the Puzzle Generator (Save ▾ — current / pack / pack unique only), or in code with PuzzleAssets.CreatePuzzle / CreatePack.

Using them in your own game

Assign a pack or puzzle in the inspector, then read the PuzzleData in code:

using SimpleHamiltonian;

public sealed class MyGame : MonoBehaviour
{
    [SerializeField] HamiltonianPuzzlePack pack;    // drag a pack asset here
    [SerializeField] HamiltonianPuzzle    single;   // or a single puzzle

    void Start()
    {
        // every puzzle in the pack
        foreach (PuzzleData p in pack.Puzzles)
            LoadLevel(p);

        // by index / count
        PuzzleData first = pack.Get(0);
        int total = pack.Count;

        // a single puzzle asset
        PuzzleData one = single.Puzzle;
    }

    void LoadLevel(PuzzleData p) { /* render it, drive moves via HamiltonianRules */ }
}

Helpers & advanced

Cell

MemberNotes
ManhattanTo(other)Grid (Manhattan) distance between two cells.
IsAdjacentTo(other)Orthogonal (square) adjacency. For hex, use a topology (below).

Topology — for custom hex movement / layout

Building your own hex input or renderer? Use the topology instead of hard-coding neighbors — it's square/hex correct:

MemberNotes
Topology.For(shape)An IGridTopology for Square or Hex.
Topology.MaxNeighbors6 — size your neighbor buffer with this constant.
IGridTopology.Neighbors(cell, w, h, buffer)Fills buffer with in-bounds neighbors; returns the count.
IGridTopology.AreAdjacent(a, b)Adjacency under that topology.

Other convenience

MemberNotes
GenerationSettings.Clone() / Clamp()Field-for-field copy / coerce to valid ranges (returns this).
ValidationResult.Summary"N error(s), M warning(s)".
HamiltonianPuzzle.Label / Mode / Width / Height / IsUnique / SolutionCount / Difficulty / SeedRead puzzle facts without touching .Puzzle (handy for list UI).
HamiltonianPuzzlePack.PackNameThe pack's display name.
Advanced / low-level — also public, but most projects won't need them: Generator.Generate (unverified — prefer HamiltonianGenerator), Solver.CountSolutions (the raw counter behind Verify), Rng (deterministic RNG: NextInt / NextDouble / Shuffle), and Grid / ObstacleMetrics (internal generation helpers). The square-only Grid.Neighbors is legacy — use IGridTopology.Neighbors so hex works too.