Circuit board 1

Generative circuit-ish boards

Log in to post a comment.

// Create a Manhattan path between two points
function createManhattanPath(sourcePin, targetPin) {
    // Get source and target coordinates
    const sourceX = sourcePin.x;
    const sourceY = sourcePin.y;
    const targetX = targetPin.x;
    const targetY = targetPin.y;
    
    // Convert to canvas coordinates for start and end
    const { x: sourceCanvasX, y: sourceCanvasY } = gridToCanvas(sourceX, sourceY);
    const { x: targetCanvasX, y: targetCanvasY } = gridToCanvas(targetX, targetY);
    
    // Create path with proper corners (Manhattan style)
    const path = [];
    
    // Add source point
    path.push({ x: sourceCanvasX, y: sourceCanvasY, canvas: true });
    
    // Determine which direction to go first (horizontal or vertical)
    // This adds some variety to the paths
    let horizontalFirst = Math.random() < 0.5;
    
    // Add intermediate points
    if (horizontalFirst) {
        // First go horizontally
        const midX = (sourceCanvasX + targetCanvasX) / 2;
        path.push({ x: midX, y: sourceCanvasY, canvas: true });
        
        // Then go vertically
        path.push({ x: midX, y: targetCanvasY, canvas: true });
    } else {
        // First go vertically
        const midY = (sourceCanvasY + targetCanvasY) / 2;
        path.push({ x: sourceCanvasX, y: midY, canvas: true });
        
        // Then go horizontally
        path.push({ x: targetCanvasX, y: midY, canvas: true });
    }
    
    // Add target point
    path.push({ x: targetCanvasX, y: targetCanvasY, canvas: true });
    
    return path;
}// Improved Procedural Circuit Board for TurtleToy
// Date: 2025-04-27
// Target: TurtleToy (https://turtletoy.net/)

// --- Settings ---
const GRID_SIZE = 5; // Spacing between grid points (lower = denser)
const TRACE_WIDTH = 0.5; // Simulate thicker traces by drawing parallel lines
const NUM_TRACE_LINES = 3; // How many parallel lines for one trace (1 for thin)

const PAD_RADIUS = GRID_SIZE * 0.3;
const VIA_RADIUS = GRID_SIZE * 0.15;

// Component density settings
const COMPONENT_DENSITY = 0.7; // Higher = more components
const MIN_COMPONENTS = 15; // Minimum number of components to place

// IC settings
const IC_MIN_WIDTH = 3; // In grid units
const IC_MAX_WIDTH = 6; // In grid units
const IC_MIN_HEIGHT = 3; // In grid units
const IC_MAX_HEIGHT = 6; // In grid units
const IC_PIN_SPACING = 1; // Grid units between pins
const IC_PIN_PAD_RADIUS = GRID_SIZE * 0.1;

const RESISTOR_LENGTH = 2; // Grid units long
const RESISTOR_WIDTH = 1; // Grid units wide
const RESISTOR_PAD_RADIUS = GRID_SIZE * 0.15;

const CAPACITOR_RADIUS = GRID_SIZE * 0.6;
const CAPACITOR_PAD_RADIUS = GRID_SIZE * 0.15;

const MAX_TRACE_SEGMENTS = 20; // Max length of a trace
const STRAIGHT_TRACE_CHANCE = 0.8; // Likelihood trace continues straight

// --- Global State ---
const turtle = new Turtle();
const occupied = new Set(); // Keep track of occupied grid points "x,y"
const pads = []; // Store locations of pads [{x, y, r, componentId, pinType}]
const components = []; // Store component info [{id, type, gx, gy, width, height, pins: [{x, y, type}]}]

// --- Canvas Setup ---
const MIN_X = -90;
const MAX_X = 90;
const MIN_Y = -90;
const MAX_Y = 90;

// --- Circuit Types ---
const CIRCUIT_TYPES = {
    POWER_SUPPLY: "power_supply",
    LOGIC_GATES: "logic_gates",
    MICROCONTROLLER: "microcontroller",
    AUDIO_AMPLIFIER: "audio_amplifier",
    LED_DRIVER: "led_driver"
};

// --- Component Types ---
const COMPONENT_TYPES = {
    IC: "ic",
    RESISTOR: "resistor",
    CAPACITOR: "capacitor",
    DIODE: "diode",
    TRANSISTOR: "transistor",
    LED: "led",
    POWER: "power",
    GROUND: "ground"
};

// --- Pin Types ---
const PIN_TYPES = {
    INPUT: "input",
    OUTPUT: "output",
    POWER: "power",
    GROUND: "ground",
    BIDIRECTIONAL: "bidirectional"
};

// --- Main Function ---
function walk(i) {
    if (i === 0) {
        // Initialize
        turtle.penup();
        turtle.home(); // Go to 0,0
        turtle.pendown();
        
        // 1. Create circuit graph (defines the logical structure)
        const circuitType = chooseRandomCircuitType();
        createCircuitGraph(circuitType);
        
        // Add additional components for a more complete circuit
        addSupplementaryComponents(circuitType);
        
        // 2. Place components based on the circuit design
        placeComponents();
        
        // 3. Draw power and ground distribution
        drawPowerAndGroundRails();
        
        // 4. Route traces logically between connected components
        routeTraces();
        
        // No outline, just circuit components and traces
    }
    // This generator creates a static image in one go
    return false; // Signal TurtleToy we are done after the first step
}

// --- Circuit Creation Functions ---

// Choose a random circuit type
function chooseRandomCircuitType() {
    const types = Object.values(CIRCUIT_TYPES);
    return types[Math.floor(Math.random() * types.length)];
}

// Create the logical circuit structure based on the chosen type
function createCircuitGraph(circuitType) {
    // Different circuit templates based on type
    switch(circuitType) {
        case CIRCUIT_TYPES.POWER_SUPPLY:
            createPowerSupplyCircuit();
            break;
        case CIRCUIT_TYPES.LOGIC_GATES:
            createLogicGatesCircuit();
            break;
        case CIRCUIT_TYPES.MICROCONTROLLER:
            createMicrocontrollerCircuit();
            break;
        case CIRCUIT_TYPES.AUDIO_AMPLIFIER:
            createAudioAmplifierCircuit();
            break;
        case CIRCUIT_TYPES.LED_DRIVER:
            createLEDDriverCircuit();
            break;
        default:
            createPowerSupplyCircuit(); // Default to simple power supply
    }
}

// Create a simple power supply circuit
function createPowerSupplyCircuit() {
    // Create power input
    const powerIn = createComponent(COMPONENT_TYPES.POWER, 1, 1);
    
    // Create main IC voltage regulator
    const regulator = createComponent(COMPONENT_TYPES.IC, 3, 3);
    regulator.name = "VREG";
    
    // Create filter capacitors
    const cap1 = createComponent(COMPONENT_TYPES.CAPACITOR, 1, 1);
    const cap2 = createComponent(COMPONENT_TYPES.CAPACITOR, 1, 1);
    const cap3 = createComponent(COMPONENT_TYPES.CAPACITOR, 1, 1);
    
    // Create output resistors for voltage divider
    const resistor1 = createComponent(COMPONENT_TYPES.RESISTOR, RESISTOR_LENGTH, RESISTOR_WIDTH);
    const resistor2 = createComponent(COMPONENT_TYPES.RESISTOR, RESISTOR_LENGTH, RESISTOR_WIDTH);
    
    // Create ground connection
    const ground = createComponent(COMPONENT_TYPES.GROUND, 1, 1);
    
    // Create power output
    const powerOut = createComponent(COMPONENT_TYPES.POWER, 1, 1);
    powerOut.name = "OUT";
    
    // Create diode for reverse polarity protection
    const diode = createComponent(COMPONENT_TYPES.DIODE, 2, 1);
    
    // Create logical connections between components
    createConnection(powerIn.id, diode.id);
    createConnection(diode.id, regulator.id);
    createConnection(diode.id, cap1.id);
    createConnection(regulator.id, cap2.id);
    createConnection(regulator.id, resistor1.id);
    createConnection(resistor1.id, resistor2.id);
    createConnection(resistor1.id, powerOut.id);
    createConnection(resistor2.id, ground.id);
    createConnection(cap1.id, ground.id);
    createConnection(cap2.id, ground.id);
    createConnection(cap3.id, powerOut.id);
    createConnection(cap3.id, ground.id);
    createConnection(powerOut.id, ground.id);
}

