import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
import { dirname, resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
import { describe, expect, it } from 'vitest';
import { encodeMap, parseMap } from '../../packages/engine/src/map/mapFormat';
import { buildMeadowsMap, buildPondsMap, buildZvenetsMap } from '../../apps/game/src/data/map';
/**
* Генератор карт-файлов: `npm run maps` (vitest run tools/maps/gen.test.ts).
* Карты строятся из data/map.ts (единый источник истины), пакуются в RLE
* через движковый encodeMap и пишутся в apps/game/assets/maps/*.map.
* Здесь же проверяется обратная распаковка: parseMap должен вернуть карту
* попиксельно равную исходной.
*/
const here = dirname(fileURLToPath(import.meta.url));
const outDir = resolve(here, '../../apps/game/assets/maps');
const MAPS: Record<string, ReturnType<typeof buildMeadowsMap>> = {
meadows: buildMeadowsMap(),
ponds: buildPondsMap(),
zvenets: buildZvenetsMap()
};
describe('карты-файлы на диске равны генераторам (fresh)', () => {
for (const [id, data] of Object.entries(MAPS)) {
it(`${id}.map не разъехался с генератором (npm run maps лечит)`, () => {
const path = resolve(outDir, `${id}.map`);
const onDisk = JSON.parse(readFileSync(path, 'utf8'));
expect(onDisk).toEqual(encodeMap(data));
});
}
});
describe('генерация карт-файлов (rpg-map, RLE)', () => {
for (const [id, data] of Object.entries(MAPS)) {
it(`${id}: encode -> файл -> parse восстанавливает карту`, () => {
const file = encodeMap(data);
const back = parseMap(JSON.parse(JSON.stringify(file)));
expect(back.width).toBe(data.width);
expect(back.height).toBe(data.height);
expect(back.blocked).toEqual(data.blocked);
expect(back.tiles).toEqual(data.tiles);
expect(back.tall).toEqual(data.tall);
mkdirSync(outDir, { recursive: true });
const path = resolve(outDir, `${id}.map`);
writeFileSync(path, JSON.stringify(file));
});
}
it('RLE реально сжимает карты', () => {
for (const [id, data] of Object.entries(MAPS)) {
const file = encodeMap(data);
const pairs = file.tiles as [number, number][];
// Серий меньше, чем тайлов: RLE что-то ужал, несмотря на пятнистость
expect(pairs.length).toBeLessThan(data.tiles.length);
expect(file.encoding).toBe('rle');
expect(id.length).toBeGreaterThan(0);
}
});
});