Minesweeper City

Generates a minesweeper grid where the big circles are the bombs. Then a line steps through it and turns whenever it hits a number and splits whenever it hits a bomb.

Log in to post a comment.

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

// Global code will be evaluated once.
const turtle = new Turtle();
let seed = 1000; // min=1 max=1000000 step=1
const bits = 20; 
const samples = 150000; 
const mod = 1<<bits;
let grid_size = 39; // min = 1 max = 50 step = 2
let num_bombs = 58; // min = 1 max = 100 step = 1
let steps = 230; // min = 0 max = 300 step = 1

if(num_bombs > grid_size*grid_size) {
    num_bombs = grid_size*grid_size;
}
grid = [];

for(let i = 0; i < grid_size; i++) {
    grid_row = []
    for(let j = 0; j < grid_size; j++) {
        grid_row.push(0);
    }
    grid.push(grid_row);
}

for(let i = 0; i < num_bombs; i++) {
    bomb_has_been_placed = false;
    while(!bomb_has_been_placed) {
        x_pos = Math.floor(random() * grid_size);
        y_pos = Math.floor(random() * grid_size);
        if(grid[x_pos][y_pos] == 0) {
            grid[x_pos][y_pos] = "bomb";
            bomb_has_been_placed = true;
        }
    }
}

for(let i = 0; i < grid_size; i++) {
    for(let j = 0; j < grid_size; j++) {
        if(grid[i][j]!="bomb") {
            if(i>0 && j>0 && grid[i-1][j-1] == "bomb") grid[i][j]++;
            if(i>0 && grid[i-1][j] == "bomb") grid[i][j]++;
            if(i>0 && j<grid_size-1 && grid[i-1][j+1] == "bomb") grid[i][j]++;
            if(j>0 && grid[i][j-1] == "bomb") grid[i][j]++;
            if(j<grid_size-1 && grid[i][j+1] == "bomb") grid[i][j]++;
            if(i<grid_size-1 && j>0 && grid[i+1][j-1] == "bomb") grid[i][j]++;
            if(i<grid_size-1 && grid[i+1][j] == "bomb") grid[i][j]++;
            if(i<grid_size-1 && j<grid_size-1 && grid[i+1][j+1] == "bomb") grid[i][j]++;
        }
    }
}

let circle_rad = 100/grid_size
for(let i = 0; i < grid_size; i++) {
    for(let j = 0; j < grid_size; j++) {
        if(grid[i][j] == "bomb") {
            circle(circle_rad, 30, -100 + i*200/grid_size + circle_rad, -100 + j*200/grid_size + circle_rad)
        }
        else if(grid[i][j] == 1) {
            circle(circle_rad/2, 30, -100 + i*200/grid_size + circle_rad, -100 + j*200/grid_size + circle_rad)
        }
        else {
            circle(circle_rad, grid[i][j]+1, -100 + i*200/grid_size + circle_rad, -100 + j*200/grid_size + circle_rad)
        }
    }
}

let scatter_turtles = [];
let scatter_turtle = new Turtle();
scatter_turtle.left(0);
scatter_turtles.push(scatter_turtle);
for(let i = 0; i < steps; i++) {
    console.log(scatter_turtles.length);
    for(j in scatter_turtles) {
        if(Math.round(scatter_turtles[j].h()) % 90 == 0) {
            scatter_turtles[j].forward(circle_rad * 2);
        }
        else {
            scatter_turtles[j].forward(circle_rad * 2 * Math.pow(2,0.5));
        }
        let off_map = false;
        if(scatter_turtles[j].x() > 100 || scatter_turtles[j].x() < -100 || scatter_turtles[j].y() > 100 || scatter_turtles[j].y() < -100) {
            off_map = true;
        }
        if(!off_map) {
            current_pos = grid[Math.floor((scatter_turtles[j].x()+100)*grid_size/200)][Math.floor((scatter_turtles[j].y()+100)*grid_size/200)];
            if(current_pos == "bomb") {
                let copy_turtle = new Turtle();
                copy_turtle.jump(scatter_turtles[j].x(), scatter_turtles[j].y());
                copy_turtle.setheading(scatter_turtles[j].h() - 90);
                let duplicate_turtle = false;
                for(k in scatter_turtles) {
                    if(Math.round(copy_turtle.x()) == Math.round(scatter_turtles[k].x())
                    && Math.round(copy_turtle.y()) == Math.round(scatter_turtles[k].y()) 
                    && Math.round(copy_turtle.h()) == Math.round(scatter_turtles[k].h())) {
                       duplicate_turtle = true; 
                    }
                }
                if(!duplicate_turtle) {
                    scatter_turtles.push(copy_turtle);
                }
                scatter_turtles[j].right(90);
            }
            else {
                scatter_turtles[j].right(current_pos * 45);
            }
        }
    }
}

function circle(radius, steps, x_center, y_center) {
    theta = Math.PI * 2 / steps;
    turtle.penup();
    turtle.goto(x_center + radius * Math.cos(theta * 0), y_center + radius * Math.sin(theta * 0))
    turtle.pendown();
    for(i = 0; i <= steps; i++) {
        x = x_center + radius * Math.cos(theta * i);
        y = y_center + radius * Math.sin(theta * i);
        turtle.goto(x,y);
    }
}

////////////////////////////////////////////////////////////////
// Pseudorandom number generator. Created by Reinder Nijhoff 2024
// https://turtletoy.net/turtle/a2274fd1fe
////////////////////////////////////////////////////////////////
function random() { // returns a number [0, 1[
    let r = 1103515245 * (((seed+=12345) >> 1) ^ seed);
    r = 1103515245 * (r ^ (r >> 3));
    r = r ^ (r >> 16);
    return (r % mod) / mod;
}