Infinite recursive maze

It's turtles all the way down

Log in to post a comment.

const seed = 1100; // min=1, max=2000, step=1
const width = 30; // min=15, max=50, step=1
const depth = 70; // min=20, max=150, step=1
const link = 5; // min=1, max=10, step=1
const draw_between = 1; // min=0, max=1, step=1 (No, Yes)

Canvas.setpenopacity(-1);

const t = new Turtle();

let cur_rand = seed;
function rand() { cur_rand = (cur_rand * 48271) % (2**31 - 1); return cur_rand; }
function rand_bool() { return rand() % 2 == 0; }
function rand_elem(ar) { return ar[rand() % ar.length]; }


const cells = [];
const visited = new Set();
const deleted_walls = new Set();

let x0 = -100, y0 = -100;
let s = 200 / width;

for (let i = 0; i < depth; i++) {
    for (let j = 0; j < width; j++) {
        cells.push([i, j, 0]); // level, x, y
        cells.push([i, j, width - 1]);
    }

    for (let j = 1; j < width - 1; j++) {
        cells.push([i, 0, j]);
        cells.push([i, width - 1, j]);
    }
}

function get_neighbours(level, x, y) {
    let neighb = [];

    if ((y == 0) || (y == width - 1)) {
        if (x > 0) {
            neighb.push([level, x - 1, y]);
        }

        if (x < width - 1) {
            neighb.push([level, x + 1, y]);
        }

        if ((level > 0) && (x > 0) && (x < width - 1)) {
            if ((Math.abs(width / 2 - x) < link) || (x < link) || (x > width - 1 - link)) {
                neighb.push([level - 1, x, y]);
            }
        }
        
        if ((level < depth - 1) && (x > 0) && (x < width - 1)) {
            if ((Math.abs(width / 2 - x) < link) || (x < link) || (x > width - 1 - link)) {
                neighb.push([level + 1, x, y]);
            }
        }
    }

    if ((x == 0) || (x == width - 1)) {
        if (y > 0) {
            neighb.push([level, x, y - 1]);
        }

        if (y < width - 1) {
            neighb.push([level, x, y + 1]);
        }

        if ((level > 0) && (y > 0) && (y < width - 1)) {
            if ((Math.abs(width / 2 - y) < link) || (y < link) || (y > width - 1 - link)) {
                neighb.push([level - 1, x, y]);
            }
        }
        
        if ((level < depth - 1) && (y > 0) && (y < width - 1)) {
            if ((Math.abs(width / 2 - y) < link) || (y < link) || (y > width - 1 - link)) {
                neighb.push([level + 1, x, y]);
            }
        }
    }
    
    return neighb;
}


let stack = [cells[0]];
visited.add(cells[0].toString());

while (stack.length > 0) {
    let cur = stack.pop();
    
    var cur_level, cur_x, cur_y;
    [cur_level, cur_x, cur_y] = cur;
    
    let neighb = get_neighbours(cur_level, cur_x, cur_y);
    
    let unvisited_neighb = [];
    for (let n of neighb) {
        if (! visited.has(n.toString())) {
            unvisited_neighb.push(n);
        }
    }
    
    if (unvisited_neighb.length > 0) {
        stack.push(cur);
        
        let next = rand_elem(unvisited_neighb);
        
        deleted_walls.add(cur.toString() + ' ' + next.toString());
        deleted_walls.add(next.toString() + ' ' + cur.toString());
        
        visited.add(next.toString());
        stack.push(next);
    }
}


let depth_shift = [-100];
let cell_size = [200 / width];

for (let i = 1; i < depth; i++) {
    depth_shift[i] = depth_shift[i - 1] + cell_size[i - 1];
    cell_size[i] = ((width - 2) * cell_size[i - 1]) / width;
}

for (let c of cells) {
    var cur_level, cur_x, cur_y;
    [cur_level, cur_x, cur_y] = c;
    
    let d = depth_shift[cur_level];
    let s = cell_size[cur_level];

    let neighb = get_neighbours(cur_level, cur_x, cur_y);

    let left = false, right = false, up = false, down = false;
    
    for (let n of neighb) {
        var n_level, n_x, n_y;
        [n_level, n_x, n_y] = n;
        
        let draw = ! deleted_walls.has(c.toString() + ' ' + n.toString());
        
        if ((n_level == cur_level) && (n_x == cur_x - 1)) {
            if (draw) {
                t.jump(d + cur_x * s, d + cur_y * s);
                t.goto(d + cur_x * s, d + (cur_y + 1) * s);
            }
            
            left = true;
        }

        if ((n_level == cur_level - 1) && (n_x == 0) && (cur_x == 0)) {
            if (draw) {
                t.jump(d + cur_x * s, d + cur_y * s);
                t.goto(d + cur_x * s, d + (cur_y + 1) * s);
            }
            
            left = true;
        }

        if ((n_level == cur_level + 1) && (n_x == width - 1) && (cur_x == width - 1)) {
            if (draw) {
                t.jump(d + cur_x * s, d + cur_y * s);
                t.goto(d + cur_x * s, d + (cur_y + 1) * s);
            }
            
            left = true;
        }

        if ((n_level == cur_level) && (n_y == cur_y - 1)) {
            if (draw) {
                t.jump(d + cur_x * s, d + cur_y * s);
                t.goto(d + (cur_x + 1) * s, d + cur_y * s);
            }
            
            up = true;
        }

        if ((n_level == cur_level - 1) && (n_y == 0) && (cur_y == 0)) {
            if (draw) {
                t.jump(d + cur_x * s, d + cur_y * s);
                t.goto(d + (cur_x + 1) * s, d + cur_y * s);
            }
            
            up = true;
        }

        if ((n_level == cur_level + 1) && (n_y == width - 1) && (cur_y == width - 1)) {
            if (draw) {
                t.jump(d + cur_x * s, d + cur_y * s);
                t.goto(d + (cur_x + 1) * s, d + cur_y * s);
            }
            
            up = true;
        }
    }
    
    if (draw_between == 1) {
        if (! left) {
            t.jump(d + cur_x * s, d + cur_y * s);
            t.goto(d + cur_x * s, d + (cur_y + 1) * s);
        }
    
        if (! up) {
            t.jump(d + cur_x * s, d + cur_y * s);
            t.goto(d + (cur_x + 1) * s, d + cur_y * s);
        }
    }
    
    // t.jump(d + cur_x * s, d + cur_y * s);
    // t.seth(0);
    // for (let k = 0; k < 4; k++) {
    //     t.forward(s);
    //     t.right(90);
    // }
    
    // let neighb = get_neighbours(cur_level, cur_x, cur_y);
    // for (let n of neighb) {
    //     var nlevel, nx, ny;
    //     [nlevel, nx, ny] = n;
    //     let dn = depth_shift[nlevel];
    //     let sn = cell_size[nlevel];
    //     t.jump(d + (cur_x + 0.5) * s, d + (cur_y + 0.5) * s);
    //     t.goto(dn + (nx + 0.5) * sn, dn + (ny + 0.5) * sn);
    // }
    
    // if (visited.has(c.toString())) {
    //     t.jump(d + (cur_x + 0.5) * s, d + (cur_y + 0.5) * s);
    //     t.seth(45);
    //     for (let i = 0; i < 4; i++) {
    //         t.forward(2);
    //         t.back(2);
    //         t.right(90);
    //     }
    // }
}