Code viewer for World: mywork guess (clone by Zoro)
// === Constants ===

// Enable diagonal moves
const diagonal = true;

// Canvas and grid settings
const cw = 900;
const ch = 600;

// Number of columns and rows
var cols = 18;
var rows = 12;

// "Street" parameters
const streetChance = 0.2; // Percentage chance that a row or column is open as a "street"

const backcolor = 'white';
const wallcolor = 'black';
const pathcolor = 'darkred';
const opencolor = 'lightgreen';
const closedcolor = 'lightpink';
const carColors = ['blue', 'green', 'orange', 'purple'];

// 2D grid array
var grid = new Array(cols);

// A* sets for pathfinding
var openSet = [];
var closedSet = [];

// Car objects with random start and border destinations
var cars = [];
const numCars = 4;

// Cell size
var w, h;

// Path and block management
var paths = [];

// === Setup ===

function setup() {
  createCanvas(cw, ch);
  w = width / cols;
  h = height / rows;

  // Initialize the grid and create a "street-like" structure
  for (let i = 0; i < cols; i++) {
    grid[i] = new Array(rows);
    for (let j = 0; j < rows; j++) {
      grid[i][j] = new Spot(i, j);
      if (Math.random() > streetChance && i % 2 !== 0 && j % 2 !== 0) {
        grid[i][j].wall = true; // Make this cell a wall unless it’s a “street”
      }
    }
  }

  // Define neighbors for each cell
  for (let i = 0; i < cols; i++) {
    for (let j = 0; j < rows; j++) {
      grid[i][j].addNeighbors(grid);
    }
  }

  // Initialize cars with random positions and border destinations
  for (let i = 0; i < numCars; i++) {
    let start = getRandomEmptyCell();
    let destination = getRandomBorderCell();
    cars.push({ id: i, pos: start, dest: destination, path: [] });
  }
  
  console.log('Start Simulation');
}

// === Main Draw Loop ===

function draw() {
  background(backcolor);

  // Move and update paths for each car
  for (let car of cars) {
    // Recalculate path based on dynamic obstacles
    if (car.path.length === 0 || grid[car.pos.i][car.pos.j] === car.dest) {
      car.path = aStar(car.pos, car.dest);
    }

    // Move the car along the path
    if (car.path.length > 0) {
      let nextStep = car.path.shift(); // Take the next step
      if (!isBlocked(nextStep)) { // Move if the next cell is not blocked
        car.pos = nextStep;
      }
    }
  }

  // Draw grid and cars
  for (let i = 0; i < cols; i++) {
    for (let j = 0; j < rows; j++) {
      grid[i][j].show();
    }
  }

  for (let car of cars) {
    fill(carColors[car.id]);
    noStroke();
    ellipse(car.pos.i * w + w / 2, car.pos.j * h + h / 2, w * 0.6, h * 0.6);
  }
}

// === Spot (Cell) ===

function Spot(i, j) {
  this.i = i;
  this.j = j;
  this.wall = false;
  this.neighbors = [];
  this.previous = undefined;

  this.show = function() {
    fill(this.wall ? wallcolor : backcolor);
    noStroke();
    rect(this.i * w, this.j * h, w, h);
  };

  this.addNeighbors = function(grid) {
    if (this.i < cols - 1) this.neighbors.push(grid[this.i + 1][this.j]);
    if (this.i > 0) this.neighbors.push(grid[this.i - 1][this.j]);
    if (this.j < rows - 1) this.neighbors.push(grid[this.i][this.j + 1]);
    if (this.j > 0) this.neighbors.push(grid[this.i][this.j - 1]);
    if (diagonal) {
      if (this.i > 0 && this.j > 0) this.neighbors.push(grid[this.i - 1][this.j - 1]);
      if (this.i < cols - 1 && this.j > 0) this.neighbors.push(grid[this.i + 1][this.j - 1]);
      if (this.i > 0 && this.j < rows - 1) this.neighbors.push(grid[this.i - 1][this.j + 1]);
      if (this.i < cols - 1 && this.j < rows - 1) this.neighbors.push(grid[this.i + 1][this.j + 1]);
    }
  };
}

// === A* Algorithm ===

function aStar(start, end) {
  // Initialize A* variables here (reset openSet and closedSet, set g, h, f values)
  // A* pathfinding logic to calculate a path from start to end
  // Return the computed path as an array of cells
}

// === Helper Functions ===

function getRandomEmptyCell() {
  let cell;
  do {
    let i = Math.floor(Math.random() * cols);
    let j = Math.floor(Math.random() * rows);
    cell = grid[i][j];
  } while (cell.wall);
  return cell;
}

function getRandomBorderCell() {
  let i, j;
  if (Math.random() > 0.5) {
    i = Math.random() > 0.5 ? 0 : cols - 1;
    j = Math.floor(Math.random() * rows);
  } else {
    j = Math.random() > 0.5 ? 0 : rows - 1;
    i = Math.floor(Math.random() * cols);
  }
  return grid[i][j];
}

function isBlocked(cell) {
  return cars.some(car => car.pos.i === cell.i && car.pos.j === cell.j);
}