Never ending turtle

A turtle that dies without dying.
Freely inspired by Shadow of the Ego.

Log in to post a comment.

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

const generations = 20000;      //min = 100, max = 100000, step = 10
const forward = 0.05;           //min = 0.01, max = 2, step = 0.01
const angle = 10;               //min = 0, max = 45, step = 1

const size = 180;

let turtles = [];

let nests = [];

let holes = [];

function addTurtle(nest){
    let turtle = new Turtle();
    
    turtle.seth(Math.random() * 360);
    turtle.nest = nest;
    turtle.jump(nest.pos());
    turtles.push(turtle);
    
    return turtle;
}

function addNest(x = 0, y = 0, qty = 5){
    for (let i = 0; i < qty;  i++){
        let nt = addTurtle(x, y, Math.random() * 360)
        turtles.push(nt);
    }
}

class Hole{
    constructor(x, y, w, h){
        this.xmin = x - w / 2;
        this.xmax = x + w / 2;
        this.ymin = y - h / 2;
        this.ymax = y + h / 2;
    }
    
    isInHole(t){
        let x = t.x();
        let y = t.y();
        return x > this.xmin && x < this.xmax && y > this.ymin && y < this.ymax; 
    }
}

class Nest{
    constructor(x, y){
        this.x = x;
        this.y = y;
        addTurtle(this);
    }
    
    x(){
        return this.x;
    }
    
    y(){
        return this.y;
    }
    
    pos(){
        return [this.x, this.y];
    }
}

//nests.push(new Nest(0, 0));
//nests.push(new Nest(-10, -45));
//nests.push(new Nest(-10, 45));
/*
holes.push(new Hole(-30, -60, 20, 20));
holes.push(new Hole(-30, -30, 20, 20));
holes.push(new Hole(-30, 0, 20, 20));
holes.push(new Hole(-30, 30, 20, 20));
holes.push(new Hole(-30, 60, 20, 20));
*/
/*
holes.push(new Hole(-30, -30, 30, 30));
holes.push(new Hole(-30, 30, 30, 30));
holes.push(new Hole(30, -30, 30, 30));
holes.push(new Hole(30, 30, 30, 30));
*/
/*
holes.push(new Hole(0, -30, 20, 20));
holes.push(new Hole(0, 0, 20, 20));
holes.push(new Hole(0, 30, 20, 20));

//nests.push(new Nest(60, 60));
//nests.push(new Nest(60, -60));
nests.push(new Nest(-60, 60));
nests.push(new Nest(-60, -60));

nests.push(new Nest(-60, 0));
*/

nests.push(new Nest(0, 0));

holes.push(new Hole(-40, -40, 25, 25));
holes.push(new Hole(-40, 40, 25, 25));
holes.push(new Hole(40, -40, 25, 25));
holes.push(new Hole(40, 40, 25, 25));

holes.push(new Hole(-40, 0, 25, 25));
holes.push(new Hole(40, 0, 25, 25));
holes.push(new Hole(0, -40, 25, 25));
holes.push(new Hole(0, 40, 25, 25));

/*
nests.push(new Nest(50, 0));
nests.push(new Nest(-50, 0));
nests.push(new Nest(0, 50));
nests.push(new Nest(0, -50));

holes.push(new Hole(-30, -30, 20, 20));
holes.push(new Hole(-30, 30, 20, 20));
holes.push(new Hole(30, -30, 20, 20));
holes.push(new Hole(30, 30, 20, 20));

holes.push(new Hole(-30, 0, 20, 20));
holes.push(new Hole(30, 0, 20, 20));
holes.push(new Hole(0, -30, 20, 20));
holes.push(new Hole(0, 30, 20, 20));
*/
let gen = 0;
// The walk function will be called until it returns false.
function walk(i) {
    
    // revelation ! We can use a console for debugging !
//    console.log(`iteration ${i}, ${turtles.length} turtles.`);
    
    for(let turtle of turtles){
        turtle.right(Math.random() * 2 * angle - angle);
        turtle.forward(forward);

        turtle.age++;

        for(let hole of holes){
            if(hole.isInHole(turtle)){
                turtle.jump(turtle.nest.pos());
                turtle.seth(Math.random() * 360);
                gen++;
                break;
            }
        }
        //remove out off canvas turtles.
        if(turtle.x() < -size/2 || turtle.x() > size/2 || turtle.y() < -size/2 || turtle.y() > size/2){
            turtle.jump(turtle.nest.pos());
            turtle.seth(Math.random() * 360);
            gen++;
        }
    }
    

    return gen < generations;
}