#!/usr/bin/env python3 """Shared quiet-position predicate, per NNUE.md: exclude positions where the side to move is in check, or where a given move is an SEE-positive (>=50cp) capture. Used two ways by this pipeline, with a deliberately different choice of *which* move gets SEE-checked in each case: - Pre-search filtering (annotate.py): checked against the move actually played in the source human game, since that's the only move known before the engine has searched anything -- the whole point is to skip the sd-N search entirely for positions that would be discarded anyway. - Post-hoc filtering (quiet_filter.py, quiet_filter_games.py): checked against the first move of the already-recorded sd-N search PV (the engine's own considered-best reply), per NNUE.md's original filter design. This remains the definition used for data already annotated before pre-filtering existed, and is NOT the same training distribution as the game-move variant above -- do not mix rows produced under the two definitions into one training run without accounting for that. Both call the same `position_is_quiet` predicate once a concrete move is in hand; only how that move is obtained differs. Reuses eval_tune/tune_eval_dna.py's existing static_exchange_eval() -- a classic swap-list SEE (ignores pins/x-rays/discoveries, a documented, accepted simplification; see check_see_against_engine.py for a cross-check against the engine's real SEE()) -- rather than reimplementing it. """ import os import sys from pathlib import Path _EVAL_TUNE_DIR = Path(__file__).resolve().parent.parent / "src" / "eval_tune" sys.path.insert(0, str(_EVAL_TUNE_DIR)) import chess # noqa: E402 # tune_eval_dna imports dna_diff, which reads "../eval.c" relative to # the *current working directory* at import time, not relative to its # own file -- chdir there just for the import, then restore, so this # module can be imported from any directory. _cwd = os.getcwd() os.chdir(_EVAL_TUNE_DIR) try: from tune_eval_dna import static_exchange_eval, has_hanging_material # noqa: E402,F401 finally: os.chdir(_cwd) SEE_THRESHOLD = 50 # matches has_hanging_material's own default def is_see_positive_capture(board, move, threshold=SEE_THRESHOLD): """board is the position *before* move. Does not mutate board.""" if not board.is_capture(move): return False return static_exchange_eval(board, move) >= threshold def position_is_quiet(board, move, threshold=SEE_THRESHOLD): """board is the position *before* move; move is whichever move the caller has decided to SEE-check (played move or PV's first move -- see module docstring). True means: keep this position in the training set.""" if board.is_check(): return False return not is_see_positive_capture(board, move, threshold)