// The forward pass IS the live bots' inference engine — hand-checked math.
import test from "node:test";
import assert from "node:assert/strict";
import { mlpForward, mlpInit } from "../dist/forward.js";
test("a 2-layer net matches hand-computed relu + linear", () => {
// hidden: 2 units over 2 inputs; output: 1 linear unit
const net = {
sizes: [2, 2, 1],
layers: [
{ w: [1, -1, 0.5, 0.5], b: [0, -2] }, // h0 = relu(x0 - x1), h1 = relu(0.5x0 + 0.5x1 - 2)
{ w: [3, -4], b: [0.25] }, // y = 3h0 - 4h1 + 0.25
],
};
assert.deepEqual(mlpForward(net, [2, 1]), [3 * 1 - 4 * 0 + 0.25]);
assert.deepEqual(mlpForward(net, [3, 3]), [3 * 0 - 4 * 1 + 0.25]);
assert.deepEqual(mlpForward(net, [0, 3]), [0.25], "both hidden units clamped by relu");
});
test("mlpInit shapes match the sizes and a seeded rand is deterministic", () => {
const seq = (s) => () => (s = (s * 16807) % 2147483647) / 2147483647;
const a = mlpInit([9, 32, 1], seq(7));
const b = mlpInit([9, 32, 1], seq(7));
assert.deepEqual(a.sizes, [9, 32, 1]);
assert.equal(a.layers[0].w.length, 32 * 9);
assert.equal(a.layers[0].b.length, 32);
assert.equal(a.layers[1].w.length, 1 * 32);
assert.ok(a.layers[1].b.every((x) => x === 0), "biases start at zero");
assert.deepEqual(a, b, "same rand stream, same net");
});