Skip to content

feat(hexmap): bit-parallel BFS search, distance, reachable and range (L1) - #133

Merged
bal7hazar merged 1 commit into
mainfrom
feat/hexmap-bfs
Sep 27, 2026
Merged

bal7hazar merged 1 commit into
mainfrom
feat/hexmap-bfs

Conversation

@bal7hazar

@bal7hazar bal7hazar commented Sep 27, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Lot L1 of origami_hexmap: the default pathfinder.

  • Bfs::search(grid, width, height, from, to) -> Span<u8>: shortest path (unit cost, 6 neighbours), from the target (included) to the start (excluded), empty when unreachable or from == to. One hex dilation per layer on two u128 limbs with a local bitwise triple, layers stored, then backtracking with the neighbour mask of the current tile. Deterministic.
  • Endpoints are handled outside the loop: the first layer is the start neighbourhood, and the loop stops on the layer that touches the target neighbourhood. Open edge tiles (Digger entrances) can be endpoints; paths never cross another edge tile.
  • The hex distance between the endpoints lets the first layers skip the target test. Boards of at most 128 bits run on a single limb. Loops are unrolled ×4.
  • New Bfs::distance(..) -> Option<u8>: the forward pass only, ~70% of search.
  • Bfs::reachable and Bfs::tiles_within_range (movement range with obstacles): open edge tiles are included when a path ends on them.
  • Panics: Asserter: invalid dimension, Asserter: position not inside, Bfs: position not walkable.

Gas (17x14, sierra gas, minus the 15_040 fixture baseline)

Fixture (far) Path Library Target Status
EMPTY 19 554_993 500_000 +11 %, not met
CAVE 24 691_095 650_000 +6 %, not met
MAZE 53 1_504_486 1_400_000 +7 %, not met
SERPENTINE 90 2_517_050 2_400_000 +5 %, not met
UNREACHABLE 0 248_280 < flooding the component (reachable 276_581, keep_component 283_755) met
  • Per unit: ~19.3k per layer, ~8.4k per backtracking step, ~55k fixed cost. On 7x7 boards: 9.9k per layer and 6.4k per step.
  • origami_map for reference: its BFS medium test (4x4, path of 6) costs 1_608_464; the hex 7x7 EMPTY far search (path of 6) costs 131_733.
  • Baseline to beat: the scalar queue BFS is 3–35× more expensive on every fixture.
  • reachable: −4 % to −8 % against Caver::keep_component on 17x14, about −40 % on 7x7.

Every variant listed in the brief is implemented test-only in bench_bfs.cairo and measured in GAS.md: layer storage, backtracking step, target test, bidirectional search, the single-limb path, the corelib operators and the scalar baseline. GAS.md also covers the iteration history (v1 to v12) and the Sierra code size of the close variants.

Test plan

  • snforge test -p origami_hexmap: 538 passed, 0 failed, 3 ignored.
  • Checked against a scalar queue BFS oracle on:
    • the fixture pairs, and sampled pairs on the fixtures and on random caves and mazes (7x7, 17x14, 19x13);
    • boards 3x3, 8x16, 9x15, 25x10, 83x3 and 3x83;
    • edge entrances, corners, adjacent edge tiles, the no-shortcut-through-the-edge case and Digger corridors and mazes.
  • Every returned path is valid: consecutive tiles adjacent, walkable interior tiles only, and the same path on a second call.
  • reachable equals Caver::keep_component on caves; tiles_within_range checked for every radius.
  • CI Test origami_hexmap (green, 8m23s).

🤖 Generated with Claude Code

…(L1)

Bfs::search runs one hex dilation per layer on two u128 limbs with a
local bitwise triple, stores the layers and backtracks through them
with the neighbour mask of the current tile. The first layer is the
start neighbourhood and the loop stops on the layer that touches the
target neighbourhood; open edge tiles are endpoints only. Layers closer
than the hex distance skip the target test, boards of at most 128 bits
run on a single limb, loops are unrolled four times.

Adds Bfs::distance (forward pass only), Bfs::reachable and
Bfs::tiles_within_range, tests against a scalar queue BFS (fixtures,
random caves and mazes, edge entrances, corners, board extremes) and
benchmarks with the measured losing variants in GAS.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@bal7hazar
bal7hazar merged commit 7adb9c4 into main Sep 27, 2026
9 checks passed
@bal7hazar
bal7hazar deleted the feat/hexmap-bfs branch September 27, 2026 18:01
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