Skip to content

Instantly share code, notes, and snippets.

@darrenmason
Created July 4, 2023 23:12
Show Gist options
  • Save darrenmason/957b477f75287facad81f147aa4f80bf to your computer and use it in GitHub Desktop.
Save darrenmason/957b477f75287facad81f147aa4f80bf to your computer and use it in GitHub Desktop.
dungeon generator
class DungeonGenerator {
constructor(width, height, maxRooms, minRoomSize, maxRoomSize) {
this.width = width;
this.height = height;
this.maxRooms = maxRooms;
this.minRoomSize = minRoomSize;
this.maxRoomSize = maxRoomSize;
this.dungeon = [];
}
generateDungeon() {
// Initialize the dungeon grid
this.dungeon = new Array(this.height);
for (let y = 0; y < this.height; y++) {
this.dungeon[y] = new Array(this.width).fill('#');
}
// Generate rooms
const rooms = [];
for (let i = 0; i < this.maxRooms; i++) {
const roomWidth = Math.floor(Math.random() * (this.maxRoomSize - this.minRoomSize + 1)) + this.minRoomSize;
const roomHeight = Math.floor(Math.random() * (this.maxRoomSize - this.minRoomSize + 1)) + this.minRoomSize;
const x = Math.floor(Math.random() * (this.width - roomWidth - 1)) + 1;
const y = Math.floor(Math.random() * (this.height - roomHeight - 1)) + 1;
const room = new Room(x, y, roomWidth, roomHeight);
if (this.isRoomOverlap(room, rooms)) {
continue;
}
rooms.push(room);
// Carve the room into the dungeon grid
for (let row = room.y; row < room.y + room.height; row++) {
for (let col = room.x; col < room.x + room.width; col++) {
this.dungeon[row][col] = '.';
}
}
}
// Connect rooms with tunnels
for (let i = 0; i < rooms.length - 1; i++) {
const currentRoom = rooms[i];
const nextRoom = rooms[i + 1];
const startPoint = currentRoom.getCenter();
const endPoint = nextRoom.getCenter();
this.connectRooms(startPoint, endPoint);
}
return this.dungeon;
}
isRoomOverlap(room, rooms) {
for (const existingRoom of rooms) {
if (
room.x < existingRoom.x + existingRoom.width &&
room.x + room.width > existingRoom.x &&
room.y < existingRoom.y + existingRoom.height &&
room.y + room.height > existingRoom.y
) {
return true;
}
}
return false;
}
connectRooms(startPoint, endPoint) {
let x = startPoint.x;
let y = startPoint.y;
while (x !== endPoint.x || y !== endPoint.y) {
if (x !== endPoint.x) {
x += x < endPoint.x ? 1 : -1;
} else if (y !== endPoint.y) {
y += y < endPoint.y ? 1 : -1;
}
if (this.dungeon[y][x] === '#') {
this.dungeon[y][x] = '.';
}
}
}
}
class Room {
constructor(x, y, width, height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
getCenter() {
const centerX = Math.floor((this.x + this.x + this.width) / 2);
const centerY = Math.floor((this.y + this.y + this.height) / 2);
return { x: centerX, y: centerY };
}
}
// Example usage
const dungeonWidth = 40;
const dungeonHeight = 20;
const maxRooms = 10;
const minRoomSize = 3;
const maxRoomSize = 6;
const generator = new DungeonGenerator(dungeonWidth, dungeonHeight, maxRooms, minRoomSize, maxRoomSize);
const dungeon = generator.generateDungeon();
// Print the dungeon to the console
for (let y = 0; y < dungeonHeight; y++) {
console.log(dungeon[y].join(''));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment