Maze generator, according to en.wikipedia.org/wik…ative_implementation
Log in to post a comment.
// You can find the Turtle API reference here: https://turtletoy.net/syntax
Canvas.setpenopacity(1);
const size = 90; //min = 10, max = 100, step = 5
const grid = 30; // min = 3, max = 80, step = 1
// Global code will be evaluated once.
const turtle = new Turtle();
let cells = [];
let vWalls = [];
let hWalls = [];
let stack = [];
let maxIndex = grid**2;
class Cell{
constructor(i, j){
this.i = i;
this.j = j;
this.visited = false;
// this.twice = false;
this.list = [];
if(this.i > 0) this.list.push([-1, 0]);
if(this.j > 0) this.list.push([0, -1]);
if(this.i < grid - 1) this.list.push([1, 0]);
if(this.j < grid - 1) this.list.push([0, 1]);
}
getNeighbor(){
this.visited = true;
for(let i = this.list.length - 1; i >= 0; i--){
const index = this.list[i];
const x = this.i + index[0];
const y = this.j + index[1];
const cell = cells[x][y];
if(cell.visited){
const tmp = this.list.slice(0, i);
this.list = this.list.slice(i);
this.list.shift();
this.list = tmp.concat(this.list);
}
}
const length = this.list.length;
if(length){
// this.twice = 1;
const index = this.list[Math.floor(Math.random() * length)];
let x = this.i;
let y = this.j;
if(index[0] != 0){
// deplacing left or right
if(index[0] > 0) vWalls[x + 1][y] = 0;
else vWalls[x][y] = 0;
} else if(index[1] != 0){
// deplacing up or down
if(index[1] > 0) hWalls[x][y + 1] = 0;
else hWalls[x][y] = 0;
}
// console.log(this.i, this.j, index, hWalls[x][y], vWalls[x + 1][y], hWalls[x][y + 1], vWalls[x][y])
x += + index[0];
y += + index[1];
return cells[x][y];
} else {
return null;
}
}
draw(){
const cellSize = (size * 2) / grid;
const posx = this.i * cellSize - cellSize * grid / 2;
const posy = this.j * cellSize - cellSize * grid / 2;
turtle.jump(posx, posy);
turtle.seth(0);
for(let i = 0; i < 4; i++){
turtle.forward(cellSize);
turtle.right(90);
}
/*
if(this.twice){
turtle.jump(posx + 1, posy + 1);
for(let i = 0; i < 4; i++){
turtle.forward(cellSize - 2);
turtle.right(90);
}
}
*/
}
}
for(let j = 0; j < grid; j++){
let row = [];
for(let i = 0; i < grid; i++){
row.push(new Cell(j, i));
// console.log(i, j);
}
cells.push(row);
}
for(let j = 0; j <= grid; j++){
let row = [];
for(let i = 0; i < grid; i++){
row.push(1);
}
vWalls.push(row);
}
for(let j = 0; j < grid; j++){
let row = [];
for(let i = 0; i <= grid; i++){
row.push(1);
}
hWalls.push(row);
}
function drawWalls(){
const cellSize = (size * 2) / grid;
for(let j = 0; j <= grid; j++){
for(let i = 0; i < grid; i++){
// console.log(i, j);
const posx = i * cellSize - cellSize * grid / 2;
const posy = j * cellSize - cellSize * grid / 2;
if(vWalls[i][j]){
turtle.jump(posx, posy);
turtle.goto(posx, posy + cellSize);
}
if(hWalls[i][j]){
turtle.jump(posx, posy);
turtle.goto(posx + cellSize, posy);
}
}
}
for(let i = 0; i < grid; i++){
const posx = grid * cellSize - cellSize * grid / 2;
const posy = i * cellSize - cellSize * grid / 2;
if(vWalls[grid][i]){
turtle.jump(posx, posy);
turtle.goto(posx, posy + cellSize);
}
}
}
function drawPad(cell){
const cellSize = (size * 2) / grid;
const posx = cell.i * cellSize - cellSize * grid / 2 + cellSize / 2;
const posy = cell.j * cellSize - cellSize * grid / 2 + cellSize / 2;
const radius = cellSize / 5;
for(let i = radius; i > 0; i -= 0.2){
turtle.jump(posx, posy - i);
turtle.seth(0);
turtle.circle(i);
}
}
function drawRoute(start, end){
const cellSize = (size * 2) / grid;
let posx = start.i * cellSize - cellSize * grid / 2 + cellSize / 2;
let posy = start.j * cellSize - cellSize * grid / 2 + cellSize / 2;
turtle.jump(posx, posy);
}
stack.push(cells[Math.floor(Math.random() * grid)][Math.floor(Math.random() * grid)]);
drawPad(stack[stack.length - 1]);
let lastTime = Date.now();
let farthestCell;
let biggestStackSize = 0;
const firstCell = stack[0];
// The walk function will be called until it returns false.
function walk(i) {
const length = stack.length;
if(!length){
drawWalls();
drawPad(farthestCell);
drawRoute(firstCell, farthestCell);
return false;
}
let cell = stack.pop();
lastCell = cell;
if(length > biggestStackSize){
biggestStackSize = length;
farthestCell = cell;
}
let newCell = cell.getNeighbor();
if(newCell != null){
stack.push(cell);
stack.push(newCell);
}
/*
while(lastTime >= Date.now());
lastTime = Date.now() + 50;
*/
return true;
}