add testing infrastructure and example test (#276)

This commit is contained in:
evanpelle
2025-03-17 12:20:23 -07:00
committed by GitHub
parent bd91d7c00b
commit cd1f8b9586
15 changed files with 246 additions and 464 deletions
+19 -66
View File
@@ -2,23 +2,8 @@ import { decodePNGFromStream } from "pureimage";
import path from "path";
import fs from "fs/promises";
import { createReadStream } from "fs";
import { fileURLToPath } from "url";
import { Readable } from "stream";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const maps = [
"Africa",
"Asia",
"WorldMap",
"BlackSea",
"Europe",
"Mars",
"Mena",
"Oceania",
"NorthAmerica",
"SouthAmerica",
];
const min_island_size = 30;
interface Coord {
@@ -38,21 +23,14 @@ class Terrain {
constructor(public type: TerrainType) {}
}
async function loadTerrainMap(mapName: string): Promise<void> {
const imagePath = path.resolve(
__dirname,
"..",
"..",
"resources",
"maps",
mapName + ".png",
);
export async function generateMap(
imageBuffer: Buffer,
): Promise<{ map: Uint8Array; miniMap: Uint8Array }> {
const stream = Readable.from(imageBuffer);
const img = await decodePNGFromStream(stream);
const readStream = createReadStream(imagePath);
const img = await decodePNGFromStream(readStream);
console.log(`${mapName}: Image loaded successfully`);
console.log(`${mapName}: `, "Image dimensions:", img.width, "x", img.height);
console.log("Image loaded successfully");
console.log("Image dimensions:", img.width, "x", img.height);
const terrain: Terrain[][] = Array(img.width)
.fill(null)
@@ -79,34 +57,17 @@ async function loadTerrainMap(mapName: string): Promise<void> {
}
removeSmallIslands(terrain);
removeSmallLakes(mapName, terrain);
removeSmallLakes(terrain);
const shorelineWaters = processShore(terrain);
processDistToLand(shorelineWaters, terrain);
processOcean(terrain);
const outputPath = path.join(
__dirname,
"..",
"..",
"resources",
"maps",
mapName + ".bin",
);
fs.writeFile(outputPath, packTerrain(mapName, terrain));
const miniTerrain = await createMiniMap(terrain);
const miniOutputPath = path.join(
__dirname,
"..",
"..",
"resources",
"maps",
mapName + "Mini.bin",
);
fs.writeFile(miniOutputPath, packTerrain(mapName, miniTerrain));
}
export async function loadTerrainMaps() {
await Promise.all(maps.map((map) => loadTerrainMap(map)));
return {
map: packTerrain(terrain),
miniMap: packTerrain(miniTerrain),
};
}
export async function createMiniMap(tm: Terrain[][]): Promise<Terrain[][]> {
@@ -225,7 +186,7 @@ function processOcean(map: Terrain[][]) {
}
}
function packTerrain(mapName: string, map: Terrain[][]): Uint8Array {
function packTerrain(map: Terrain[][]): Uint8Array {
const width = map.length;
const height = map[0].length;
const packedData = new Uint8Array(4 + width * height);
@@ -262,7 +223,7 @@ function packTerrain(mapName: string, map: Terrain[][]): Uint8Array {
packedData[4 + y * width + x] = packedByte;
}
}
logBinaryAsBits(mapName, packedData);
logBinaryAsBits(packedData);
return packedData;
}
@@ -315,13 +276,11 @@ function removeSmallIslands(map: Terrain[][]) {
}
}
function removeSmallLakes(mapName: string, map: Terrain[][]) {
function removeSmallLakes(map: Terrain[][]) {
const visited = new Set<string>();
const min_lake_size = 200;
console.log(
`${mapName}: removing small lakes ${map.length}, ${map[0].length}`,
);
console.log(`removing small lakes ${map.length}, ${map[0].length}`);
for (let x = 0; x < map.length; x++) {
for (let y = 0; y < map[0].length; y++) {
@@ -341,15 +300,11 @@ function removeSmallLakes(mapName: string, map: Terrain[][]) {
}
}
function logBinaryAsBits(
mapName: string,
data: Uint8Array,
length: number = 8,
) {
function logBinaryAsBits(data: Uint8Array, length: number = 8) {
const bits = Array.from(data.slice(0, length))
.map((b) => b.toString(2).padStart(8, "0"))
.join(" ");
console.log(`${mapName}: Binary data (bits):`, bits);
console.log(`Binary data (bits):`, bits);
}
function getNeighborCoords(x: number, y: number, map: Terrain[][]): Coord[] {
@@ -368,5 +323,3 @@ function getNeighborCoords(x: number, y: number, map: Terrain[][]): Coord[] {
}
return coords;
}
await loadTerrainMaps();
+61
View File
@@ -0,0 +1,61 @@
import { generateMap } from "./TerrainMapGenerator.js";
import path from "path";
import fs from "fs/promises";
const maps = [
"Africa",
"Asia",
"WorldMap",
"BlackSea",
"Europe",
"Mars",
"Mena",
"Oceania",
"NorthAmerica",
"SouthAmerica",
];
async function loadTerrainMaps() {
await Promise.all(
maps.map(async (map) => {
const mapPath = path.resolve(
process.cwd(),
"resources",
"maps",
map + ".png",
);
const imageBuffer = await fs.readFile(mapPath);
const { map: mainMap, miniMap } = await generateMap(imageBuffer);
const outputPath = path.join(
process.cwd(),
"resources",
"maps",
map + ".bin",
);
const miniOutputPath = path.join(
process.cwd(),
"resources",
"maps",
map + "Mini.bin",
);
await Promise.all([
fs.writeFile(outputPath, mainMap),
fs.writeFile(miniOutputPath, miniMap),
]);
}),
);
}
async function main() {
try {
await loadTerrainMaps();
console.log("Terrain maps generated successfully");
} catch (error) {
console.error("Error generating terrain maps:", error);
process.exit(1);
}
}
main();