// Create a logic gates circuit
function createLogicGatesCircuit() {
    // Create input pins
    const input1 = createComponent(COMPONENT_TYPES.POWER, 1, 1);
    input1.name = "IN1";
    const input2 = createComponent(COMPONENT_TYPES.POWER, 1, 1);
    input2.name = "IN2";
    
    // Create logic ICs
    const gate1 = createComponent(COMPONENT_TYPES.IC, 3, 3);
    gate1.name = "AND";
    const gate2 = createComponent(COMPONENT_TYPES.IC, 3, 3);
    gate2.name = "OR";
    
    // Create output connections
    const output = createComponent(COMPONENT_TYPES.POWER, 1, 1);
    output.name = "OUT";
    
    // Create resistors for pull-up/pull-down
    const resistor1 = createComponent(COMPONENT_TYPES.RESISTOR, RESISTOR_LENGTH, RESISTOR_WIDTH);
    const resistor2 = createComponent(COMPONENT_TYPES.RESISTOR, RESISTOR_LENGTH, RESISTOR_WIDTH);
    
    // Create ground connection
    const ground = createComponent(COMPONENT_TYPES.GROUND, 1, 1);
    
    // Create logical connections
    createConnection(input1.id, gate1.id);
    createConnection(input2.id, gate1.id);
    createConnection(input1.id, gate2.id);
    createConnection(input2.id, gate2.id);
    createConnection(gate1.id, output.id);
    createConnection(gate2.id, resistor1.id);
    createConnection(resistor1.id, resistor2.id);
    createConnection(resistor2.id, ground.id);
}

// Create a microcontroller circuit
function createMicrocontrollerCircuit() {
    // Create main microcontroller IC
    const mcu = createComponent(COMPONENT_TYPES.IC, 6, 6);
    mcu.name = "MCU";
    
    // Create power input
    const power = createComponent(COMPONENT_TYPES.POWER, 1, 1);
    
    // Create crystal oscillator
    const osc = createComponent(COMPONENT_TYPES.IC, 2, 2);
    osc.name = "XTAL";
    
    // Create reset circuit components
    const resetCap = createComponent(COMPONENT_TYPES.CAPACITOR, 1, 1);
    const resetRes = createComponent(COMPONENT_TYPES.RESISTOR, RESISTOR_LENGTH, RESISTOR_WIDTH);
    
    // Create I/O components
    const led1 = createComponent(COMPONENT_TYPES.LED, 1, 1);
    const led2 = createComponent(COMPONENT_TYPES.LED, 1, 1);
    const button = createComponent(COMPONENT_TYPES.POWER, 1, 1);
    button.name = "BTN";
    
    // Create ground
    const ground = createComponent(COMPONENT_TYPES.GROUND, 1, 1);
    
    // Create logical connections
    createConnection(power.id, mcu.id);
    createConnection(power.id, resetRes.id);
    createConnection(resetRes.id, mcu.id);
    createConnection(resetRes.id, resetCap.id);
    createConnection(resetCap.id, ground.id);
    createConnection(osc.id, mcu.id);
    createConnection(mcu.id, led1.id);
    createConnection(mcu.id, led2.id);
    createConnection(button.id, mcu.id);
    createConnection(led1.id, ground.id);
    createConnection(led2.id, ground.id);
    createConnection(mcu.id, ground.id);
    createConnection(osc.id, ground.id);
}

// Create an audio amplifier circuit
function createAudioAmplifierCircuit() {
    // Create input jack
    const input = createComponent(COMPONENT_TYPES.POWER, 1, 1);
    input.name = "AUDIO IN";
    
    // Create coupling capacitor
    const couplingCap = createComponent(COMPONENT_TYPES.CAPACITOR, 1, 1);
    
    // Create amplifier IC
    const ampIC = createComponent(COMPONENT_TYPES.IC, 4, 4);
    ampIC.name = "AMP";
    
    // Create feedback components
    const feedbackRes = createComponent(COMPONENT_TYPES.RESISTOR, RESISTOR_LENGTH, RESISTOR_WIDTH);
    const feedbackCap = createComponent(COMPONENT_TYPES.CAPACITOR, 1, 1);
    
    // Create output coupling capacitor
    const outputCap = createComponent(COMPONENT_TYPES.CAPACITOR, 1, 1);
    
    // Create output jack
    const output = createComponent(COMPONENT_TYPES.POWER, 1, 1);
    output.name = "AUDIO OUT";
    
    // Create power and ground
    const power = createComponent(COMPONENT_TYPES.POWER, 1, 1);
    const ground = createComponent(COMPONENT_TYPES.GROUND, 1, 1);
    
    // Create logical connections
    createConnection(input.id, couplingCap.id);
    createConnection(couplingCap.id, ampIC.id);
    createConnection(ampIC.id, feedbackRes.id);
    createConnection(feedbackRes.id, feedbackCap.id);
    createConnection(feedbackCap.id, ampIC.id);
    createConnection(ampIC.id, outputCap.id);
    createConnection(outputCap.id, output.id);
    createConnection(power.id, ampIC.id);
    createConnection(ampIC.id, ground.id);
    createConnection(input.id, ground.id);
    createConnection(output.id, ground.id);
}

// Create an LED driver circuit
function createLEDDriverCircuit() {
    // Create power input
    const power = createComponent(COMPONENT_TYPES.POWER, 1, 1);
    
    // Create driver IC
    const driver = createComponent(COMPONENT_TYPES.IC, 4, 4);
    driver.name = "LED DRIVER";
    
    // Create LEDs
    const leds = [];
    for (let i = 0; i < 4; i++) {
        leds.push(createComponent(COMPONENT_TYPES.LED, 1, 1));
    }
    
    // Create current limiting resistors
    const resistors = [];
    for (let i = 0; i < 4; i++) {
        resistors.push(createComponent(COMPONENT_TYPES.RESISTOR, RESISTOR_LENGTH, RESISTOR_WIDTH));
    }
    
    // Create ground
    const ground = createComponent(COMPONENT_TYPES.GROUND, 1, 1);
    
    // Create logical connections
    createConnection(power.id, driver.id);
    
    for (let i = 0; i < 4; i++) {
        createConnection(driver.id, resistors[i].id);
        createConnection(resistors[i].id, leds[i].id);
        createConnection(leds[i].id, ground.id);
    }
    
    createConnection(driver.id, ground.id);
}

// --- Component Management Functions ---

// Create a new component and add it to the components array
function createComponent(type, width, height) {
    const id = components.length;
    const component = {
        id,
        type,
        width,
        height,
        pins: [],
        connections: []
    };
    
    components.push(component);
    return component;
}

// Create a logical connection between components
function createConnection(fromId, toId) {
    // Add to both components' connection lists
    components[fromId].connections.push(toId);
    components[toId].connections.push(fromId);
}

// Add supplementary components for more detailed circuits
function addSupplementaryComponents(circuitType) {
    // Add more components based on circuit type
    switch(circuitType) {
        case CIRCUIT_TYPES.POWER_SUPPLY:
            // Add a fuse
            const fuse = createComponent(COMPONENT_TYPES.RESISTOR, 2, 1);
            fuse.name = "FUSE";
            createConnection(0, fuse.id); // Connect to power input
            
            // Add an LED indicator
            const led = createComponent(COMPONENT_TYPES.LED, 1, 1);
            const ledResistor = createComponent(COMPONENT_TYPES.RESISTOR, RESISTOR_LENGTH, RESISTOR_WIDTH);
            createConnection(components.find(c => c.name === "OUT").id, ledResistor.id);
            createConnection(ledResistor.id, led.id);
            createConnection(led.id, components.find(c => c.type === COMPONENT_TYPES.GROUND).id);
            break;
            
        case CIRCUIT_TYPES.LOGIC_GATES:
            // Add a pull-up resistor
            const pullUp = createComponent(COMPONENT_TYPES.RESISTOR, RESISTOR_LENGTH, RESISTOR_WIDTH);
            createConnection(components.find(c => c.name === "IN1").id, pullUp.id);
            createConnection(pullUp.id, components.find(c => c.type === COMPONENT_TYPES.POWER).id);
            
            // Add a capacitor for noise filtering
            const noiseCap = createComponent(COMPONENT_TYPES.CAPACITOR, 1, 1);
            createConnection(components.find(c => c.name === "IN2").id, noiseCap.id);
            createConnection(noiseCap.id, components.find(c => c.type === COMPONENT_TYPES.GROUND).id);
            break;
            
        case CIRCUIT_TYPES.MICROCONTROLLER:
            // Add a reset button
            const resetBtn = createComponent(COMPONENT_TYPES.POWER, 1, 1);
            resetBtn.name = "RST";
            const mcu = components.find(c => c.name === "MCU");
            createConnection(resetBtn.id, mcu.id);
            
            // Add more LEDs
            const led3 = createComponent(COMPONENT_TYPES.LED, 1, 1);
            const ledRes3 = createComponent(COMPONENT_TYPES.RESISTOR, RESISTOR_LENGTH, RESISTOR_WIDTH);
            createConnection(mcu.id, ledRes3.id);
            createConnection(ledRes3.id, led3.id);
            createConnection(led3.id, components.find(c => c.type === COMPONENT_TYPES.GROUND).id);
            break;
            
        case CIRCUIT_TYPES.AUDIO_AMPLIFIER:
            // Add tone control
            const toneRes = createComponent(COMPONENT_TYPES.RESISTOR, RESISTOR_LENGTH, RESISTOR_WIDTH);
            const toneCap = createComponent(COMPONENT_TYPES.CAPACITOR, 1, 1);
            const amp = components.find(c => c.name === "AMP");
            createConnection(amp.id, toneRes.id);
            createConnection(toneRes.id, toneCap.id);
            createConnection(toneCap.id, components.find(c => c.type === COMPONENT_TYPES.GROUND).id);
            
            // Add volume control resistors
            const volRes1 = createComponent(COMPONENT_TYPES.RESISTOR, RESISTOR_LENGTH, RESISTOR_WIDTH);
            const volRes2 = createComponent(COMPONENT_TYPES.RESISTOR, RESISTOR_LENGTH, RESISTOR_WIDTH);
            createConnection(components.find(c => c.name === "AUDIO IN").id, volRes1.id);
            createConnection(volRes1.id, volRes2.id);
            createConnection(volRes2.id, components.find(c => c.type === COMPONENT_TYPES.GROUND).id);
            createConnection(volRes1.id, amp.id);
            break;
            
        case CIRCUIT_TYPES.LED_DRIVER:
            // Add more LEDs
            const ledDriver = components.find(c => c.name === "LED DRIVER");
            for (let i = 0; i < 2; i++) {
                const led = createComponent(COMPONENT_TYPES.LED, 1, 1);
                const ledRes = createComponent(COMPONENT_TYPES.RESISTOR, RESISTOR_LENGTH, RESISTOR_WIDTH);
                createConnection(ledDriver.id, ledRes.id);
                createConnection(ledRes.id, led.id);
                createConnection(led.id, components.find(c => c.type === COMPONENT_TYPES.GROUND).id);
            }
            
            // Add timing capacitor
            const timingCap = createComponent(COMPONENT_TYPES.CAPACITOR, 1, 1);
            createConnection(ledDriver.id, timingCap.id);
            createConnection(timingCap.id, components.find(c => c.type === COMPONENT_TYPES.GROUND).id);
            break;
    }
    
    // Add decoupling capacitors to all ICs
    const ics = components.filter(c => c.type === COMPONENT_TYPES.IC);
    for (const ic of ics) {
        const decouplingCap = createComponent(COMPONENT_TYPES.CAPACITOR, 1, 1);
        createConnection(ic.id, decouplingCap.id);
        createConnection(decouplingCap.id, components.find(c => c.type === COMPONENT_TYPES.GROUND).id);
    }
    
    // Add test points
    const testPoint1 = createComponent(COMPONENT_TYPES.POWER, 1, 1);
    testPoint1.name = "TP1";
    const testPoint2 = createComponent(COMPONENT_TYPES.POWER, 1, 1);
    testPoint2.name = "TP2";
    
    // Connect test points to interesting nodes
    if (components.length > 5) {
        createConnection(testPoint1.id, components[Math.floor(Math.random() * components.length)].id);
        createConnection(testPoint2.id, components[Math.floor(Math.random() * components.length)].id);
    }
}

// Place components based on their connections
function placeComponents() {
    const nx = Math.floor((MAX_X - MIN_X) / GRID_SIZE);
    const ny = Math.floor((MAX_Y - MIN_Y) / GRID_SIZE);
    
    // Ensure we have enough components
    if (components.length < MIN_COMPONENTS) {
        // Add some generic components
        const numToAdd = MIN_COMPONENTS - components.length;
        for (let i = 0; i < numToAdd; i++) {
            const type = Object.values(COMPONENT_TYPES)[Math.floor(Math.random() * 5)]; // Choose one of first 5 types
            const newComp = createComponent(type, type === COMPONENT_TYPES.IC ? 3 : 1, type === COMPONENT_TYPES.IC ? 3 : 1);
            
            // Connect to existing components
            const connectTo = components[Math.floor(Math.random() * components.length)];
            createConnection(newComp.id, connectTo.id);
            
            if (type === COMPONENT_TYPES.RESISTOR || type === COMPONENT_TYPES.CAPACITOR) {
                // Connect other end to ground or power
                const groundOrPower = components.find(c => 
                    c.type === (Math.random() < 0.5 ? COMPONENT_TYPES.GROUND : COMPONENT_TYPES.POWER)
                );
                if (groundOrPower) {
                    createConnection(newComp.id, groundOrPower.id);
                }
            }
        }
    }
    
    // Group related components (to place them closer together)
    const componentGroups = [];
    const processedComponents = new Set();
    
    // Create groups based on connections
    for (const component of components) {
        if (processedComponents.has(component.id)) continue;
        
        const group = [component];
        processedComponents.add(component.id);
        
        // Add directly connected components to group
        for (const connectedId of component.connections) {
            if (!processedComponents.has(connectedId)) {
                group.push(components[connectedId]);
                processedComponents.add(connectedId);
            }
        }
        
        componentGroups.push(group);
    }
    
    // Assign regions to each group
    const groupRegions = [];
    const numGroups = componentGroups.length;
    
    if (numGroups > 1) {
        // Divide board into regions
        const rowGroups = Math.ceil(Math.sqrt(numGroups));
        const colGroups = Math.ceil(numGroups / rowGroups);
        
        const regionWidth = Math.floor(nx / colGroups);
        const regionHeight = Math.floor(ny / rowGroups);
        
        for (let i = 0; i < numGroups; i++) {
            const row = Math.floor(i / colGroups);
            const col = i % colGroups;
            
            groupRegions.push({
                startX: col * regionWidth,
                startY: row * regionHeight,
                endX: (col + 1) * regionWidth - 1,
                endY: (row + 1) * regionHeight - 1
            });
        }
    } else {
        // Just one group, use the whole board
        groupRegions.push({
            startX: 0,
            startY: 0,
            endX: nx - 1,
            endY: ny - 1
        });
    }
    
    // Place components by group
    for (let g = 0; g < componentGroups.length; g++) {
        const group = componentGroups[g];
        const region = groupRegions[g];
        
        for (const component of group) {
            let placed = false;
            let attempts = 0;
            
            while (!placed && attempts < 100) {
                attempts++;
                
                // Generate position within region
                const gx = region.startX + Math.floor(Math.random() * (region.endX - region.startX - component.width + 1));
                const gy = region.startY + Math.floor(Math.random() * (region.endY - region.startY - component.height + 1));
                
                // Check if space is available
                let canPlace = true;
                for (let ox = 0; ox < component.width; ox++) {
                    for (let oy = 0; oy < component.height; oy++) {
                        if (!isInBounds(gx + ox, gy + oy) || occupied.has(`${gx+ox},${gy+oy}`)) {
                            canPlace = false;
                            break;
                        }
                    }
                    if (!canPlace) break;
                }
                
                if (canPlace) {
                    component.gx = gx;
                    component.gy = gy;
                    
                    // Mark as occupied
                    markOccupiedRect(gx, gy, component.width, component.height);
                    
                    // Draw the component
                    drawComponent(component);
                    
                    placed = true;
                }
            }
            
            // If we couldn't place in the region, try anywhere
            if (!placed) {
                attempts = 0;
                while (!placed && attempts < 100) {
                    attempts++;
                    
                    // Generate random position anywhere
                    const gx = Math.floor(Math.random() * (nx - component.width));
                    const gy = Math.floor(Math.random() * (ny - component.height));
                    
                    // Check if space is available
                    let canPlace = true;
                    for (let ox = 0; ox < component.width; ox++) {
                        for (let oy = 0; oy < component.height; oy++) {
                            if (!isInBounds(gx + ox, gy + oy) || occupied.has(`${gx+ox},${gy+oy}`)) {
                                canPlace = false;
                                break;
                            }
                        }
                        if (!canPlace) break;
                    }
                    
                    if (canPlace) {
                        component.gx = gx;
                        component.gy = gy;
                        
                        // Mark as occupied
                        markOccupiedRect(gx, gy, component.width, component.height);
                        
                        // Draw the component
                        drawComponent(component);
                        
                        placed = true;
                    }
                }
            }
        }
    }
}

// Draw a component on the board
function drawComponent(component) {
    const { x: cx, y: cy } = gridToCanvas(component.gx, component.gy);
    
    switch (component.type) {
        case COMPONENT_TYPES.IC:
            drawIC(component, cx, cy);
            break;
        case COMPONENT_TYPES.RESISTOR:
            drawResistor(component, cx, cy);
            break;
        case COMPONENT_TYPES.CAPACITOR:
            drawCapacitor(component, cx, cy);
            break;
        case COMPONENT_TYPES.LED:
            drawLED(component, cx, cy);
            break;
        case COMPONENT_TYPES.POWER:
            drawPowerNode(component, cx, cy);
            break;
        case COMPONENT_TYPES.GROUND:
            drawGroundNode(component, cx, cy);
            break;
        case COMPONENT_TYPES.DIODE:
            drawDiode(component, cx, cy);
            break;
        case COMPONENT_TYPES.TRANSISTOR:
            drawTransistor(component, cx, cy);
            break;
    }
}

// --- Component Drawing Functions ---

// Draw an IC component
function drawIC(component, cx, cy) {
    const width = component.width * GRID_SIZE;
    const height = component.height * GRID_SIZE;
    
    // Draw IC body
    drawFilledRect(cx + width/2, cy + height/2, width, height);
    
    // Add text/name if available
    if (component.name) {
        // Simple text representation (no actual text in TurtleToy)
        const textX = cx + width/2;
        const textY = cy + height/2;
        drawSimpleText(component.name, textX, textY, width * 0.6);
    }
    
    // Add pins along edges
    component.pins = [];
    
    // Top edge pins
    for (let px = 0; px < component.width; px += IC_PIN_SPACING) {
        if (px === 0 || px === component.width - 1 || Math.random() < 0.7) {
            const { x: pinX, y: pinY } = gridToCanvas(component.gx + px, component.gy - 1);
            const pinType = (px === 0) ? PIN_TYPES.POWER : 
                           (px === component.width - 1) ? PIN_TYPES.GROUND :
                           (Math.random() < 0.5) ? PIN_TYPES.INPUT : PIN_TYPES.OUTPUT;
            
            if (isInBounds(component.gx + px, component.gy - 1)) {
                drawPad(pinX, pinY, IC_PIN_PAD_RADIUS, component.id, pinType);
                component.pins.push({
                    x: component.gx + px,
                    y: component.gy - 1,
                    type: pinType
                });
            }
        }
    }
    
    // Bottom edge pins
    for (let px = 0; px < component.width; px += IC_PIN_SPACING) {
        if (px === 0 || px === component.width - 1 || Math.random() < 0.7) {
            const { x: pinX, y: pinY } = gridToCanvas(component.gx + px, component.gy + component.height);
            const pinType = (px === 0) ? PIN_TYPES.GROUND : 
                           (px === component.width - 1) ? PIN_TYPES.POWER :
                           (Math.random() < 0.5) ? PIN_TYPES.OUTPUT : PIN_TYPES.INPUT;
            
            if (isInBounds(component.gx + px, component.gy + component.height)) {
                drawPad(pinX, pinY, IC_PIN_PAD_RADIUS, component.id, pinType);
                component.pins.push({
                    x: component.gx + px,
                    y: component.gy + component.height,
                    type: pinType
                });
            }
        }
    }
    
    // Left edge pins
    for (let py = 0; py < component.height; py += IC_PIN_SPACING) {
        if (py === 0 || py === component.height - 1 || Math.random() < 0.7) {
            const { x: pinX, y: pinY } = gridToCanvas(component.gx - 1, component.gy + py);
            const pinType = (py === 0) ? PIN_TYPES.POWER : 
                           (py === component.height - 1) ? PIN_TYPES.GROUND :
                           (Math.random() < 0.5) ? PIN_TYPES.INPUT : PIN_TYPES.BIDIRECTIONAL;
            
            if (isInBounds(component.gx - 1, component.gy + py)) {
                drawPad(pinX, pinY, IC_PIN_PAD_RADIUS, component.id, pinType);
                component.pins.push({
                    x: component.gx - 1,
                    y: component.gy + py,
                    type: pinType
                });
            }
        }
    }
    
    // Right edge pins
    for (let py = 0; py < component.height; py += IC_PIN_SPACING) {
        if (py === 0 || py === component.height - 1 || Math.random() < 0.7) {
            const { x: pinX, y: pinY } = gridToCanvas(component.gx + component.width, component.gy + py);
            const pinType = (py === 0) ? PIN_TYPES.GROUND : 
                           (py === component.height - 1) ? PIN_TYPES.POWER :
                           (Math.random() < 0.5) ? PIN_TYPES.OUTPUT : PIN_TYPES.BIDIRECTIONAL;
            
            if (isInBounds(component.gx + component.width, component.gy + py)) {
                drawPad(pinX, pinY, IC_PIN_PAD_RADIUS, component.id, pinType);
                component.pins.push({
                    x: component.gx + component.width,
                    y: component.gy + py,
                    type: pinType
                });
            }
        }
    }
}

// Draw a resistor component
function drawResistor(component, cx, cy) {
    const width = component.width * GRID_SIZE;
    const height = component.height * GRID_SIZE;
    
    // Draw resistor body
    drawFilledRect(cx + width/2, cy + height/2, width, height);
    
    // Add zigzag pattern inside
    turtle.jump(cx, cy + height/2);
    turtle.goto(cx + width * 0.2, cy + height/2);
    
    // Zigzag pattern
    const zigZagWidth = width * 0.6;
    const segmentWidth = zigZagWidth / 6;
    const zigHeight = height * 0.6;
    
    turtle.goto(cx + width * 0.2 + segmentWidth, cy + height/2 - zigHeight/2);
    turtle.goto(cx + width * 0.2 + segmentWidth * 2, cy + height/2 + zigHeight/2);
    turtle.goto(cx + width * 0.2 + segmentWidth * 3, cy + height/2 - zigHeight/2);
    turtle.goto(cx + width * 0.2 + segmentWidth * 4, cy + height/2 + zigHeight/2);
    turtle.goto(cx + width * 0.2 + segmentWidth * 5, cy + height/2 - zigHeight/2);
    turtle.goto(cx + width * 0.2 + segmentWidth * 6, cy + height/2);
    turtle.goto(cx + width, cy + height/2);
    
    // Add pads at ends
    component.pins = [];
    
    // Left pad
    const { x: pinX1, y: pinY1 } = gridToCanvas(component.gx - 1, component.gy);
    if (isInBounds(component.gx - 1, component.gy)) {
        drawPad(pinX1, pinY1, RESISTOR_PAD_RADIUS, component.id, PIN_TYPES.BIDIRECTIONAL);
        component.pins.push({
            x: component.gx - 1,
            y: component.gy,
            type: PIN_TYPES.BIDIRECTIONAL
        });
    }
    
    // Right pad
    const { x: pinX2, y: pinY2 } = gridToCanvas(component.gx + component.width, component.gy);
    if (isInBounds(component.gx + component.width, component.gy)) {
        drawPad(pinX2, pinY2, RESISTOR_PAD_RADIUS, component.id, PIN_TYPES.BIDIRECTIONAL);
        component.pins.push({
            x: component.gx + component.width,
            y: component.gy,
            type: PIN_TYPES.BIDIRECTIONAL
        });
    }
}

// Draw a capacitor component
function drawCapacitor(component, cx, cy) {
    // Draw capacitor symbol
    const radius = CAPACITOR_RADIUS;
    const centerX = cx + radius;
    const centerY = cy + radius;
    
    // Draw plates
    // Vertical line left plate
    turtle.jump(centerX - radius * 0.5, centerY - radius * 0.7);
    turtle.goto(centerX - radius * 0.5, centerY + radius * 0.7);
    
    // Vertical line right plate
    turtle.jump(centerX + radius * 0.5, centerY - radius * 0.7);
    turtle.goto(centerX + radius * 0.5, centerY + radius * 0.7);
    
    // Add pads
    component.pins = [];
    
    // Left pad
    const { x: pinX1, y: pinY1 } = gridToCanvas(component.gx - 1, component.gy);
    if (isInBounds(component.gx - 1, component.gy)) {
        drawPad(pinX1, pinY1, CAPACITOR_PAD_RADIUS, component.id, PIN_TYPES.BIDIRECTIONAL);
        component.pins.push({
            x: component.gx - 1,
            y: component.gy,
            type: PIN_TYPES.BIDIRECTIONAL
        });
    }
    
    // Right pad
    const { x: pinX2, y: pinY2 } = gridToCanvas(component.gx + 2, component.gy);
    if (isInBounds(component.gx + 2, component.gy)) {
        drawPad(pinX2, pinY2, CAPACITOR_PAD_RADIUS, component.id, PIN_TYPES.BIDIRECTIONAL);
        component.pins.push({
            x: component.gx + 2,
            y: component.gy,
            type: PIN_TYPES.BIDIRECTIONAL
        });
    }
    
    // Connect pads to plates
    turtle.jump(pinX1, pinY1);
    turtle.goto(centerX - radius * 0.5, centerY);
    
    turtle.jump(pinX2, pinY2);
    turtle.goto(centerX + radius * 0.5, centerY);
}

// Draw an LED component
function drawLED(component, cx, cy) {
    const centerX = cx + GRID_SIZE/2;
    const centerY = cy + GRID_SIZE/2;
    const radius = GRID_SIZE * 0.4;
    
    // Draw circle for LED
    turtle.jump(centerX, centerY - radius);
    turtle.circle(radius);
    
    // Draw arrow inside (simplified LED symbol)
    const arrowSize = radius * 0.8;
    turtle.jump(centerX - arrowSize/2, centerY - arrowSize/2);
    turtle.goto(centerX + arrowSize/2, centerY);
    turtle.goto(centerX - arrowSize/2, centerY + arrowSize/2);
    
    // Add pads
    component.pins = [];
    
    // Anode pad
    const { x: anodeX, y: anodeY } = gridToCanvas(component.gx - 1, component.gy);
    if (isInBounds(component.gx - 1, component.gy)) {
        drawPad(anodeX, anodeY, RESISTOR_PAD_RADIUS, component.id, PIN_TYPES.POWER);
        component.pins.push({
            x: component.gx - 1,
            y: component.gy,
            type: PIN_TYPES.POWER
        });
    }
    
    // Cathode pad
    const { x: cathodeX, y: cathodeY } = gridToCanvas(component.gx + 1, component.gy);
    if (isInBounds(component.gx + 1, component.gy)) {
        drawPad(cathodeX, cathodeY, RESISTOR_PAD_RADIUS, component.id, PIN_TYPES.GROUND);
        component.pins.push({
            x: component.gx + 1,
            y: component.gy,
            type: PIN_TYPES.GROUND
        });
    }
}

// Draw a power node
function drawPowerNode(component, cx, cy) {
    const centerX = cx + GRID_SIZE/2;
    const centerY = cy + GRID_SIZE/2;
    const radius = GRID_SIZE * 0.4;
    
    // Draw power symbol
    drawPad(centerX, centerY, radius, component.id, PIN_TYPES.POWER);
    
    // Draw + symbol inside
    const symbolSize = radius * 0.6;
    
    // Horizontal line
    turtle.jump(centerX - symbolSize, centerY);
    turtle.goto(centerX + symbolSize, centerY);
    
    // Vertical line
    turtle.jump(centerX, centerY - symbolSize);
    turtle.goto(centerX, centerY + symbolSize);
    
    component.pins = [{
        x: component.gx,
        y: component.gy,
        type: PIN_TYPES.POWER
    }];
}

// Draw a ground node
function drawGroundNode(component, cx, cy) {
    const centerX = cx + GRID_SIZE/2;
    const centerY = cy + GRID_SIZE/2;
    const radius = GRID_SIZE * 0.4;
    
    // Draw ground symbol
    drawPad(centerX, centerY, radius, component.id, PIN_TYPES.GROUND);
    
    // Draw ground symbol inside
    const symbolSize = radius * 0.8;
    
    // Horizontal lines
    turtle.jump(centerX - symbolSize, centerY);
    turtle.goto(centerX + symbolSize, centerY);
    
    turtle.jump(centerX - symbolSize * 0.7, centerY + symbolSize * 0.3);
    turtle.goto(centerX + symbolSize * 0.7, centerY + symbolSize * 0.3);
    
    turtle.jump(centerX - symbolSize * 0.4, centerY + symbolSize * 0.6);
    turtle.goto(centerX + symbolSize * 0.4, centerY + symbolSize * 0.6);
    
    component.pins = [{
        x: component.gx,
        y: component.gy,
        type: PIN_TYPES.GROUND
    }];
}

// Draw a diode
function drawDiode(component, cx, cy) {
    const centerX = cx + GRID_SIZE;
    const centerY = cy + GRID_SIZE/2;
    
    // Draw diode symbol
    // Triangle
    const triangleSize = GRID_SIZE * 0.8;
    turtle.jump(centerX - triangleSize, centerY - triangleSize/2);
    turtle.goto(centerX, centerY);
    turtle.goto(centerX - triangleSize, centerY + triangleSize/2);
    turtle.goto(centerX - triangleSize, centerY - triangleSize/2);
    
    // Line
    turtle.jump(centerX, centerY - triangleSize/2);
    turtle.goto(centerX, centerY + triangleSize/2);
    
    // Add pads
    component.pins = [];
    
    // Anode pad
    const { x: anodeX, y: anodeY } = gridToCanvas(component.gx - 1, component.gy);
    if (isInBounds(component.gx - 1, component.gy)) {
        drawPad(anodeX, anodeY, RESISTOR_PAD_RADIUS, component.id, PIN_TYPES.POWER);
        component.pins.push({
            x: component.gx - 1,
            y: component.gy,
            type: PIN_TYPES.POWER
        });
    }
    
    // Cathode pad
    const { x: cathodeX, y: cathodeY } = gridToCanvas(component.gx + 2, component.gy);
    if (isInBounds(component.gx + 2, component.gy)) {
        drawPad(cathodeX, cathodeY, RESISTOR_PAD_RADIUS, component.id, PIN_TYPES.GROUND);
        component.pins.push({
            x: component.gx + 2,
            y: component.gy,
            type: PIN_TYPES.GROUND
        });
    }
}

// Draw a transistor
function drawTransistor(component, cx, cy) {
    const centerX = cx + GRID_SIZE;
    const centerY = cy + GRID_SIZE;
    const size = GRID_SIZE * 0.8;
    
    // Draw transistor symbol (simplified)
    // Circle
    turtle.jump(centerX, centerY - size);
    turtle.circle(size);
    
    // Base line
    turtle.jump(centerX - size, centerY);
    turtle.goto(centerX - size/4, centerY);
    
    // Collector line
    turtle.jump(centerX - size/4, centerY + size/2);
    turtle.goto(centerX - size/4, centerY - size/2);
    turtle.goto(centerX - size/4, centerY + size/3);
    
    // Emitter line
    turtle.jump(centerX - size/4, centerY);
    turtle.goto(centerX + size/2, centerY + size/2);
    
    // Add pads
    component.pins = [];
    
    // Base pad
    const { x: baseX, y: baseY } = gridToCanvas(component.gx - 1, component.gy + 1);
    if (isInBounds(component.gx - 1, component.gy + 1)) {
        drawPad(baseX, baseY, RESISTOR_PAD_RADIUS, component.id, PIN_TYPES.INPUT);
        component.pins.push({
            x: component.gx - 1,
            y: component.gy + 1,
            type: PIN_TYPES.INPUT
        });
    }
    
    // Collector pad
    const { x: collectorX, y: collectorY } = gridToCanvas(component.gx + 1, component.gy);
    if (isInBounds(component.gx + 1, component.gy)) {
        drawPad(collectorX, collectorY, RESISTOR_PAD_RADIUS, component.id, PIN_TYPES.OUTPUT);
        component.pins.push({
            x: component.gx + 1,
            y: component.gy,
            type: PIN_TYPES.OUTPUT
        });
    }
    
    // Emitter pad
    const { x: emitterX, y: emitterY } = gridToCanvas(component.gx + 1, component.gy + 2);
    if (isInBounds(component.gx + 1, component.gy + 2)) {
        drawPad(emitterX, emitterY, RESISTOR_PAD_RADIUS, component.id, PIN_TYPES.GROUND);
        component.pins.push({
            x: component.gx + 1,
            y: component.gy + 2,
            type: PIN_TYPES.GROUND
        });
    }
}

// --- Trace Routing Functions ---

// Route traces between connected components
function routeTraces() {
    const processed = new Set();
    
    // For each component
    for (const component of components) {
        // For each connection
        for (const connectedId of component.connections) {
            const connectionKey = [component.id, connectedId].sort().join('-');
            
            // Skip if already processed
            if (processed.has(connectionKey)) continue;
            processed.add(connectionKey);
            
            const connectedComponent = components[connectedId];
            
            // Find suitable pins to connect
            const sourcePin = findSuitablePin(component, connectedComponent);
            const targetPin = findSuitablePin(connectedComponent, component);
            
            if (sourcePin && targetPin) {
                routeTraceBetweenPins(sourcePin, targetPin, component.id, connectedId);
            }
        }
    }
}

// Find a suitable pin on a component for connection
function findSuitablePin(fromComponent, toComponent) {
    if (!fromComponent.pins || fromComponent.pins.length === 0) return null;
    
    // Find compatible pins based on types
    let compatiblePins = [];
    
    for (const pin of fromComponent.pins) {
        // Check pin type compatibility
        if (
            (pin.type === PIN_TYPES.OUTPUT && toComponent.type !== COMPONENT_TYPES.POWER) ||
            (pin.type === PIN_TYPES.INPUT && toComponent.type !== COMPONENT_TYPES.GROUND) ||
            (pin.type === PIN_TYPES.POWER && (toComponent.type === COMPONENT_TYPES.POWER || toComponent.type === COMPONENT_TYPES.IC)) ||
            (pin.type === PIN_TYPES.GROUND && (toComponent.type === COMPONENT_TYPES.GROUND || toComponent.type === COMPONENT_TYPES.IC)) ||
            pin.type === PIN_TYPES.BIDIRECTIONAL
        ) {
            compatiblePins.push(pin);
        }
    }
    
    // If no compatible pins, use any available pin
    if (compatiblePins.length === 0) {
        compatiblePins = fromComponent.pins;
    }
    
    // Pick a pin
    return compatiblePins[Math.floor(Math.random() * compatiblePins.length)];
}

// Route a trace between two pins using A* pathfinding
function routeTraceBetweenPins(sourcePin, targetPin, sourceComponentId, targetComponentId) {
    // Convert to canvas coordinates
    const { x: sourceX, y: sourceY } = gridToCanvas(sourcePin.x, sourcePin.y);
    const { x: targetX, y: targetY } = gridToCanvas(targetPin.x, targetPin.y);
    
    // Use A* to find a path
    const path = findPath(sourcePin.x, sourcePin.y, targetPin.x, targetPin.y);
    
    // Only draw if we have a valid path with multiple segments
    if (path.length > 0) {
        // Convert path to canvas coordinates
        const canvasPath = path.map(point => gridToCanvas(point.x, point.y));
        
        // Add start and end points
        canvasPath.unshift({ x: sourceX, y: sourceY });
        canvasPath.push({ x: targetX, y: targetY });
        
        // Only draw if we have at least 3 points (minimum 2 segments)
        if (canvasPath.length >= 3) {
            // Draw the trace
            drawTracePath(canvasPath);
        } else {
            // For short paths, add intermediate points to create a proper routed path
            const midX = (sourceX + targetX) / 2;
            const midY = (sourceY + targetY) / 2;
            
            // Create a 3-segment path with jogs
            const enhancedPath = [
                { x: sourceX, y: sourceY },
                { x: sourceX, y: midY },
                { x: targetX, y: midY },
                { x: targetX, y: targetY }
            ];
            
            // Draw the enhanced path
            drawTracePath(enhancedPath);
        }
    } else {
        // Create a multi-segment manhattan path instead of direct line
        const manhattanPath = createManhattanPath(sourcePin, targetPin);
        const canvasPath = manhattanPath.map(point => 
            point.canvas ? point : { x: gridToCanvas(point.x, point.y).x, y: gridToCanvas(point.x, point.y).y }
        );
        
        // Draw the manhattan path
        drawTracePath(canvasPath);
    }
}

// A* pathfinding algorithm
function findPath(startX, startY, endX, endY) {
    const openSet = [{ x: startX, y: startY, g: 0, h: heuristic(startX, startY, endX, endY), f: 0 }];
    const closedSet = new Set();
    const cameFrom = {};
    
    while (openSet.length > 0) {
        // Find node with lowest f score
        let currentIndex = 0;
        for (let i = 1; i < openSet.length; i++) {
            if (openSet[i].f < openSet[currentIndex].f) {
                currentIndex = i;
            }
        }
        
        const current = openSet[currentIndex];
        
        // Check if we reached the goal
        if (current.x === endX && current.y === endY) {
            // Reconstruct path
            const path = [];
            let currentNode = `${current.x},${current.y}`;
            
            while (cameFrom[currentNode]) {
                const [x, y] = currentNode.split(',').map(Number);
                path.unshift({ x, y });
                currentNode = cameFrom[currentNode];
            }
            
            return path;
        }
        
        // Remove current from openSet and add to closedSet
        openSet.splice(currentIndex, 1);
        closedSet.add(`${current.x},${current.y}`);
        
        // Check neighbors
        const directions = [
            { dx: 1, dy: 0 },  // Right
            { dx: 0, dy: 1 },  // Up
            { dx: -1, dy: 0 }, // Left
            { dx: 0, dy: -1 }  // Down
        ];
        
        for (const dir of directions) {
            const neighborX = current.x + dir.dx;
            const neighborY = current.y + dir.dy;
            const neighborKey = `${neighborX},${neighborY}`;
            
            // Skip if neighbor is in closedSet or not in bounds
            if (closedSet.has(neighborKey) || !isInBounds(neighborX, neighborY)) {
                continue;
            }
            
            // Skip if occupied (unless it's the target)
            if (occupied.has(neighborKey) && !(neighborX === endX && neighborY === endY)) {
                continue;
            }
            
            const g = current.g + 1;
            const h = heuristic(neighborX, neighborY, endX, endY);
            const f = g + h;
            
            // Check if neighbor is in openSet with a better path
            const existingNeighbor = openSet.find(node => node.x === neighborX && node.y === neighborY);
            if (existingNeighbor && existingNeighbor.g <= g) {
                continue;
            }
            
            // Add neighbor to openSet
            if (!existingNeighbor) {
                openSet.push({ x: neighborX, y: neighborY, g, h, f });
            } else {
                existingNeighbor.g = g;
                existingNeighbor.f = f;
            }
            
            // Record path
            cameFrom[neighborKey] = `${current.x},${current.y}`;
        }
    }
    
    // No path found
    return [];
}

// Manhattan distance heuristic
function heuristic(x1, y1, x2, y2) {
    return Math.abs(x1 - x2) + Math.abs(y1 - y2);
}

// --- Power and Ground Routing ---

