Skip to content

feat(hexmap): bit-parallel weighted Dial search and field of movement (L3) - #132

Merged
bal7hazar merged 8 commits into
mainfrom
feat/hexmap-dial
Sep 27, 2026
Merged

bal7hazar merged 8 commits into
mainfrom
feat/hexmap-dial

Conversation

@bal7hazar

Copy link
Copy Markdown
Collaborator

Summary

Lot L3 of origami_hexmap: weighted shortest path without a heap, and movement range with costs.

  • Dial::search(grid, width, height, from, to, costs): cheapest path, entry cost 1 unless the tile is in costs[k] (cost k + 2, at most 3 classes). A tile in several classes takes the highest cost. Output as Bfs::search (target included, start excluded, empty if unreachable or from == to).
  • Dial::field_of_movement(grid, width, height, from, budget, costs) -> felt252 (new public function): tiles reachable with total cost <= budget, start included (hexx semantics).
  • Time-expanded buckets: because costs are paid on entering a tile, a tile's first scheduling is final. It goes into bucket t + cost once and leaves the unvisited set at that moment. That means no stale entries, and the search stops when the target is scheduled. The ring is 4 felts, and unions are additions because the scheduled sets are disjoint.
  • Separate unit-cost loop when costs is empty. Single-limb u128 path for boards <= 128 bits, sharing code through a private Set<T> trait.
  • Edge endpoints are handled locally (interior layer loop, edge tiles only as endpoints). Nothing is taken from L1.

Gas (17x14, CAVE far pair, 2 classes over 30 % of the floor)

Measured Target
Dial::search CAVE far 1_427_654 < 1.5M
Per time step (2 classes) 36_806 < 40k
Per time step (0 / 1 / 3 classes) 26_456 / 35_600 / 38_012
Scalar Dijkstra + binary heap (baseline) 25_902_461
origami_map Dijkstra, 18x14 unit costs 22_826_630

All variants from the brief are implemented and measured in tests/bench_dial.cairo (bucket ring as locals / fixed array / Array, per-class masking vs partition, sparse layers, bit-test backtracking, corelib vs local bitwise triple, u128 vs u256, Dijkstra with a heap). The full tables are in the L3 section of GAS.md.

Tests

  • Oracle: a scalar Dijkstra (test-only). Total cost is equal and every path is valid, on all fixtures, random caves (17x14, 19x13), 3x3, open edge tiles (corner, adjacent edge pairs, edge to edge) and 0 to 3 pseudo-random cost classes. field_of_movement is checked against the oracle for several budgets.
  • With no costs, the path length equals the scalar BFS of tests/variants.cairo.
  • Unit tests in dial.cairo: exact paths with printouts, the overlap rule, edges, dimensions, and panics (Dial: too many costs, Dial: position not walkable, asserter errors).

Scope: finders/dial.cairo, tests/bench_dial.cairo, GAS.md (L3 section).

🤖 Generated with Claude Code

bal7hazar and others added 8 commits September 27, 2026 14:54
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ng in Dial

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… bits

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@bal7hazar
bal7hazar merged commit cb734e0 into main Sep 27, 2026
9 checks passed
@bal7hazar
bal7hazar deleted the feat/hexmap-dial branch September 27, 2026 16:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant