Skip to content

one_d4: add Novotny detector; fix cross-pin detector to cover relative pins #1056

@aaylward

Description

@aaylward

Background

Two related motifs that are not yet correctly detected:

  1. Cross-pinCrossPinDetector exists but only scans outward from the king, so it only finds absolute cross-pins (both pins shielding the king). A true cross-pin is when a single piece is pinned along two different axes simultaneously — the most common case is one absolute pin to the king plus a relative pin to the queen (or other valuable piece) from a different angle. There are also no tests for CrossPinDetector.

  2. Novotny — no detector exists. A Novotny interference is when a piece is sacrificed on the intersection of two enemy line pieces' attack rays (classically a rook ray and a bishop ray). Whichever piece captures, it blocks the other's line, enabling a tactical or mating continuation.

Cross-pin: what needs fixing

Current behaviour (CrossPinDetector):

  • Scans the 8 directions from the king only
  • Detects a cross-pin only if the same square appears pinned along two axes that both terminate at the king
  • Misses relative cross-pins (e.g. a knight pinned against the king by a bishop and against the queen by a rook)

Correct detection:

  • For each friendly non-king piece P:
    • Is P on the line between the king and an enemy slider (absolute pin)?
    • Is P also on the line between a more-valuable friendly piece and a different enemy slider (relative pin)?
    • If both conditions hold, and the two pin axes are different, it is a cross-pin.
  • A cross-pin where both pins are relative (no king involvement) is theoretically possible but extremely rare; worth supporting if easy.

Add CrossPinDetectorTest — cover: single absolute pin (not a cross-pin), absolute + relative cross-pin, double relative cross-pin (if supported), no-pin position.

Novotny: new detector

Definition: After a move by the active side, the moved piece now occupies a square that lies on the attack rays of two different enemy line pieces (rook/queen on a rank/file; bishop/queen on a diagonal). If the enemy captures with either piece, it physically blocks the other's ray, allowing the active side to execute a follow-up threat that would otherwise be defended.

Simplified detection algorithm (practical games, not compositions only):

  1. Identify the destination square S of the last move.
  2. Find all enemy sliding pieces whose pre-capture attack ray passes through S and continues to at least one further square.
  3. For each pair (A, B) of such attackers whose ray directions are different (e.g. one orthogonal, one diagonal):
    • Simulate capture by A: does A's piece now block B's ray to a square B was defending?
    • Simulate capture by B: does B's piece now block A's ray to a square A was defending?
    • If both simulations block a relevant defender, this qualifies as a Novotny interference.
  4. Optionally require that the "blocked" square is a mating-threat square or captures a hanging piece, to reduce false positives in practical play (Novotnys in games are rare but not compositions-only).

Required changes:

  • NovotnyDetector.java — implement MotifDetector
  • Motif.java — add NOVOTNY enum value
  • FeatureExtractor.java — register NovotnyDetector
  • NovotnyDetectorTest.java — test cases including the classical rook+bishop intersection, a queen acting as one of the line pieces, and positions without a Novotny
  • ChessQL: add motif(novotny) support in the grammar/parser

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels
    No fields configured for Feature.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions