Mazes

Maze generators, based on Mazes for Programmers

Source Code for this Sketch

const north = 0
const south = 1
const west = 2
const east = 3

class Cell{
    constructor(col, row) {
        this.col = col;
        this.row = row;
        this.links = {}
    }

    link(direction) {
        this.links[direction] = true
    }

    unlink(direction) {
        delete this.links[direction]
    }

    linked(direction) {
        return this.links.hasOwnProperty(direction)
    }
}

class Grid{
    constructor(columns, rows){
        this.grid = []

        for(let row=0; row<rows; row++){
            this.grid[row] = []
            for(let col=0; col<columns; col++){
                this.grid[row][col] = new Cell(this, col, row)
            }
        }
    }

    visit(func) {
        for (let row=0; row<this.grid.length; row++) {
            for (let col=0; col<this.grid[row].length; col++){
                func(this.grid[row][col], col, row)
            }
        }
    }

    random(func) {
        let row = random(0, this.grid.length)
        let col = random(0, this.grid[row].length)

        func(this.grid[row][col], col, row)
    }

    at(col, row) {
        return this.grid[row][col]
    }

    draw(width, height) {
        let boxHeight = height/this.grid.length
        let boxWidth = width/this.grid[0].length

        fill(100)
        stroke(0)
        strokeWeight(1)
        rect(0, 0, width, height)

        this.visit((cell, col, row) => {
            if(!cell.linked(north)) {
                // north wall
                line(col*boxWidth, row*boxHeight, (col+1)*boxWidth, row*boxHeight)
            }
            if(!cell.linked(east)) {
                // east wall
                line((col+1)*boxWidth, row*boxHeight, (col+1)*boxWidth, (row+1)*boxHeight)
            }
            // west wall
            // line(col*boxWidth, row*boxHeight, col*boxWidth, (row+1)*boxHeight)
            // south wall
            // line(col*boxWidth, (row+1)*boxHeight, (col+1)*boxWidth, (row+1)*boxHeight)
        })
    }
}

class BinaryTreeMaze extends Grid {
    constructor(columns, rows) {
        super(columns, rows);

        this.visit((cell, col, row) => {
            let choices = []
            if(col !== columns-1) {
                choices.push(east)
            }
            if(row !== 0) {
                choices.push(north)
            }

            if(choices.length > 0) {
                cell.link(random(choices))
            }
        })
    }
}

class SidewinderMaze extends Grid {
    constructor(columns, rows) {
        super(columns, rows)

        let run = []
        this.visit((cell, col, row) => {
            run.push(cell)

            let direction = random([north, east])
            if(col === columns-1 || (direction === north && row !== 0)) {
                random(run).link(north)
                run = []
            } else {
                cell.link(east)
            }
        })
    }
}

let maze

function setup() {
    createCanvas(800, 400, P2D, canvas)
    chrisDefaults()
    circle(width/2, height/2, 200)

    const cols = 40
    const rows = 20

    maze = new Grid(cols, rows)

    new NativeButton("Reset", function (){
        maze = new Grid(cols, rows)
    })
    new NativeButton("Binary Tree Maze", function (){
        maze = new BinaryTreeMaze(cols, rows)
    })
    new NativeButton("Sidewinder Maze", function (){
        maze = new SidewinderMaze(cols, rows)
    })
}

function draw() {
    maze.draw(width, height)
}


You may use all or part of the p5 code seen on this page for your own creations, without restriction. Attribution is appreciated but not required.

This sketch also includes the following sources: p5common.js . Sources are available under their respective licenses.

See all p5.js sketches