Files
andrey 36f0fa2623 R2-3: полное покрытие новых фич, паритет torus, полировка
- tests/test.js: 148 -> 206 проверок (разделы 23 wrap/torus, 24 зоны, 25 бюджет,
  26 размеры, 27 сейв v2/миграция, 28 рендер/resize 300x300, 29 HUD 381-400px);
  resetGlobals сбрасывает tool/reason/winner; sleep заменён на waitCond/settleViewport.
- tools/old-ref/: независимый torus-эталон (nextStepCleanWrap, CLI --torus,
  gen-torus.js, reference-torus.json); diff-our.js сверяет stepN при setWrap(true).
- index.html: медиазапрос HUD 380->400px (убрана микро-обрезка 381-388px);
  инлайн-комментарий про согласованность useWrap/setWrap.
- AGENTS.md: полный список контракта дополнен; useWrap-заметка уточнена; покрытие
  приведено в соответствие. README: скорость — константа в коде, не UI.
- .gitignore: tools/old-ref/.tmp-*.txt.
- Прогоны: check: OK; суита 206/206 (3 повтора); паритет clean 273/273 + torus 273/273.
- Ревью-гейт R2-3 (Oracle): PASS; minor/nit закрыты.
2026-10-11 11:02:23 +03:00

67 lines
2.9 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use strict';
/* Генерация эталона ЧИСТОГО правила НА ТОРЕ (--torus) для всех кейсов reference.json.
Опция «Замкнутая карта» — новая (в прототипе old заворотов не было), поэтому
независимого прототипного эталона нет; эталон считает тот же harness
(nextStepCleanWrap) с заворотом через края.
Использует CLI-режим harness: ./old_ref <file.txt> <steps> --torus
Пишет reference-torus.json в структуре: [{name,w,h,steps:[ascii0..asciiN]}].
Запуск: node gen-torus.js (из tools/old-ref/)
*/
const { execFileSync } = require('child_process');
const fs = require('fs');
const path = require('path');
const DIR = __dirname;
const refPath = path.join(DIR, 'reference.json');
const outPath = path.join(DIR, 'reference-torus.json');
const tmpPath = path.join(DIR, '.tmp-torus-case.txt');
const ref = JSON.parse(fs.readFileSync(refPath, 'utf8'));
const out = [];
for (const c of ref) {
const init = c.steps[0]; // ASCII начального поля (строки\n)
fs.writeFileSync(tmpPath, init);
const n = c.steps.length - 1; // число шагов
const res = execFileSync(path.join(DIR, 'old_ref'), [tmpPath, String(n), '--torus'], {
encoding: 'utf8',
});
const parts = res.split(/--- step \d+ ---\n/);
if (parts.length !== n + 1) {
throw new Error(`case ${c.name}: ожидалось ${n + 1} полей, получено ${parts.length}`);
}
out.push({ name: c.name, w: c.w, h: c.h, steps: parts });
}
// Санити-проверка: шаг 0 совпадает с начальным полем reference.json.
for (let i = 0; i < ref.length; i++) {
if (ref[i].steps[0] !== out[i].steps[0]) {
throw new Error(`шаг 0 расходится для ${ref[i].name}`);
}
}
fs.writeFileSync(outPath, JSON.stringify(out, null, 1) + '\n');
try { fs.unlinkSync(tmpPath); } catch (e) {}
// Сводка: сколько (кейс×шаг) разошлось clean(жёсткие) vs torus.
const cleanPath = path.join(DIR, 'reference-clean.json');
let diff = 0, total = 0;
const diffCases = new Set();
if (fs.existsSync(cleanPath)) {
const clean = JSON.parse(fs.readFileSync(cleanPath, 'utf8'));
const cleanByName = new Map(clean.map(c => [c.name, c]));
for (const c of out) {
const cl = cleanByName.get(c.name);
if (!cl) continue;
for (let k = 1; k < c.steps.length; k++) {
total++;
if (cl.steps[k] !== c.steps[k]) { diff++; diffCases.add(c.name); }
}
}
}
console.log('reference-torus.json записан:', outPath);
console.log(`кейсов: ${out.length}, сравнений clean(жёстк.)-vs-torus: ${total}, расхождений: ${diff}`);
console.log('кейсы, где torus ≠ жёсткие границы:', [...diffCases].join(', ') || '(нет)');