Path Generation¶
Overview¶
Path generation computes the ordered sequence of squares the gantry head must traverse to carry a piece from its source to its destination. Because the gantry moves beneath the board and uses a magnet to drag pieces, it must follow physically valid routes: it cannot jump over squares the way a chess move description abstracts away.
Each piece-specific generator returns a std::vector<Path> that may contain multiple candidate paths. The caller then selects the best candidate using selectBestPath.
Dispatch¶
generatePath(const PhysicalMove& move) — Function
Parameters: move – the physical move including piece type, source, and destination
Returns: std::vector<Path>
Dispatches to the appropriate piece-specific generator based on move.pieceType. For UNKNOWN piece types, the movement pattern is inferred geometrically:
An L-shaped pattern (
rowDiff$\in {1,2}$,colDiff$\in {1,2}$ with $\text{rowDiff}+\text{colDiff}=3$) $\Rightarrow$ knight pathEqual row and column difference $\Rightarrow$ bishop (diagonal) path
All other patterns $\Rightarrow$ rook (orthogonal) path
Piece-Specific Generators¶
Pawn¶
generatePawnPath(const BoardCoord& from, const BoardCoord& to) — Function
Parameters: from, to – source and destination coordinates
Returns: std::vector<Path> with exactly one path
Generates a straight-line path stepping one square at a time in the direction of travel. Handles both single-step advances, double-step advances from the starting rank, and diagonal captures with the same algorithm (step in the direction of the row and column delta simultaneously).
Knight¶
generateKnightPath(const BoardCoord& from, const BoardCoord& to) — Function
Parameters: from, to – source and destination coordinates
Returns: std::vector<Path> with exactly two paths
Knights jump in chess, but the gantry must physically travel through intermediate squares. Two L-shaped routes are generated for every knight move:
Vertical-first: travel the longer leg along the row direction, then the shorter leg along the column direction.
Horizontal-first: travel the shorter leg along the column direction first, then the longer leg along the row direction.
Both paths are returned so the best one (fewest blockers) can be selected.
Bishop¶
generateBishopPath(const BoardCoord& from, const BoardCoord& to) — Function
Parameters: from, to – source and destination coordinates
Returns: std::vector<Path> with exactly one path
Delegates to generateDiagonalPath, producing a single path that steps one square diagonally at a time toward the destination.
Rook¶
generateRookPath(const BoardCoord& from, const BoardCoord& to) — Function
Parameters: from, to – source and destination coordinates
Returns: std::vector<Path> with exactly one path
Delegates to generateOrthogonalPath, stepping either horizontally or vertically depending on the direction of the move.
Queen¶
generateQueenPath(const BoardCoord& from, const BoardCoord& to) — Function
Parameters: from, to – source and destination coordinates
Returns: std::vector<Path> with exactly one path
Selects diagonal movement when |rowDiff| == |colDiff|, orthogonal movement otherwise. Returns a single path.
King¶
generateKingPath(const BoardCoord& from, const BoardCoord& to) — Function
Parameters: from, to – source and destination coordinates
Returns: std::vector<Path> with exactly one path containing only the destination square
King moves are always a single square. The path contains only the destination, so the gantry moves directly without intermediate steps.
Primitive Path Helpers¶
Two low-level helpers are shared by multiple generators:
generateDiagonalPath(const BoardCoord& from, const BoardCoord& to) — Function
Parameters: from, to – source and destination
Returns: Path
Steps one square per iteration with equal row and column increments (signs determined by the direction of travel) until the destination is reached. All intermediate squares plus the destination are included.
generateOrthogonalPath(const BoardCoord& from, const BoardCoord& to) — Function
Parameters: from, to – source and destination
Returns: Path
Steps one square per iteration along either a row or a column (one of the step values is always zero). Implementation is identical to generateDiagonalPath; the distinction lies in what from/to pairs are passed by the callers.
Path Selection¶
selectBestPath(const PhysicalBoard& board, const std::vector<Path>& paths) — Function
Parameters: board – current physical board state; paths – candidate paths
Returns: Path – the path with the fewest blocking pieces
Iterates over all candidate paths, calling findBlockers on each, and returns the path whose blocker count is minimal. If two paths tie, the earlier one in the vector wins. If the input vector is empty, returns an empty Path.