Simple Maze

by Spencer Smith

HTML

<canvas width="100" height="100"></canvas>

CSS

canvas {
  background-color: #333;
}

JavaScript

const dim = 5;
const graph = {};
const path = [];

const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
ctx.lineWidth = 10;
ctx.strokeStyle="white";

const border = ctx.lineWidth / 2;
const part = (canvas.width - border*2) / dim;


// create graph
for (let i = 0; i < dim*dim; i++) {
  const row = i % dim;
  const col = Math.floor(i / dim);
  const edges = [
    getIndex(row + 1, col),
    getIndex(row -1, col),
    getIndex(row, col + 1),
    getIndex(row, col - 1),
  ].filter(e => e != null);
  graph[i] = {
    edges: shuffle(edges),
  };
}

// create maze path
explore(graph, Math.floor(Math.random() * (dim*dim) + 1));

console.log('graph:', graph);
console.log('path:', path);

draw(path);

function getIndex(row, col) {
  if (row >= dim || row < 0 || col >= dim || col < 0) return null;
  return (col * dim) + row;
}

function shuffle(array) {
  for(let i = 0; i < array.length; i++){
    const randomIndex = Math.floor(Math.random() * array.length);
    const temp = array[i];
    array[i] = array[randomIndex];
    array[randomIndex] = temp;
  }
  return array;
}

function explore(graph, currentIndex) {
  const current = graph[currentIndex];
  current.visited = true;
  for (let i = 0; i < current.edges.length; i++) {
    const nextIndex = current.edges[i];
    const next = graph[nextIndex];
    if (!next.visited) {
      path.push([currentIndex, nextIndex]);
      explore(graph, nextIndex);
    }
  }
}

async function draw(path) {
  for (let i = 0; i < path.length; i++) {
    const [currentIndex, nextIndex] = path[i];
    const [cx, cy] = getXY(currentIndex);
    const [nx, ny] = getXY(nextIndex);

    const maxX = Math.max(cx, nx);
    const minX = Math.min(cx, nx);
    const maxY = Math.max(cy, ny);
    const minY = Math.min(cy, ny);

    const comp = ctx.lineWidth / 2;

    if (cx === nx) { // vertical
      ctx.moveTo(cx, maxY + comp);
      ctx.lineTo(cx, minY - comp);
    } else { // horizonal
      ctx.moveTo(minX - comp,...