JS Recursive Division Maze

Recursive Division Maze with Vanilla JavaScript

by Mohammed Affan

HTML

<div id="grid"></div>

CSS

body {
    display: flex;
    height: 100vh;
    justify-content: center;
    align-items: center;
}

#grid {
    display: grid;
    grid-template-columns: repeat(50, 15px);

}

.node {
    width: 15px;
    height: 15px;
    border: 1px solid black;
}

.wall {
    background: black;
}

JavaScript

const width = 50;
const height = 20;
const nodes = [];

const getRandomInt = (max) => {
  return Math.floor(Math.random() * max);
};

const pointToString = (pos) => {
  return `${pos.x}, ${pos.y}`;
};

for (let y = 0; y < height; y++) {
  const row = [];
  for (let x = 0; x < width; x++) {
    row.push({
      x: x,
      y: y,
    });
  }
  nodes.push(row);
}

gridDiv = document.getElementById("grid");

nodes.flat().forEach((node) => {
  const nodeDiv = document.createElement("div");
  nodeDiv.setAttribute("class", "node");
  nodeDiv.setAttribute("data-pos", pointToString(node));
  gridDiv.appendChild(nodeDiv);
});

const addWallsToUI = (walls) => {
  for (const wall of walls) {
    const nodeToChange = document.querySelector(`div[data-pos="${wall}"]`)
    nodeToChange.classList.add("wall");
  }
};

const addBorders = (width, height) => {
  const borders = [];
  for (let i = 0; i < width; i++) {
    borders.push(pointToString({ x: i, y: 0 }));
  }
  for (let i = 0; i < height; i++) {
    borders.push(pointToString({ x: width - 1, y: i }));
  }
  for (let i = width - 1; i >= 0; i--) {
    borders.push(pointToString({ x: i, y: height - 1 }));
  }
  for (let i = height - 1; i >= 0; i--) {
    borders.push(pointToString({ x: 0, y: i }));
  }

  return borders;
};

const borders = addBorders(width, height);

addWallsToUI(borders);

const generateRecursiveDivisionMaze = (width, height) => {
  // The algorithm considers the grid as a "room", storing the coordinates of the top left node
  // And the top right node.

  const walls = [];
  const topLeft = { x: 0, y: 0 };
  const bottomRight = { x: width, y: height };

  // Running the recursive function
  divide(walls, topLeft, bottomRight);
  return walls;
};

const chooseOrientation = (width, height) => {
  
  if (width < height) {
    // The room is upright
    return "vertical";
  } else if (height < width) {
    // The room is sideways
    return "horizontal";
  } else {
    // The room is square. So just use a...