Add tests and move constants to config

This commit is contained in:
Peter Stockings
2026-01-04 10:27:27 +11:00
parent 6e3763a17b
commit f3607bc167
9 changed files with 484 additions and 35 deletions

View File

@@ -1,5 +1,6 @@
import { type World, type EntityId, type RunState, type Tile, type Actor, type Vec2 } from "./types";
import { idx } from "./world";
import { GAME_CONFIG } from "./config/GameConfig";
interface Room {
x: number;
@@ -16,9 +17,15 @@ function seededRandom(seed: number): () => number {
};
}
export function makeTestWorld(level: number, runState: RunState): { world: World; playerId: EntityId } {
const width = 60;
const height = 40;
/**
* Generates a procedural dungeon world with rooms and corridors
* @param level The level number (affects difficulty and randomness seed)
* @param runState Player's persistent state across levels
* @returns Generated world and player ID
*/
export function generateWorld(level: number, runState: RunState): { world: World; playerId: EntityId } {
const width = GAME_CONFIG.map.width;
const height = GAME_CONFIG.map.height;
const tiles: Tile[] = new Array(width * height).fill(1); // Start with all walls
const fakeWorldForIdx: World = { width, height, tiles, actors: new Map(), exit: { x: 0, y: 0 } };
@@ -26,11 +33,11 @@ export function makeTestWorld(level: number, runState: RunState): { world: World
// Generate rooms
const rooms: Room[] = [];
const numRooms = 8 + Math.floor(random() * 6); // 8-13 rooms
const numRooms = GAME_CONFIG.map.minRooms + Math.floor(random() * (GAME_CONFIG.map.maxRooms - GAME_CONFIG.map.minRooms + 1));
for (let i = 0; i < numRooms; i++) {
const roomWidth = 5 + Math.floor(random() * 8); // 5-12
const roomHeight = 4 + Math.floor(random() * 7); // 4-10
const roomWidth = GAME_CONFIG.map.roomMinWidth + Math.floor(random() * (GAME_CONFIG.map.roomMaxWidth - GAME_CONFIG.map.roomMinWidth + 1));
const roomHeight = GAME_CONFIG.map.roomMinHeight + Math.floor(random() * (GAME_CONFIG.map.roomMaxHeight - GAME_CONFIG.map.roomMinHeight + 1));
const roomX = 1 + Math.floor(random() * (width - roomWidth - 2));
const roomY = 1 + Math.floor(random() * (height - roomHeight - 2));
@@ -108,7 +115,7 @@ export function makeTestWorld(level: number, runState: RunState): { world: World
id: playerId,
isPlayer: true,
pos: { x: playerX, y: playerY },
speed: 100,
speed: GAME_CONFIG.player.speed,
energy: 0,
stats: { ...runState.stats },
inventory: { gold: runState.inventory.gold, items: [...runState.inventory.items] }
@@ -116,7 +123,7 @@ export function makeTestWorld(level: number, runState: RunState): { world: World
// Place enemies in random rooms (skip first room with player)
let enemyId = 2;
const numEnemies = 3 + level + Math.floor(random() * 4); // Increases with level
const numEnemies = GAME_CONFIG.enemy.baseCount + level * GAME_CONFIG.enemy.baseCountPerLevel + Math.floor(random() * GAME_CONFIG.enemy.randomBonus);
for (let i = 0; i < numEnemies && i < rooms.length - 1; i++) {
const roomIdx = 1 + Math.floor(random() * (rooms.length - 1));
@@ -126,20 +133,20 @@ export function makeTestWorld(level: number, runState: RunState): { world: World
const enemyY = room.y + 1 + Math.floor(random() * (room.height - 2));
// Vary enemy stats by level
const baseHp = 8 + level * 2;
const baseAttack = 3 + Math.floor(level / 2);
const baseHp = GAME_CONFIG.enemy.baseHp + level * GAME_CONFIG.enemy.baseHpPerLevel;
const baseAttack = GAME_CONFIG.enemy.baseAttack + Math.floor(level / 2) * GAME_CONFIG.enemy.attackPerTwoLevels;
actors.set(enemyId, {
id: enemyId,
isPlayer: false,
pos: { x: enemyX, y: enemyY },
speed: 80 + Math.floor(random() * 50), // 80-130 speed
speed: GAME_CONFIG.enemy.minSpeed + Math.floor(random() * (GAME_CONFIG.enemy.maxSpeed - GAME_CONFIG.enemy.minSpeed)),
energy: 0,
stats: {
maxHp: baseHp + Math.floor(random() * 4),
hp: baseHp + Math.floor(random() * 4),
attack: baseAttack + Math.floor(random() * 2),
defense: Math.floor(random() * 3)
defense: Math.floor(random() * (GAME_CONFIG.enemy.maxDefense + 1))
}
});
enemyId++;
@@ -147,3 +154,8 @@ export function makeTestWorld(level: number, runState: RunState): { world: World
return { world: { width, height, tiles, actors, exit }, playerId };
}
// Backward compatibility - will be removed in Phase 2
/** @deprecated Use generateWorld instead */
export const makeTestWorld = generateWorld;