feedback7: the battle sim uses engine-independent math — Chrome, Firefox, Safari and the server agree bit for bit (PR #373 by @Cloudnyco)
- server/sim/detmath.js: hypot (sqrt of the squares, rescaled outside 2^±500), powi (integer powers in double-double, one rounding), sin / cos (fdlibm 5.3) and atan2 (fdlibm / FreeBSD msun) built only from correctly rounded IEEE operations; the sim's Math.hypot / sin / cos / atan2 / pow calls go through it (65 files); eslint.config.js forbids the approximated Math functions under server/sim and test/sim/detmath.test.js scans for them. - sin / cos / atan2 are the algorithms V8 runs in Node, so the server's results stay; only hypot differs from V8's. Golden: 2 moved — diy-027 (a hypot distance, damage +80) and coop3-ABYSS-5 (a later card pick from round 9, same end). - Applied unchanged after review (Grok static review: MERGE; the diff read in full: no network, no new dependency). - Tests: broad node --test 5155 / 5155 with the new file tracked (detmath 7 / 7, package 10 / 10); lint 0 errors, typecheck, check:imports.
This commit is contained in:
1 parent
2580152a3a
commit
ae22335cfe
65 files changed
+616
-141
No files matched your search
@@ -37,6 +37,7 @@ import { COLS, ROWS } from '../constants.js';
|
||||
import { performAttack } from '../ai.js';
|
||||
import { sortEnemyTargets } from '../targeting.js';
|
||||
import { DIR_VEC, normDir, oppositeDir } from '../dir.js';
|
||||
import { hypot } from '../detmath.js';
|
||||
|
||||
const num = (v, d = 0) => (typeof v === 'number' && Number.isFinite(v) ? v : (typeof v === 'string' && v.trim() !== '' && Number.isFinite(+v) ? +v : d));
|
||||
/** ASPD blackboard values: a fraction (|v| < 1, e.g. −0.6 / −0.05) is ×100 ASPD, otherwise flat (+20). */
|
||||
@@ -192,7 +193,7 @@ function deviceTile(battle, r0, c0) {
|
||||
const exact = r === r0 && c === c0;
|
||||
if (!exact && battle.grid.tile(r, c).build !== 'NONE') continue;
|
||||
const walk = !exact && battle.grid.groundPassable(r, c, true) ? 1 : 0;
|
||||
const s = [exact ? 0 : 1, walk, Math.hypot(r - r0, c - c0), r * COLS + c];
|
||||
const s = [exact ? 0 : 1, walk, hypot(r - r0, c - c0), r * COLS + c];
|
||||
let less = !bs;
|
||||
if (!less) for (let i = 0; i < s.length; i++) { if (s[i] < bs[i] - 1e-9) { less = true; break; } if (s[i] > bs[i] + 1e-9) break; }
|
||||
if (less) { best = [r, c]; bs = s; }
|
||||
@@ -455,7 +456,7 @@ function tickAirflowEnemy(battle, st, e) {
|
||||
const r = Math.round(e.y), c = Math.round(e.x);
|
||||
const f = r >= 0 && r < ROWS && c >= 0 && c < COLS ? st.flow.get(r * COLS + c) : null;
|
||||
const vx = e.x - px, vy = e.y - py;
|
||||
const v = Math.hypot(vx, vy);
|
||||
const v = hypot(vx, vy);
|
||||
if (f && v > 1e-6) {
|
||||
const rel = airflowRelation((vx * f.fx + vy * f.fy) / v);
|
||||
if (rel !== 'vertical') mul = 1 + num(f.bb[`blower_s_enemy[${rel}].move_speed`], 0);
|
||||
|
||||
Reference in new issue
Block a user