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); // } // } }