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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions