Log in to post a comment.

// You can find the Turtle API reference here: https://turtletoy.net/syntax
Canvas.setpenopacity(1);

const iterations = 4;       //min = 0, max = 8, step = 1
const size = 80;            //min = 10, max = 100, step = 1
const square = 1            // min = 0, max  =1, step = 0.1

// Global code will be evaluated once.
const turtle = new Turtle();

function rotate(x,y, n = 1){
    let tmp = 0;
    
    for(let i = 0; i < n; i++){
        tmp = x;
        x = -y;
        y = tmp;
    }
    
    return [x, y];
}

function deadEnd(x, y, s, h){
    let posx = -s;
    let posy = -s/4;

    [posx, posy] = rotate(posx, posy, h);
    
    turtle.jump(x+posx, y+posy);
    turtle.seth(h * 90);
    turtle.forward(square * s/4);
    turtle.circle(s/4, 180);
    turtle.forward(square * s/4);
}

function line(x, y, s, h){
    let posx = -s;
    let posy = 0;

    let ox = 0;
    let oy = s/4;

    [posx, posy] = rotate(posx, posy, h);
    [ox, oy] = rotate(ox, oy, h);

    turtle.jump(x+posx+ox, y+posy+oy);
    [posx, posy] = rotate(posx, posy);
    [posx, posy] = rotate(posx, posy);
    turtle.goto(x+posx+ox, y+posy+oy);

    [ox, oy] = rotate(ox, oy);
    [ox, oy] = rotate(ox, oy);
    
    turtle.jump(x+posx+ox, y+posy+oy);
    [posx, posy] = rotate(posx, posy);
    [posx, posy] = rotate(posx, posy);
    turtle.goto(x+posx+ox, y+posy+oy);

    /*
    turtle.jump(x+posx, y+posy);
    turtle.seth(h * 90);
    turtle.forward(2*s);
    turtle.right(90);
    turtle.up();
    turtle.forward(s/2);
    turtle.down();
    turtle.right(90);
    turtle.forward(2*s);
    */
}

function crossing(x, y, s){
    let posx = -s;
    let posy = s/4;
    let tmp = 0;
    
    for(let i = 0; i < 4; i++){
        turtle.jump(x+posx, y+posy);
        turtle.seth(i * 90);
        turtle.forward(square * s/4);
        turtle.circle((1 - square) * s/4 + s/2, 90);
        turtle.forward(square * s/4);
        
        [posx, posy] = rotate(posx, posy);
    }
}

function curve(x, y, s, h, dir){
    let posx = -s;
    let posy = 0;
    let ox = 0;
    let oy = s/4;
    
    if(dir < 0) oy =- oy;
    
    [posx, posy] = rotate(posx, posy, h);
    [ox, oy] = rotate(ox, oy, h);

    turtle.jump(x+posx+ox, y+posy+oy);
    turtle.seth(h * 90);
    turtle.forward(square * s/4);
    turtle.circle(dir * ((1-square) * s/4 + 1/2 * s), 90);
    turtle.forward(square * s/4);

    [ox, oy] = rotate(ox, oy);
    [ox, oy] = rotate(ox, oy);

    turtle.jump(x+posx+ox, y+posy+oy);
    turtle.seth(h * 90);
    turtle.forward(square * s/4);
    turtle.circle(dir * ((1-square) * s/4 + s), 90);
    turtle.forward(square * s/4);
    
}

function divide(x, y, s, l){
    
    if(l == 0){
        const rand = Math.random();
        
        if(rand < 0.2){
            // first tile type is all off.
            
            deadEnd(x, y, s, 0);
            deadEnd(x, y, s, 1);
            deadEnd(x, y, s, 2);
            deadEnd(x, y, s, 3);

        } else if(rand < 0.4){
            // second tile type is crossing ahead
            if(Math.random() < 0.5){
                line(x, y, s, 0);

                deadEnd(x, y, s, 1);
                deadEnd(x, y, s, 3);
                
            } else {
                line(x, y, s, 1);

                deadEnd(x, y, s, 0);
                deadEnd(x, y, s, 2);
            }
            
        } else if(rand < 0.6){
            // third tile type is everything opens
            
            crossing(x, y, s);
        } else if(rand){
            
            let direction = 1;
            if(Math.random() < 0.5) direction *= -1;
            
            let rotation = Math.floor(Math.random() * 4);
            curve(x, y, s, rotation, direction);
            
            if(Math.random() < 0.5){
                // We draw a second curve, rotated 90°
                curve(x, y, s, rotation + 2, direction);
            } else {
                // We draw two dead ends on the remaining borders.
                deadEnd(x, y, s, rotation + 2);
                if(direction == 1) deadEnd(x, y, s, rotation + 1);
                else deadEnd(x, y, s, rotation + 3);
            }
        }
        
    } else {
        l--;
        s /= 2;
        
        divide(x+s, y+s, s, l);
        divide(x+s, y-s, s, l);
        divide(x-s, y+s, s, l);
        divide(x-s, y-s, s, l);
    }
}

divide(0, 0, size, iterations)

// The walk function will be called until it returns false.
function walk(i) {
    
    return false;
}