Parameterize the judging harness by axis so the en panel gets its own work dir, blind keys, arm list and contrast family

This commit is contained in:
heaven 2026-08-14 17:15:23 +03:00
parent 3ec17c8f03
commit bd5c4850da

View file

@ -67,11 +67,19 @@ import absjudge as AJ # noqa: E402
# ⚠ РАБОЧИЙ КАТАЛОГ СУДЬИ — ВНЕ `~/books/dovodka`. Рядом с заданиями не должно лежать ни ключа
# слепых меток, ни сырья с полем `arm`, ни кода. Ключи живут ОТДЕЛЬНО и судье не выдаются.
WORK = Path.home() / "sud-d4"
# ⚠ ОСЬ — ПАРАМЕТР. Каталоги, ключи, состав панели и семейство контрастов у английской оси свои,
# и класть её пачки рядом с китайскими нельзя: судья, увидевший обе, перестаёт быть слепым к
# паре, а ключи разных осей в одном каталоге — прямая дорога к разбору чужой приманки (класс,
# уже пойманный дважды: `itog_d4.py:53` и селфтест этого файла).
AXIS = next((a.split("=", 1)[1] for a in sys.argv if a.startswith("--axis=")), "d4")
if AXIS not in ("d4", "d3"):
raise SystemExit(f"⛔ ось {AXIS} харнессу неизвестна")
WORK = Path.home() / f"sud-{AXIS}"
TASKS1, TASKS2 = WORK / "p1-tasks", WORK / "p2-tasks"
ANSW1, ANSW2 = WORK / "p1-answers", WORK / "p2-answers"
VOTES = WORK / "votes"
KEYS = Path.home() / "books" / "dovodka" / "blind-keys-d4" # НЕ в WORK: судья туда не ходит
KEYS = Path.home() / "books" / "dovodka" / f"blind-keys-{AXIS}" # НЕ в WORK: судья туда не ходит
# ⚠ ПЕРЕВОДИМ РИГ НА КЛЮЧИ ФАЗЫ СРАЗУ, а не только внутри `emit`. Селфтест зовёт `AJ._plant`
# напрямую и при дефолтном `AJ.KEYS` строил приманку ПОСАДКАМИ ЧУЖОГО ПАКА (7 против 6, правила
# разные) — то есть гейт «грубый декой грубее маржевого» сертифицировал не тот текст, который
@ -82,6 +90,13 @@ AJ.KEYS = KEYS
ARMS_D4 = ("A0", "A1B", "A2", "A3", "A4", "A1")
ARMS_OLD = ("A6", "A6F") # есть только у 16 старых единиц
# Панель английской оси. `D0` — черновик: он ЧЛЕН панели, потому что первичный контраст оси
# именно `E0/D0` (H-3 «покупает ли редактор поверх черновика»), а не контраст контуров.
ARMS_D3 = ("D0", "E0", "E1", "E2", "E4")
FAMILY_D3 = [
("E0", "D0", "боевой редактор поверх черновика (H-3, несущая оси)"),
]
# ⚠ ПЕРВИЧНОЕ СЕМЕЙСТВО — по одному контрасту на гипотезу владельца, Холм по трём. Объявлено в
# пре-реге Д0.5 и `power.py`; здесь оно ПОВТОРЕНО, а не переопределено, и впечатывается в ключ
# до первого ответа судьи.
@ -113,6 +128,30 @@ MARGIN_PLANTS = [
MARGIN_MIN = 2 # клетка, где посадить удалось меньше, в маржевый декой не идёт
ARMS = ARMS_D3 if AXIS == "d3" else ARMS_D4
FAMILY = FAMILY_D3 if AXIS == "d3" else FAMILY_D4
BASE_ARM = "E0" if AXIS == "d3" else "A0" # эталон, против которого строится декой и пол
def _wire_axis() -> None:
"""Включить пару оси. Для d4 — no-op (китайская пара и так умолчание)."""
if AXIS == "d3":
import importlib.util # noqa: PLC0415
sp = importlib.util.spec_from_file_location(
"en_axis_sud", Path(__file__).resolve().parent / "en_axis.py")
ax = importlib.util.module_from_spec(sp)
sys.modules["en_axis_sud"] = ax
sp.loader.exec_module(ax)
# ⚠ НЕ `ax.wire()`: драйвер держит СВОЙ экземпляр контура, и его настройка нашего не
# касается — судейство осталось бы на китайской паре с 31 единицей вместо 16. Ловушка
# та же, что с кассой (`money_d` настраивал свой экземпляр). Настраиваем СВОЙ.
C.configure(C.PARA.EN, units_provider=ax.units,
base_draft_hook=ax.base_draft, base_a0_hook=ax.base_e0)
_wire_axis()
def units():
"""Единицы, допустимые к судейству: без брака базы и без клеток finish=length."""
return C.units_ok()