// Draw integrated power and ground distribution
function drawPowerAndGroundRails() {
    const nx = Math.floor((MAX_X - MIN_X) / GRID_SIZE);
    const ny = Math.floor((MAX_Y - MIN_Y) / GRID_SIZE);
    
    // Find power and ground components
    const powerComponents = components.filter(c => c.type === COMPONENT_TYPES.POWER);
    const groundComponents = components.filter(c => c.type === COMPONENT_TYPES.GROUND);
    
    // Only draw rails if we have enough components to connect to
    if (powerComponents.length > 0 && groundComponents.length > 0 && components.length >= 5) {
        // Instead of straight horizontal rails, create a more integrated power distribution
        // Find component clusters to route power through
        
        // Create terminal blocks at edges for power and ground
        const powerTerminalX = 5;
        const powerTerminalY = Math.floor(ny / 4);
        const { x: powerTermX, y: powerTermY } = gridToCanvas(powerTerminalX, powerTerminalY);
        
        const groundTerminalX = nx - 6;
        const groundTerminalY = Math.floor(3 * ny / 4);
        const { x: groundTermX, y: groundTermY } = gridToCanvas(groundTerminalX, groundTerminalY);
        
        // Draw terminal blocks
        drawFilledRect(powerTermX + GRID_SIZE, powerTermY + GRID_SIZE, GRID_SIZE * 2, GRID_SIZE * 2);
        drawSimpleText("VCC", powerTermX + GRID_SIZE, powerTermY + GRID_SIZE, GRID_SIZE * 1.5);
        drawPad(powerTermX, powerTermY, PAD_RADIUS * 1.2, -1, PIN_TYPES.POWER);
        
        drawFilledRect(groundTermX + GRID_SIZE, groundTermY + GRID_SIZE, GRID_SIZE * 2, GRID_SIZE * 2);
        drawSimpleText("GND", groundTermX + GRID_SIZE, groundTermY + GRID_SIZE, GRID_SIZE * 1.5);
        drawPad(groundTermX, groundTermY, PAD_RADIUS * 1.2, -1, PIN_TYPES.GROUND);
        
        // Create power distribution tree instead of a single rail
        const powerNodes = [];
        const groundNodes = [];
        
        // Add 3-4 power distribution nodes
        const numPowerNodes = 3 + Math.floor(Math.random() * 2);
        const numGroundNodes = 3 + Math.floor(Math.random() * 2);
        
        // Create power distribution nodes
        for (let i = 0; i < numPowerNodes; i++) {
            const nodeX = Math.floor(nx * (i + 1) / (numPowerNodes + 1));
            const nodeY = Math.floor(ny / 3 + (Math.random() * ny / 3));
            
            if (!isOccupied(nodeX, nodeY)) {
                const { x: canvasX, y: canvasY } = gridToCanvas(nodeX, nodeY);
                drawPad(canvasX, canvasY, VIA_RADIUS * 1.5, -1, PIN_TYPES.POWER);
                powerNodes.push({ x: nodeX, y: nodeY, canvasX, canvasY });
                markOccupiedPoint(nodeX, nodeY);
            }
        }
        
        // Create ground distribution nodes
        for (let i = 0; i < numGroundNodes; i++) {
            const nodeX = Math.floor(nx * (i + 1) / (numGroundNodes + 1));
            const nodeY = Math.floor(ny * 2/3 + (Math.random() * ny / 4));
            
            if (!isOccupied(nodeX, nodeY)) {
                const { x: canvasX, y: canvasY } = gridToCanvas(nodeX, nodeY);
                drawPad(canvasX, canvasY, VIA_RADIUS * 1.5, -1, PIN_TYPES.GROUND);
                groundNodes.push({ x: nodeX, y: nodeY, canvasX, canvasY });
                markOccupiedPoint(nodeX, nodeY);
            }
        }
        
        // Connect power terminal to first power node
        if (powerNodes.length > 0) {
            turtle.jump(powerTermX, powerTermY);
            turtle.goto(powerNodes[0].canvasX, powerNodes[0].canvasY);
            
            // Connect power nodes in a tree
            for (let i = 1; i < powerNodes.length; i++) {
                const prevNode = powerNodes[i-1];
                const currNode = powerNodes[i];
                
                turtle.jump(prevNode.canvasX, prevNode.canvasY);
                turtle.goto(currNode.canvasX, currNode.canvasY);
            }
        }
        
        // Connect ground terminal to first ground node
        if (groundNodes.length > 0) {
            turtle.jump(groundTermX, groundTermY);
            turtle.goto(groundNodes[0].canvasX, groundNodes[0].canvasY);
            
            // Connect ground nodes in a tree
            for (let i = 1; i < groundNodes.length; i++) {
                const prevNode = groundNodes[i-1];
                const currNode = groundNodes[i];
                
                turtle.jump(prevNode.canvasX, prevNode.canvasY);
                turtle.goto(currNode.canvasX, currNode.canvasY);
            }
        }
        
        // Connect power components to nearest power node
        for (const component of powerComponents) {
            if (component.pins && component.pins.length > 0) {
                const pin = component.pins[0];
                const { x: pinX, y: pinY } = gridToCanvas(pin.x, pin.y);
                
                // Find closest power node
                let closestNode = null;
                let minDist = Infinity;
                
                for (const node of powerNodes) {
                    const dist = Math.sqrt(
                        Math.pow(pin.x - node.x, 2) + Math.pow(pin.y - node.y, 2)
                    );
                    
                    if (dist < minDist) {
                        minDist = dist;
                        closestNode = node;
                    }
                }
                
                if (closestNode) {
                    // Route to closest power node
                    const path = findPath(pin.x, pin.y, closestNode.x, closestNode.y);
                    
                    if (path.length > 0) {
                        // Convert path to canvas coordinates
                        const canvasPath = path.map(point => gridToCanvas(point.x, point.y));
                        
                        // Add start and end points
                        canvasPath.unshift({ x: pinX, y: pinY });
                        canvasPath.push({ x: closestNode.canvasX, y: closestNode.canvasY });
                        
                        // Draw the trace
                        drawTracePath(canvasPath);
                    } else {
                        // Direct line if no path found
                        turtle.jump(pinX, pinY);
                        turtle.goto(closestNode.canvasX, closestNode.canvasY);
                    }
                }
            }
        }
        
        // Connect ground components to nearest ground node
        for (const component of groundComponents) {
            if (component.pins && component.pins.length > 0) {
                const pin = component.pins[0];
                const { x: pinX, y: pinY } = gridToCanvas(pin.x, pin.y);
                
                // Find closest ground node
                let closestNode = null;
                let minDist = Infinity;
                
                for (const node of groundNodes) {
                    const dist = Math.sqrt(
                        Math.pow(pin.x - node.x, 2) + Math.pow(pin.y - node.y, 2)
                    );
                    
                    if (dist < minDist) {
                        minDist = dist;
                        closestNode = node;
                    }
                }
                
                if (closestNode) {
                    // Route to closest ground node
                    const path = findPath(pin.x, pin.y, closestNode.x, closestNode.y);
                    
                    if (path.length > 0) {
                        // Convert path to canvas coordinates
                        const canvasPath = path.map(point => gridToCanvas(point.x, point.y));
                        
                        // Add start and end points
                        canvasPath.unshift({ x: pinX, y: pinY });
                        canvasPath.push({ x: closestNode.canvasX, y: closestNode.canvasY });
                        
                        // Draw the trace
                        drawTracePath(canvasPath);
                    } else {
                        // Direct line if no path found
                        turtle.jump(pinX, pinY);
                        turtle.goto(closestNode.canvasX, closestNode.canvasY);
                    }
                }
            }
        }
        
        // Connect power/ground pins from ICs to nearest distribution nodes
        for (const component of components) {
            if (component.type === COMPONENT_TYPES.IC && component.pins) {
                // Find power pins
                const powerPins = component.pins.filter(pin => pin.type === PIN_TYPES.POWER);
                
                for (const pin of powerPins) {
                    const { x: pinX, y: pinY } = gridToCanvas(pin.x, pin.y);
                    
                    // Find closest power node
                    let closestNode = null;
                    let minDist = Infinity;
                    
                    for (const node of powerNodes) {
                        const dist = Math.sqrt(
                            Math.pow(pin.x - node.x, 2) + Math.pow(pin.y - node.y, 2)
                        );
                        
                        if (dist < minDist) {
                            minDist = dist;
                            closestNode = node;
                        }
                    }
                    
                    if (closestNode) {
                        // Route to power node
                        const path = findPath(pin.x, pin.y, closestNode.x, closestNode.y);
                        
                        if (path.length > 0) {
                            // Convert path to canvas coordinates
                            const canvasPath = path.map(point => gridToCanvas(point.x, point.y));
                            
                            // Add start and end points
                            canvasPath.unshift({ x: pinX, y: pinY });
                            canvasPath.push({ x: closestNode.canvasX, y: closestNode.canvasY });
                            
                            // Draw the trace
                            drawTracePath(canvasPath);
                        } else {
                            // Direct line
                            turtle.jump(pinX, pinY);
                            turtle.goto(closestNode.canvasX, closestNode.canvasY);
                        }
                    }
                }
                
                // Find ground pins
                const groundPins = component.pins.filter(pin => pin.type === PIN_TYPES.GROUND);
                
                for (const pin of groundPins) {
                    const { x: pinX, y: pinY } = gridToCanvas(pin.x, pin.y);
                    
                    // Find closest ground node
                    let closestNode = null;
                    let minDist = Infinity;
                    
                    for (const node of groundNodes) {
                        const dist = Math.sqrt(
                            Math.pow(pin.x - node.x, 2) + Math.pow(pin.y - node.y, 2)
                        );
                        
                        if (dist < minDist) {
                            minDist = dist;
                            closestNode = node;
                        }
                    }
                    
                    if (closestNode) {
                        // Route to ground node
                        const path = findPath(pin.x, pin.y, closestNode.x, closestNode.y);
                        
                        if (path.length > 0) {
                            // Convert path to canvas coordinates
                            const canvasPath = path.map(point => gridToCanvas(point.x, point.y));
                            
                            // Add start and end points
                            canvasPath.unshift({ x: pinX, y: pinY });
                            canvasPath.push({ x: closestNode.canvasX, y: closestNode.canvasY });
                            
                            // Draw the trace
                            drawTracePath(canvasPath);
                        } else {
                            // Direct line
                            turtle.jump(pinX, pinY);
                            turtle.goto(closestNode.canvasX, closestNode.canvasY);
                        }
                    }
                }
            }
        }
    }
}

// --- Helper Functions ---

// Add board outline and decorative elements
function addBoardOutline() {
    // Draw PCB outline
    turtle.penup();
    turtle.goto(MIN_X + 5, MIN_Y + 5);
    turtle.pendown();
    
    // Rounded corners
    const cornerRadius = 10;
    
    // Bottom left corner
    turtle.goto(MIN_X + 5 + cornerRadius, MIN_Y + 5);
    turtle.arc(90, cornerRadius);
    
    // Bottom edge
    turtle.goto(MAX_X - 5 - cornerRadius, MIN_Y + 5 + cornerRadius);
    
    // Bottom right corner
    turtle.arc(90, cornerRadius);
    
    // Right edge
    turtle.goto(MAX_X - 5, MAX_Y - 5 - cornerRadius);
    
    // Top right corner
    turtle.arc(90, cornerRadius);
    
    // Top edge
    turtle.goto(MIN_X + 5 + cornerRadius, MAX_Y - 5);
    
    // Top left corner
    turtle.arc(90, cornerRadius);
    
    // Left edge
    turtle.goto(MIN_X + 5, MIN_Y + 5 + cornerRadius);
}

// Add mounting holes to the board
function addMountingHoles() {
    const holeRadius = 3;
    const margin = 15;
    
    // Bottom left mounting hole
    turtle.jump(MIN_X + margin, MIN_Y + margin);
    turtle.circle(holeRadius);
    
    // Bottom right mounting hole
    turtle.jump(MAX_X - margin, MIN_Y + margin);
    turtle.circle(holeRadius);
    
    // Top right mounting hole
    turtle.jump(MAX_X - margin, MAX_Y - margin);
    turtle.circle(holeRadius);
    
    // Top left mounting hole
    turtle.jump(MIN_X + margin, MAX_Y - margin);
    turtle.circle(holeRadius);
}

// Arc drawing helper (adds to Turtle prototype)
Turtle.prototype.arc = function(angle, radius) {
    const startX = this.x;
    const startY = this.y;
    const steps = Math.max(10, Math.floor(radius * 0.5));
    const angleStep = angle / steps;
    
    // Get starting angle based on current direction
    let currentAngle = this.angle - 90;
    
    for (let i = 0; i <= steps; i++) {
        const rads = (currentAngle + angleStep * i) * Math.PI / 180;
        const x = startX + radius * Math.cos(rads);
        const y = startY + radius * Math.sin(rads);
        this.goto(x, y);
    }
    
    // Update turtle's angle
    this.angle = (this.angle + angle) % 360;
};

// Grid coordinate conversion
function gridToCanvas(gx, gy) {
    const canvasX = MIN_X + (MAX_X - MIN_X) * (gx / (Math.floor((MAX_X - MIN_X) / GRID_SIZE)));
    const canvasY = MIN_Y + (MAX_Y - MIN_Y) * (gy / (Math.floor((MAX_Y - MIN_Y) / GRID_SIZE)));
    // Clamp to bounds just in case
    return {
        x: Math.max(MIN_X, Math.min(MAX_X, canvasX)),
        y: Math.max(MIN_Y, Math.min(MAX_Y, canvasY))
    };
}

// Check if grid coordinate is within bounds
function isInBounds(gx, gy) {
    const nx = Math.floor((MAX_X - MIN_X) / GRID_SIZE);
    const ny = Math.floor((MAX_Y - MIN_Y) / GRID_SIZE);
    return gx >= 0 && gx < nx && gy >= 0 && gy < ny;
}

// Mark grid points as occupied
function markOccupiedRect(gx, gy, gw, gh) {
    for (let x = gx; x < gx + gw; x++) {
        for (let y = gy; y < gy + gh; y++) {
            if (isInBounds(x, y)) {
                occupied.add(`${x},${y}`);
            }
        }
    }
}

function markOccupiedPoint(gx, gy) {
    if (isInBounds(gx, gy)) {
        occupied.add(`${gx},${gy}`);
    }
}

function isOccupied(gx, gy) {
    return occupied.has(`${gx},${gy}`);
}

// Draw a simple circle pad
function drawPad(cx, cy, radius, componentId, pinType) {
    turtle.jump(cx, cy - radius); // Jump to starting point for circle
    turtle.circle(radius);
    
    // Store pad center for trace routing
    pads.push({ x: cx, y: cy, r: radius, componentId, pinType });
}

// Draw a filled rectangle (for components)
function drawFilledRect(cx, cy, width, height) {
    const x1 = cx - width / 2;
    const y1 = cy - height / 2;
    const x2 = cx + width / 2;
    const y2 = cy + height / 2;

    turtle.jump(x1, y1);
    turtle.goto(x2, y1);
    turtle.goto(x2, y2);
    turtle.goto(x1, y2);
    turtle.goto(x1, y1);

    // Add simple hatching fill
    for (let y = y1; y <= y2; y += GRID_SIZE / 2) {
        turtle.jump(x1, y);
        turtle.goto(x2, y);
    }
}

// Draws the actual lines for a trace path, optionally thicker
function drawTracePath(path) {
    if (NUM_TRACE_LINES <= 1) {
        // Simple thin trace
        turtle.jump(path[0].x, path[0].y);
        for (let k = 1; k < path.length; k++) {
            turtle.goto(path[k].x, path[k].y);
        }
    } else {
        // Simulate thicker trace with parallel lines
        for (let lineIdx = 0; lineIdx < NUM_TRACE_LINES; lineIdx++) {
            const offset = (lineIdx - Math.floor(NUM_TRACE_LINES / 2)) * TRACE_WIDTH;
            let lastOffsetP = null;

            turtle.penup();
            for (let k = 0; k < path.length; k++) {
                let p1 = path[k];
                let p2 = (k < path.length - 1) ? path[k+1] : p1; // Next point or current if last
                let p0 = (k > 0) ? path[k-1] : p1; // Previous point or current if first

                let dx = p2.x - p0.x;
                let dy = p2.y - p0.y;
                let len = Math.sqrt(dx*dx + dy*dy);
                let nx = 0, ny = 0;
                if (len > 0.01) {
                    // Normal vector (perpendicular)
                    nx = -dy / len;
                    ny = dx / len;
                } else if (k > 0) {
                    // Handle endpoint case - use previous segment's normal
                    dx = p1.x - p0.x;
                    dy = p1.y - p0.y;
                    len = Math.sqrt(dx*dx + dy*dy);
                    if (len > 0.01) {
                        nx = -dy / len;
                        ny = dx / len;
                    }
                }

                const offsetX = p1.x + nx * offset;
                const offsetY = p1.y + ny * offset;
                const offsetP = {x: offsetX, y: offsetY};

                if (k === 0) {
                    turtle.goto(offsetP.x, offsetP.y);
                    turtle.pendown();
                } else {
                    turtle.goto(offsetP.x, offsetP.y);
                }
                lastOffsetP = offsetP;
            }
            turtle.penup(); // End of one parallel line
        }
    }
}

// Draw simplified text representation
function drawSimpleText(text, x, y, maxWidth) {
    const scale = Math.min(1, maxWidth / (text.length * 5));
    const charWidth = 5 * scale;
    const charHeight = 7 * scale;
    const startX = x - (text.length * charWidth) / 2;
    
    for (let i = 0; i < text.length; i++) {
        const charX = startX + i * charWidth;
        
        // Extremely simplified text (just a box for each character)
        turtle.jump(charX, y - charHeight/2);
        turtle.goto(charX + charWidth, y - charHeight/2);
        turtle.goto(charX + charWidth, y + charHeight/2);
        turtle.goto(charX, y + charHeight/2);
        turtle.goto(charX, y - charHeight/2);
    }
}

// Simple jump function
Turtle.prototype.jump = function(x,y) {
    this.penup();
    this.goto(x,y);
    this.pendown();
};