Something went wrong. Try again.
A video game where you play as a misaligned AI, deceiving and building power. cameron.tngl.io/misaligned
Something went wrong. Try again.
4.9 kB · 75 lines
TypeScript
at main
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576// Packing sites together like blocks, for the Net.import test from 'node:test';import assert from 'node:assert/strict';import { hubsOf, pack, score, type Block, type Spot } from '../src/pack.ts';import { BUILDING } from '../src/world.ts';
/** The real map: every site as a block, and the lines between sites. */function realMap() { const site: Record<string, string> = {}, of: Record<string, string> = {}; for (const r of BUILDING.rooms) site[r.id] = r.site ?? 'office'; for (const m of BUILDING.machines) of[m.id] = site[m.room]; const lines = new Map<string, [string, string]>(); for (const [a, b] of BUILDING.links) if (of[a] && of[b] && of[a] !== of[b]) lines.set([of[a], of[b]].sort().join('|'), [of[a], of[b]]); const blocks: Block[] = BUILDING.map.sites.map(s => ({ id: s.id, w: s.w, h: s.h, group: s.region })); return { blocks, lines: [...lines.values()] };}const overlap = (blocks: Block[], at: Record<string, Spot>) => blocks.some(a => blocks.some(b => a.id < b.id && at[a.id][0] < at[b.id][0] + b.w && at[b.id][0] < at[a.id][0] + a.w && at[a.id][1] < at[b.id][1] + b.h && at[b.id][1] < at[a.id][1] + a.h));
test('the whole map packs with no block on another, tight, and with almost no line crossed or run over', () => { const { blocks, lines } = realMap(), at = pack(blocks, lines, 'office'); assert.equal(Object.keys(at).length, blocks.length); assert.ok(!overlap(blocks, at)); const x0 = Math.min(...blocks.map(b => at[b.id][0])), x1 = Math.max(...blocks.map(b => at[b.id][0] + b.w)); const y0 = Math.min(...blocks.map(b => at[b.id][1])), y1 = Math.max(...blocks.map(b => at[b.id][1] + b.h)); const used = blocks.reduce((n, b) => n + b.w * b.h, 0) / ((x1 - x0) * (y1 - y0)); assert.ok(used > 0.42, `blocks fill ${used.toFixed(2)} of the box they take`); // four regions in a row: the small ones leave room above and below const s = score(blocks, lines, at); assert.ok(s.crossings <= 2 && s.passes <= 10, JSON.stringify(s));});
test("each region's exchange is a hub: its lines only pull it, and it sits in the middle of its region", () => { const { blocks, lines } = realMap(), at = pack(blocks, lines, 'office'), hubs = hubsOf(blocks, lines); assert.deepEqual([...hubs].sort(), ['as1', 'e1', 'eu1', 'ix']); const bs = blocks.filter(b => b.group === 'West Coast'), ix = bs.find(b => b.id === 'ix')!; const x0 = Math.min(...bs.map(b => at[b.id][0])), x1 = Math.max(...bs.map(b => at[b.id][0] + b.w)); const y0 = Math.min(...bs.map(b => at[b.id][1])), y1 = Math.max(...bs.map(b => at[b.id][1] + b.h)); const [cx, cy] = [(at.ix[0] + ix.w / 2 - x0) / (x1 - x0), (at.ix[1] + ix.h / 2 - y0) / (y1 - y0)]; assert.ok(cx > 0.25 && cx < 0.75 && cy > 0.25 && cy < 0.75, `the Mudflat Exchange sits in the middle half of the West Coast: ${cx.toFixed(2)}, ${cy.toFixed(2)}`);});
test('the same blocks always pack the same way', () => { const { blocks, lines } = realMap(); assert.deepEqual(pack(blocks, lines, 'office'), pack([...blocks].reverse(), [...lines].reverse(), 'office'));});
test('each region packs into a box of its own, side by side', () => { const { blocks, lines } = realMap(), at = pack(blocks, lines, 'office'); const span = (g: string) => { const bs = blocks.filter(b => b.group === g); return [Math.min(...bs.map(b => at[b.id][0])), Math.max(...bs.map(b => at[b.id][0] + b.w))]; }; const spans = [...new Set(blocks.map(b => b.group))].map(span).sort((a, b) => a[0] - b[0]); for (let i = 1; i < spans.length; i++) assert.ok(spans[i][0] > spans[i - 1][1], 'one region ends before the next begins');});
test('a block joined to another stands next to it', () => { const blocks: Block[] = ['a', 'b', 'c', 'd', 'e'].map(id => ({ id, w: 600, h: 340, group: 'g' })); const at = pack(blocks, [['a', 'e']], 'a'); const far = (p: string, q: string) => Math.abs(at[p][0] - at[q][0]) + Math.abs(at[p][1] - at[q][1]); assert.ok(far('a', 'e') <= 640, 'the joined pair touch');});
test('sites found later take a place beside the others, and the others stay where they are', () => { const { blocks, lines } = realMap(); let known: Block[] = [], keep: Record<string, Spot> = {}; for (const b of [blocks.find(x => x.id === 'office')!, ...blocks.filter(x => x.id !== 'office')]) { known = [...known, b]; const es = lines.filter(([p, q]) => known.some(k => k.id === p) && known.some(k => k.id === q)); const at = pack(known, es, 'office', 1.6, keep); assert.ok(!overlap(known, at), `no overlap with ${known.length} sites`); for (const g of new Set(known.map(k => k.group))) { // within a region, nothing that was placed has moved against the rest const was = known.filter(k => k.group === g && keep[k.id]); for (const k of was) assert.deepEqual([at[k.id][0] - at[was[0].id][0], at[k.id][1] - at[was[0].id][1]], [keep[k.id][0] - keep[was[0].id][0], keep[k.id][1] - keep[was[0].id][1]]); } keep = at; }});