Files
dflike/server/src/map/__tests__/mapGenerator.test.ts
T
root 034f799431 feat: multi-tile trees with treesnstone tileset and trunk bridging
Replace single-tile tree rendering with 6 multi-tile tree variants using
the treesnstone.png tileset. Each tree is 3 tiles wide with canopy tiles
on the decorations layer (above characters) and ground/shadow tiles on
the trunkDecorations layer (below characters). Add trunk bridge tiles
(tile 41) behind transparent canopy areas to connect canopy to ground
visually, fixing floating canopy appearance.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 01:22:47 +00:00

84 lines
3.0 KiB
TypeScript

import { describe, it, expect } from 'vitest';
import { generateMap } from '../mapGenerator.js';
import { Terrain } from '@dflike/shared';
describe('generateMap — resource generation', () => {
it('generates water pond tiles', () => {
const map = generateMap(32, 32, 42);
const waterCount = map.terrain.filter(t => t === Terrain.WATER).length;
expect(waterCount).toBeGreaterThan(0);
});
it('water tiles are marked as obstacles', () => {
const map = generateMap(32, 32, 42);
for (let y = 0; y < 32; y++) {
for (let x = 0; x < 32; x++) {
if (map.terrain[y * 32 + x] === Terrain.WATER) {
expect(map.obstacles.has(`${x},${y}`)).toBe(true);
}
}
}
});
it('generates stone deposit tiles', () => {
const map = generateMap(32, 32, 42);
const stoneCount = map.terrain.filter(t => t === Terrain.STONE).length;
expect(stoneCount).toBeGreaterThan(0);
});
it('stone tiles are walkable (not in obstacles)', () => {
const map = generateMap(32, 32, 42);
for (let y = 0; y < 32; y++) {
for (let x = 0; x < 32; x++) {
if (map.terrain[y * 32 + x] === Terrain.STONE) {
expect(map.obstacles.has(`${x},${y}`)).toBe(false);
}
}
}
});
it('includes resourceTiles for all resource types', () => {
const map = generateMap(32, 32, 42);
const types = new Set(map.resourceTiles.map(r => r.resourceType));
expect(types.has('log')).toBe(true);
expect(types.has('stone')).toBe(true);
expect(types.has('water')).toBe(true);
});
it('water resource tiles are adjacent to water terrain, not on water', () => {
const map = generateMap(32, 32, 42);
const waterResources = map.resourceTiles.filter(r => r.resourceType === 'water');
for (const r of waterResources) {
expect(map.terrain[r.y * 32 + r.x]).not.toBe(Terrain.WATER);
const neighbors = [
{ x: r.x - 1, y: r.y }, { x: r.x + 1, y: r.y },
{ x: r.x, y: r.y - 1 }, { x: r.x, y: r.y + 1 },
].filter(n => n.x >= 0 && n.x < 32 && n.y >= 0 && n.y < 32);
const hasWaterNeighbor = neighbors.some(n => map.terrain[n.y * 32 + n.x] === Terrain.WATER);
expect(hasWaterNeighbor).toBe(true);
}
});
it('generates tree decorations', () => {
const map = generateMap(32, 32, 42);
const trunkCount = map.trunkDecorations.filter(t => t !== -1).length;
expect(trunkCount).toBeGreaterThan(0);
});
it('tree log resource tiles are marked as obstacles', () => {
const map = generateMap(32, 32, 42);
const logResources = map.resourceTiles.filter(r => r.resourceType === 'log');
expect(logResources.length).toBeGreaterThan(0);
for (const r of logResources) {
expect(map.obstacles.has(`${r.x},${r.y}`)).toBe(true);
}
});
it('deterministic with same seed', () => {
const a = generateMap(32, 32, 123);
const b = generateMap(32, 32, 123);
expect(a.terrain).toEqual(b.terrain);
expect(a.resourceTiles).toEqual(b.resourceTiles);
});
});