From fb4c394f71eb7b1efcbf5799bdbd0163b9599656 Mon Sep 17 00:00:00 2001 From: mmaheshwari2 Date: Fri, 24 Jan 2025 17:50:16 -0800 Subject: [PATCH] abstract random room generation --- test/test_generate_blueprint.js | 144 +++++++++++++++++++++----------- 1 file changed, 95 insertions(+), 49 deletions(-) diff --git a/test/test_generate_blueprint.js b/test/test_generate_blueprint.js index ed78fc3..7a3d824 100644 --- a/test/test_generate_blueprint.js +++ b/test/test_generate_blueprint.js @@ -1,5 +1,5 @@ -/** Build house +/** Build the foundation of the house * * @param position coordinate that specify where the house should be built. come in as [x,y,z] * @param windows an int that can be 0,1,2 for increasing frequencies of windows @@ -15,93 +15,139 @@ function buildHouse(position, windows, doors){ // slice up the space ensuring each compartment has at least 4x4x2 space. - const resultMatrix = generateMatrix(width, length, height, 3); + const resultMatrix = generateAbstractHouse(width, length, height, 3); console.log(resultMatrix) - // then, internally do things like windows / stairs / doors/ etc... + // todo: then, internally do things like windows / stairs / doors/ etc... } - -//Todo: make robust. add stairs and windows and stuff -function generateMatrix(m, n, p, compartmentCount = 5) { - const matrix = Array.from({ length: m }, () => - Array.from({ length: n }, () => - Array(p).fill('air') +/** + * + * @param m - length (x-axis) + * @param n - width (y-axis) + * @param p - depth (z-axis, how many layers) + * @param compartmentCount + * @returns {any[][][]} + */ +function generateAbstractHouse(m, n, p, compartmentCount = 5) { + const matrix = Array.from({ length: p }, () => + Array.from({ length: m }, () => + Array(n).fill('air') ) ); - // Mark borders - for (let i = 0; i < m; i++) { - for (let j = 0; j < n; j++) { - matrix[i][j][0] = matrix[i][j][p-1] = 'stone'; - matrix[i][0][j] = matrix[i][n-1][j] = 'stone'; - matrix[0][i][j] = matrix[m-1][i][j] = 'stone'; + // Mark entire outer border with 'stone' + for (let z = 0; z < p; z++) { + for (let x = 0; x < m; x++) { + for (let y = 0; y < n; y++) { + if ( + z === 0 || z === p - 1 || // Top and bottom faces + x === 0 || x === m - 1 || // Front and back faces + y === 0 || y === n - 1 // Left and right faces + ) { + matrix[z][x][y] = 'stone'; + } + } } } const usedSpaces = new Set(); - for (let _ = 0; _ < compartmentCount; _++) { - const width = Math.floor(Math.random() * 6) + 3; - const height = Math.floor(Math.random() * 6) + 3; - const depth = Math.floor(Math.random() * 3) + 2; + // Loop that places rooms + for (let roomCount = 0; roomCount < compartmentCount; roomCount++) { + const length = Math.max(4, Math.floor(Math.random() * 6) + 4); + const width = Math.max(4, Math.floor(Math.random() * 6) + 4); + const depth = Math.max(3, Math.floor(Math.random() * 6) + 4); + + let roomPlaced = false; for (let attempt = 0; attempt < 50; attempt++) { - const x = Math.floor(Math.random() * (m - height - 1)) + 1; + const x = Math.floor(Math.random() * (m - length - 1)) + 1; const y = Math.floor(Math.random() * (n - width - 1)) + 1; const z = Math.floor(Math.random() * (p - depth - 1)) + 1; - const spaceAvailable = !Array.from({ length: height }).some((_, di) => - Array.from({ length: width }).some((_, dj) => - Array.from({ length: depth }).some((_, dk) => - usedSpaces.has(`${x+di},${y+dj},${z+dk}`) + // Check space availability, excluding room's own edges (so that walls/ceilings can be shared) + console.log(`Attempting room: ${length}x${width}x${depth}`); + + const spaceAvailable = !Array.from({ length: depth }).some((_, di) => + Array.from({ length: length }).some((_, dj) => + Array.from({ length: width }).some((_, dk) => + // Exclude room's own edges from check + (di !== 0 && di !== depth - 1 && + dj !== 0 && dj !== length - 1 && + dk !== 0 && dk !== width - 1) && + usedSpaces.has(`${x + dj},${y + dk},${z + di}`) ) ) ); if (spaceAvailable) { - for (let di = 0; di < height; di++) { - for (let dj = 0; dj < width; dj++) { - matrix[x+di][y+dj][z] = 'stone'; - matrix[x+di][y+dj][z+depth-1] = 'stone'; - usedSpaces.add(`${x+di},${y+dj},${z}`); - usedSpaces.add(`${x+di},${y+dj},${z+depth-1}`); - } - } - for (let di = 0; di < height; di++) { - for (let dk = 0; dk < depth; dk++) { - matrix[x+di][y][z+dk] = 'stone'; - matrix[x+di][y+width-1][z+dk] = 'stone'; - usedSpaces.add(`${x+di},${y},${z+dk}`); - usedSpaces.add(`${x+di},${y+width-1},${z+dk}`); - } - } - for (let dj = 0; dj < width; dj++) { - for (let dk = 0; dk < depth; dk++) { - matrix[x][y+dj][z+dk] = 'stone'; - matrix[x+height-1][y+dj][z+dk] = 'stone'; - usedSpaces.add(`${x},${y+dj},${z+dk}`); - usedSpaces.add(`${x+height-1},${y+dj},${z+dk}`); + for (let di = 0; di < depth; di++) { + for (let dj = 0; dj < length; dj++) { + for (let dk = 0; dk < width; dk++) { + const spaceKey = `${x + dj},${y + dk},${z + di}`; + usedSpaces.add(spaceKey); + + if ( + z + di >= 0 && z + di < p && + x + dj >= 0 && x + dj < m && + y + dk >= 0 && y + dk < n + ) { + // Mark only the outer edges of the room + if (di === 0 || di === depth - 1 || + dj === 0 || dj === length - 1 || + dk === 0 || dk === width - 1) { + matrix[z + di][x + dj][y + dk] = 'stone'; + } + } + } } } + + + roomPlaced = true; break; } } + + if (!roomPlaced) { + console.warn(`Could not place room ${roomCount}`); + } } + // TODO: Convert layers matrix into the right format + return matrix; } +//todo: new sequetial funciton +/** + * + * @param matrix + */ +function randomSequentialHouse(m,n,p,rooms){ + // place 1 room randomly on the ground floor + //while the total number of rooms has not been reached +} + + + function printMatrix(matrix) { - matrix.forEach(row => { - console.log(row.join(' ')); // Join elements of the row into a single string separated by spaces + matrix.forEach((layer, layerIndex) => { + console.log(`Layer ${layerIndex}:`); + layer.forEach(row => { + console.log( + row.map(cell => cell === 'stone' ? '█' : '.').join(' ') + ); + }); + console.log('---'); }); } -const resultMatrix = generateMatrix(10, 10, 10, 3); +const resultMatrix = generateAbstractHouse(10, 20, 6, 6); printMatrix(resultMatrix)