On this page
Source
  • fast-search.ts
Used by

Design

The playable board needs a useful recommendation while it is still responding to taps and drawing chain animations. The browser solver keeps the TypeScript reference search's result and replaces its expensive storage paths. It runs in a dedicated Web Worker, so search never occupies the page's main thread.

Implementation

A worker per position

The game creates one module worker for the current position. Progress messages can show the best completed depth while a deeper pass runs. When the position, mode or budget changes, React's cleanup terminates the old worker, which prevents a stale answer from playing a move on a newer board.

Drop7Game.tsxOwn the solver for exactly one position

This source excerpt is unavailable in this checkout.

The effect starts a worker, handles progress and final messages, and terminates the worker during cleanup or after a result.

Fast rules with the same order

One pass builds row and column occupancy masks. Run lengths then come from a small lookup table, while the returned poppers stay in the reference engine's row-major order. Gravity edits only columns that can contain a hole after the wave.

fast-search.tsFind matching discs from occupancy masks

This source excerpt is unavailable in this checkout.

The fast scan changes how run lengths are obtained while preserving the list and order observed by the chance search.
fast-search.tsSettle only the affected columns

This source excerpt is unavailable in this checkout.

The column mask avoids seven-column gravity work after a wave that touched only part of the board.

Packed cache keys

A position and its mirror share one cache entry. The browser packs the canonical board and its scalar fields into typed arrays, then keeps least-recently-used order with integer links. This removes short-lived strings and map nodes from the inner search loop.

fast-search.tsPack a mirror-aware position

This source excerpt is unavailable in this checkout.

The key preserves the reference cache's equivalence classes while fitting the position into seven 32-bit words.

Uses

Evaluate mode recommends a column and leaves the decision to the visitor. Auto mode plays the best completed result after a short pause. Both modes use iterative deepening, so a short time budget still returns the last fully evaluated depth. No server receives the board or performs the search.

Verification

This port is test-gated against the reference TypeScript solver on real positions. The suite compares chance outcomes, completed column values, cache eviction, work limits and every completed-depth callback. No browser or runtime profile was retained, so this page makes no speed claim.

Technical recordThe parity cases for the browser move generator, leaf and search
  • fast leaf is bit-identical to evaluateHeuristic for every profile
  • fast leaf sees every chance outcome identically, not just root boards
  • fast move generator streams the reference outcomes in order with exact probabilities
  • fast move generator settles a caller-supplied unsettled board like the reference
  • fast move generator ignores illegal columns and terminal states like the reference
  • completed depth-2 searches match the reference exactly
  • completed depth-3 searches match the reference exactly, per profile
  • a depth-4 search matches the reference exactly, including cache eviction
  • work-limited searches abort at the same point and report the same partial result
  • depth-complete callbacks fire with identical intermediate results
  • timing: fast search against reference on the same decisions (informational)

Limits

The browser leaf is the TypeScript heuristic profile, while the C++ fair reference uses a different weighted leaf. This solver demonstrates one policy and its results are outside the research tiers. Its timing test is informational and retains no environment or result.

Agent contextWorker invariants and the parity command for future changes

Keep fastEvaluateMoves value-identical to evaluateMoves, including outcome order, floating-point accumulation, work accounting and partial results. Run cd web && npm testafter changing anything under web/lib/play/ or the worker lifecycle in Drop7Game.tsx.

A worker response belongs to the position that created it. Terminate the worker on cleanup and ignore any message after cancellation. Preserve progress messages because they are the usable fallback when the next depth does not finish inside the budget.