/* ============================================================================ * policy-cases.js —— 评测题目生成(Node 与浏览器共用,UMD) * 2026-10-18 第六轮(审查 B-2):贴立柱题从 tests/policy_bench.cjs 移到这里,查看器 ?policy=…&autotest=N * 与 Node bench 用同一个种子出同一批题,安全层耗时两边可以逐题对照(浏览器 vs Node 差 > 3× 要解释)。 * 算法与原 bench 逐字一致:同种子出的题与第五轮之前相同。 * ==========================================================================*/ (function (root, factory) { if (typeof module === 'object' && module.exports) module.exports = factory(); else root.PolicyCases = factory(); }(typeof self !== 'undefined' ? self : this, function () { 'use strict'; function lcg(seed) { let s = seed >>> 0; return () => { s = (s * 1664525 + 1013904223) >>> 0; return s / 4294967296; }; } /* 贴立柱任务:终点贴立柱(±4° 扰动即碰立柱)、起点到终点直线被挡;返回 [{q0, T, R}] */ function ncCases(S, N, seed) { const L = S.LIM, O = S.ORDER, w = S.wrap180, rnd = lcg(seed); const rq = () => O.map(id => { const t = L[id]; return t.lo + rnd() * (t.hi - t.lo); }); const d = (a, b) => a.map((v, i) => L[O[i]].cont ? w(b[i] - v) : b[i] - v); const segOK = (a, b) => { const dd = d(a, b); const m = Math.max(...dd.map(Math.abs)); const n = Math.max(1, Math.ceil(m)); for (let i = 1; i <= n; i++) if (!S.collideFree(a.map((v, k) => v + dd[k] * i / n))) return false; return true; }; const hitsColumn = q => (S.collideDetail(q) || []).some(p => /立柱/.test(p.cnA + p.cnB)); const nearColumn = q => { for (const k of [0, 1, 2]) for (const sg of [-4, 4]) { const p = q.slice(); p[k] += sg; if (hitsColumn(p)) return true; } return false; }; const cases = []; let tries = 0; while (cases.length < N && tries < 4000000) { tries++; const b = rq(); if (!S.collideFree(b) || !nearColumn(b)) continue; let a = null; for (let t = 0; t < 200; t++) { const c = rq(); if (S.collideFree(c) && !segOK(c, b)) { a = c; break; } } if (a) cases.push({ q0: a, T: S.fk(b, 0), R: S.orient(b) }); } return cases; } return { lcg, ncCases }; }));