Code viewer for World: Tutorial 1.2 (clone by Sin...
import React, { useState, useEffect, useCallback } from 'react';
import { Camera } from 'lucide-react';

// A* Pathfinding Algorithm
class AStar {
  constructor(grid) {
    this.grid = grid;
  }

  // Manhattan distance heuristic
  heuristic(a, b) {
    return Math.abs(a.x - b.x) + Math.abs(a.y - b.y);
  }

  // Check if a cell is walkable
  isWalkable(x, y) {
    return x >= 0 && x < this.grid.length && 
           y >= 0 && y < this.grid[0].length && 
           this.grid[x][y] !== 1;
  }

  findPath(start, end, occupiedCells) {
    const openSet = [];
    const closedSet = new Set();
    const cameFrom = new Map();
    const gScore = new Map();
    const fScore = new Map();

    const startKey = "" + start.x + "," + start.y;
    const endKey = "" + end.x + "," + end.y;

    gScore.set(startKey, 0);
    fScore.set(startKey, this.heuristic(start, end));
    openSet.push(start);

    while (openSet.length > 0) {
      // Get node with lowest fScore
      const current = openSet.reduce((lowest, node) => 
        (fScore.get("" + node.x + "," + node.y) < fScore.get("" + lowest.x + "," + lowest.y) ? node : lowest)
      );

      // Check if reached goal
      if (current.x === end.x && current.y === end.y) {
        const path = [];
        let curr = current;
        while (curr) {
          path.unshift(curr);
          curr = cameFrom.get("" + curr.x + "," + curr.y);
        }
        return path;
      }

      // Remove current from openSet and add to closedSet
      openSet.splice(openSet.indexOf(current), 1);
      closedSet.add("" + current.x + "," + current.y);

      // Check neighbors
      const neighbors = [
        {x: current.x+1, y: current.y},
        {x: current.x-1, y: current.y},
        {x: current.x, y: current.y+1},
        {x: current.x, y: current.y-1}
      ];

      for (const neighbor of neighbors) {
        const neighborKey = "" + neighbor.x + "," + neighbor.y;

        // Skip if not walkable or in closed set or occupied
        if (!this.isWalkable(neighbor.x, neighbor.y) || 
            closedSet.has(neighborKey) || 
            occupiedCells.has(neighborKey)) {
          continue;
        }

        const tentativeGScore = gScore.get("" + current.x + "," + current.y) + 1;

        if (!openSet.some(n => n.x === neighbor.x && n.y === neighbor.y)) {
          openSet.push(neighbor);
        } else if (tentativeGScore >= gScore.get(neighborKey)) {
          continue;
        }

        // This path is the best until now
        cameFrom.set(neighborKey, current);
        gScore.set(neighborKey, tentativeGScore);
        fScore.set(neighborKey, gScore.get(neighborKey) + this.heuristic(neighbor, end));
      }
    }

    return null; // No path found
  }
}

// Rest of the code remains the same as in the previous artifact
const TrafficSimulation = () => {
  // ... [full previous implementation]
};

export default TrafficSimulation;