guess my age and profession - wrote this (leveraging tools of course) after a long day at work. 


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Neural Colony Evolution</title>
    <style>
        body {
            margin: 0;
            padding: 20px;
            background-color: #0a0a0a;
            color: #fff;
            font-family: 'Monaco', 'Menlo', monospace;
            overflow-x: hidden;
        }
        
        #canvas {
            border: 2px solid #333;
            display: block;
            margin: 20px auto;
            cursor: crosshair;
            box-shadow: 0 0 20px rgba(0, 200, 255, 0.3);
        }
        
        #controls {
            max-width: 800px;
            margin: 0 auto 20px;
            display: grid;
            grid-template-columns: repeat(3, 1fr);
            gap: 10px;
        }
        
        .control-group {
            display: flex;
            align-items: center;
            justify-content: space-between;
            padding: 8px;
            background-color: #1a1a1a;
            border-radius: 5px;
            border: 1px solid #333;
        }
        
        label {
            font-size: 11px;
            color: #aaa;
        }
        
        input, select {
            width: 100px;
            background-color: #2a2a2a;
            color: #fff;
            border: 1px solid #444;
            padding: 4px;
            border-radius: 3px;
        }
        
        button {
            grid-column: span 3;
            padding: 12px;
            background: linear-gradient(135deg, #00a8ff 0%, #0078ff 100%);
            color: #fff;
            border: none;
            cursor: pointer;
            border-radius: 5px;
            font-weight: bold;
            transition: all 0.3s;
        }
        
        button:hover {
            background: linear-gradient(135deg, #00b8ff 0%, #0088ff 100%);
            box-shadow: 0 4px 15px rgba(0, 150, 255, 0.4);
        }
        
        #info {
            text-align: center;
            margin-top: 10px;
            font-size: 12px;
        }
        
        .stat-badge {
            display: inline-block;
            margin: 0 10px;
            padding: 4px 12px;
            border-radius: 15px;
            background: rgba(255, 255, 255, 0.1);
            border: 1px solid rgba(255, 255, 255, 0.2);
        }
        
        #networkInspector {
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background: linear-gradient(135deg, #1a1a1a 0%, #2a2a2a 100%);
            border: 2px solid #444;
            border-radius: 10px;
            padding: 20px;
            display: none;
            z-index: 1000;
            min-width: 350px;
            box-shadow: 0 10px 40px rgba(0, 0, 0, 0.8);
        }
        
        #networkInspector h3 {
            margin: 0 0 15px 0;
            color: #00a8ff;
            text-align: center;
        }
        
        .network-viz {
            margin: 20px 0;
            text-align: center;
        }
        
        .xor-test {
            display: grid;
            grid-template-columns: repeat(2, 1fr);
            gap: 10px;
            margin: 15px 0;
        }
        
        .xor-test input {
            width: 100%;
        }
        
        .test-output {
            grid-column: span 2;
            text-align: center;
            padding: 10px;
            background: #333;
            border-radius: 5px;
            font-size: 18px;
            font-weight: bold;
        }
        
        .close-btn {
            position: absolute;
            top: 10px;
            right: 10px;
            background: #ff4444;
            border: none;
            color: white;
            width: 30px;
            height: 30px;
            border-radius: 50%;
            cursor: pointer;
            font-weight: bold;
        }
        
        .entity-stats {
            font-size: 11px;
            line-height: 1.6;
            border-top: 1px solid #444;
            margin-top: 15px;
            padding-top: 15px;
        }
        
        .overlay {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.7);
            display: none;
            z-index: 999;
        }
        
        #legend {
            position: fixed;
            top: 20px;
            right: 20px;
            background: rgba(26, 26, 26, 0.9);
            border: 1px solid #444;
            border-radius: 5px;
            padding: 15px;
            font-size: 11px;
        }
        
        .legend-item {
            margin: 5px 0;
            display: flex;
            align-items: center;
        }
        
        .legend-color {
            width: 20px;
            height: 20px;
            margin-right: 10px;
            border-radius: 3px;
        }
    </style>
</head>
<body>
    <div id="controls">
        <div class="control-group">
            <label>Learning Rate:</label>
            <input type="number" id="learningRate" value="0.5" min="0.01" max="2" step="0.01">
        </div>
        
        <div class="control-group">
            <label>Mutation Rate:</label>
            <input type="number" id="mutationRate" value="0.1" min="0" max="1" step="0.01">
        </div>
        
        <div class="control-group">
            <label>Move Threshold:</label>
            <input type="number" id="moveThreshold" value="30" min="10" max="100" step="5">
        </div>
        
        <div class="control-group">
            <label>Divide Threshold:</label>
            <input type="number" id="divideThreshold" value="80" min="50" max="200" step="10">
        </div>
        
        <div class="control-group">
            <label>Training Epochs/Cycle:</label>
            <input type="number" id="epochsPerCycle" value="10" min="1" max="50" step="1">
        </div>
        
        <div class="control-group">
            <label>Speed:</label>
            <input type="range" id="speed" value="60" min="1" max="120" step="1">
        </div>
        
        <div class="control-group">
            <label>HP Loss Rate:</label>
            <input type="number" id="hpLossRate" value="2" min="0" max="10" step="0.1">
        </div>
        
        <button onclick="initSimulation()">Restart Simulation</button>
    </div>
    
    <canvas id="canvas"></canvas>
    
    <div id="info">
        <span class="stat-badge">Generation: <span id="generation">0</span></span>
        <span class="stat-badge">Entities: <span id="entityCount">0</span></span>
        <span class="stat-badge">Avg Error: <span id="avgError">0.00</span></span>
        <span class="stat-badge">Best Error: <span id="bestError">1.00</span></span>
    </div>
    
    <div id="territoryInfo" style="text-align: center; margin-top: 10px;">
        <div id="speciesStats" style="display: flex; justify-content: center; flex-wrap: wrap; gap: 10px;"></div>
        <button onclick="findBest()" style="margin-top: 10px; padding: 8px 20px; background: linear-gradient(135deg, #ff6b00 0%, #ff8800 100%); border: none; color: white; border-radius: 5px; cursor: pointer; font-weight: bold;">🏆 Find Best Entity</button>
    </div>
    
    <div id="legend">
        <h4 style="margin: 0 0 10px 0; color: #00a8ff;">Heat Map Legend</h4>
        <div class="legend-item">
            <div class="legend-color" style="background: #ff0000;"></div>
            <span>Low HP (0-20)</span>
        </div>
        <div class="legend-item">
            <div class="legend-color" style="background: #ff8800;"></div>
            <span>Medium HP (20-50)</span>
        </div>
        <div class="legend-item">
            <div class="legend-color" style="background: #ffff00;"></div>
            <span>Good HP (50-80)</span>
        </div>
        <div class="legend-item">
            <div class="legend-color" style="background: #00ff00;"></div>
            <span>High HP (80+)</span>
        </div>
    </div>
    
    <div class="overlay" id="overlay" onclick="closeInspector()"></div>
    
    <div id="networkInspector">
        <button class="close-btn" onclick="closeInspector()">×</button>
        <h3>Neural Network Inspector</h3>
        <div id="networkDetails"></div>
        <div class="xor-test">
            <input type="number" id="input1" min="0" max="1" step="1" value="0" placeholder="Input 1">
            <input type="number" id="input2" min="0" max="1" step="1" value="0" placeholder="Input 2">
            <div class="test-output" id="testOutput">Output: -</div>
            <button onclick="testNetwork()" style="grid-column: span 2; padding: 8px;">Test XOR</button>
        </div>
        <div class="entity-stats" id="entityStats"></div>
    </div>

    <script>
        // Configuration
        const GRID_SIZE = 100;
        const CELL_SIZE = 6;
        const CANVAS_SIZE = GRID_SIZE * CELL_SIZE;
        const INITIAL_ENTITIES = 6;
        
        // XOR training data
        const XOR_DATA = [
            {inputs: [0, 0], target: [0]},
            {inputs: [0, 1], target: [1]},
            {inputs: [1, 0], target: [1]},
            {inputs: [1, 1], target: [0]}
        ];
        
        // Canvas setup
        const canvas = document.getElementById('canvas');
        const ctx = canvas.getContext('2d');
        canvas.width = CANVAS_SIZE;
        canvas.height = CANVAS_SIZE;
        
        // Global state
        let grid = [];
        let generation = 0;
        let animationId = null;
        let selectedEntity = null;
        let frameCount = 0;
        
        // Neural Network class
        class NeuralNetwork {
            constructor(hiddenNodes = 2, learningRate = 0.5, activation = 'tanh') {
                this.hiddenNodes = hiddenNodes;
                this.learningRate = learningRate;
                this.activation = activation;
                
                // Initialize weights with small random values
                this.weightsIH = this.initWeights(2, hiddenNodes);
                this.weightsHO = this.initWeights(hiddenNodes, 1);
                this.biasH = this.initWeights(1, hiddenNodes)[0];
                this.biasO = Math.random() * 2 - 1;
                
                // Tracking
                this.error = 1.0;
                this.trainingSamples = 0;
            }
            
            initWeights(inputs, outputs) {
                const weights = [];
                const scale = Math.sqrt(2.0 / inputs); // Xavier initialization
                for (let i = 0; i < inputs; i++) {
                    weights[i] = [];
                    for (let j = 0; j < outputs; j++) {
                        weights[i][j] = (Math.random() * 2 - 1) * scale;
                    }
                }
                return weights;
            }
            
            activate(x) {
                switch(this.activation) {
                    case 'sigmoid':
                        return 1 / (1 + Math.exp(-x));
                    case 'tanh':
                        return Math.tanh(x);
                    case 'relu':
                        return Math.max(0, x);
                    default:
                        return x;
                }
            }
            
            activateDerivative(x) {
                switch(this.activation) {
                    case 'sigmoid':
                        const sig = this.activate(x);
                        return sig * (1 - sig);
                    case 'tanh':
                        const tanh = Math.tanh(x);
                        return 1 - tanh * tanh;
                    case 'relu':
                        return x > 0 ? 1 : 0;
                    default:
                        return 1;
                }
            }
            
            forward(inputs) {
                // Input to hidden
                const hidden = [];
                const hidden_sums = [];
                for (let j = 0; j < this.hiddenNodes; j++) {
                    let sum = this.biasH[j];
                    for (let i = 0; i < 2; i++) {
                        sum += inputs[i] * this.weightsIH[i][j];
                    }
                    hidden_sums[j] = sum;
                    hidden[j] = this.activate(sum);
                }
                
                // Hidden to output
                let output = this.biasO;
                for (let j = 0; j < this.hiddenNodes; j++) {
                    output += hidden[j] * this.weightsHO[j][0];
                }
                output = 1 / (1 + Math.exp(-output)); // Sigmoid for output
                
                return {output, hidden, hidden_sums};
            }
            
            train(epochs = 10) {
                let totalError = 0;
                
                for (let epoch = 0; epoch < epochs; epoch++) {
                    let epochError = 0;
                    
                    // Shuffle training data
                    const shuffled = [...XOR_DATA].sort(() => Math.random() - 0.5);
                    
                    for (const sample of shuffled) {
                        const {output, hidden, hidden_sums} = this.forward(sample.inputs);
                        const error = sample.target[0] - output;
                        epochError += Math.abs(error);
                        
                        // Backpropagation
                        // Output layer
                        const outputDelta = error * output * (1 - output);
                        
                        // Update hidden to output weights
                        for (let j = 0; j < this.hiddenNodes; j++) {
                            this.weightsHO[j][0] += this.learningRate * outputDelta * hidden[j];
                        }
                        this.biasO += this.learningRate * outputDelta;
                        
                        // Hidden layer
                        const hiddenDeltas = [];
                        for (let j = 0; j < this.hiddenNodes; j++) {
                            const error = outputDelta * this.weightsHO[j][0];
                            hiddenDeltas[j] = error * this.activateDerivative(hidden_sums[j]);
                        }
                        
                        // Update input to hidden weights
                        for (let i = 0; i < 2; i++) {
                            for (let j = 0; j < this.hiddenNodes; j++) {
                                this.weightsIH[i][j] += this.learningRate * hiddenDeltas[j] * sample.inputs[i];
                            }
                        }
                        
                        // Update hidden biases
                        for (let j = 0; j < this.hiddenNodes; j++) {
                            this.biasH[j] += this.learningRate * hiddenDeltas[j];
                        }
                    }
                    
                    totalError = epochError / 4;
                }
                
                this.error = totalError;
                this.trainingSamples += epochs * 4;
                return totalError;
            }
            
            predict(inputs) {
                return this.forward(inputs).output;
            }
            
            getComplexity() {
                // Complexity based on number of hidden nodes
                return this.hiddenNodes;
            }
            
            mutate(mutationRate) {
                const child = new NeuralNetwork(this.hiddenNodes, this.learningRate, this.activation);
                
                // Copy and mutate weights
                for (let i = 0; i < 2; i++) {
                    for (let j = 0; j < this.hiddenNodes; j++) {
                        child.weightsIH[i][j] = this.weightsIH[i][j] + (Math.random() - 0.5) * mutationRate;
                    }
                }
                
                for (let j = 0; j < this.hiddenNodes; j++) {
                    child.weightsHO[j][0] = this.weightsHO[j][0] + (Math.random() - 0.5) * mutationRate;
                    child.biasH[j] = this.biasH[j] + (Math.random() - 0.5) * mutationRate;
                }
                
                child.biasO = this.biasO + (Math.random() - 0.5) * mutationRate;
                
                // Mutate hyperparameters
                if (Math.random() < mutationRate) {
                    child.learningRate = Math.max(0.01, Math.min(2, this.learningRate + (Math.random() - 0.5) * 0.2));
                }
                
                if (Math.random() < mutationRate * 0.1) { // Rare structural mutation
                    child.hiddenNodes = Math.max(1, Math.min(4, this.hiddenNodes + (Math.random() < 0.5 ? -1 : 1)));
                    child.weightsIH = child.initWeights(2, child.hiddenNodes);
                    child.weightsHO = child.initWeights(child.hiddenNodes, 1);
                    child.biasH = child.initWeights(1, child.hiddenNodes)[0];
                }
                
                return child;
            }
        }
        
        // Entity class
        class Entity {
            constructor(x, y, network = null, species = 0) {
                this.x = x;
                this.y = y;
                this.network = network || new NeuralNetwork(
                    2 + Math.floor(Math.random() * 3), // 2-4 hidden nodes
                    0.5 + Math.random() * 0.5,          // 0.5-1.0 learning rate
                    ['tanh', 'sigmoid', 'relu'][Math.floor(Math.random() * 3)]
                );
                this.hp = 50;
                this.age = 0;
                this.species = species;
                this.lastMoveGeneration = 0;
                this.lastDivideGeneration = 0;
            }
            
            calculateHP() {
                // HP rewards both simplicity AND accuracy
                const complexity = this.network.getComplexity();
                const accuracy = 1 - this.network.error;
                
                // Base HP from simplicity (fewer nodes = more HP)
                const simplicityBonus = 100 - (complexity * 20);
                
                // Accuracy bonus (better learning = more HP)
                const accuracyBonus = accuracy * 100;
                
                // Target HP based on performance
                const targetHP = Math.max(0, simplicityBonus + accuracyBonus);
                
                // Gradually move current HP toward target HP
                const hpDiff = targetHP - this.hp;
                this.hp += hpDiff * 0.1; // Smooth transition
                
                return this.hp;
            }
            
            update(generation, params) {
                this.age++;
                
                // Apply HP loss (constant drain)
                this.hp -= params.hpLossRate;
                
                // Train the network
                const error = this.network.train(params.epochsPerCycle);
                
                // Update HP based on performance
                this.calculateHP();
                
                // Ensure HP doesn't go negative
                this.hp = Math.max(0, this.hp);
                
                // Check for movement
                if (this.hp > params.moveThreshold && generation - this.lastMoveGeneration > 5) {
                    this.move();
                    this.lastMoveGeneration = generation;
                }
                
                // Check for division
                if (this.hp > params.divideThreshold && generation - this.lastDivideGeneration > 10) {
                    return this.divide(params.mutationRate);
                }
                
                return null;
            }
            
            move() {
                const directions = [
                    {dx: -1, dy: 0}, {dx: 1, dy: 0},
                    {dx: 0, dy: -1}, {dx: 0, dy: 1}
                ];
                
                const validMoves = directions.filter(dir => {
                    const newX = this.x + dir.dx;
                    const newY = this.y + dir.dy;
                    return newX >= 0 && newX < GRID_SIZE && 
                           newY >= 0 && newY < GRID_SIZE;
                });
                
                if (validMoves.length > 0) {
                    const move = validMoves[Math.floor(Math.random() * validMoves.length)];
                    const newX = this.x + move.dx;
                    const newY = this.y + move.dy;
                    
                    // Check if occupied
                    const occupant = grid[newY][newX];
                    if (occupant) {
                        // Combat! Higher HP wins
                        if (this.hp > occupant.hp) {
                            // Take over the cell
                            grid[this.y][this.x] = null;
                            grid[newY][newX] = this;
                            this.x = newX;
                            this.y = newY;
                            // Gain some HP from conquest
                            this.hp += occupant.hp * 0.2;
                        }
                    } else {
                        // Move to empty cell
                        grid[this.y][this.x] = null;
                        grid[newY][newX] = this;
                        this.x = newX;
                        this.y = newY;
                    }
                }
            }
            
            divide(mutationRate) {
                const directions = [
                    {dx: -1, dy: 0}, {dx: 1, dy: 0},
                    {dx: 0, dy: -1}, {dx: 0, dy: 1},
                    {dx: -1, dy: -1}, {dx: 1, dy: 1},
                    {dx: -1, dy: 1}, {dx: 1, dy: -1}
                ];
                
                const validSpots = directions.filter(dir => {
                    const newX = this.x + dir.dx;
                    const newY = this.y + dir.dy;
                    return newX >= 0 && newX < GRID_SIZE && 
                           newY >= 0 && newY < GRID_SIZE &&
                           !grid[newY][newX];
                });
                
                if (validSpots.length > 0) {
                    const spot = validSpots[Math.floor(Math.random() * validSpots.length)];
                    const childX = this.x + spot.dx;
                    const childY = this.y + spot.dy;
                    
                    // Create child with mutated network
                    const childNetwork = this.network.mutate(mutationRate);
                    const child = new Entity(childX, childY, childNetwork, this.species);
                    
                    // Parent loses HP from division
                    this.hp *= 0.7;
                    this.lastDivideGeneration = generation;
                    
                    return child;
                }
                
                return null;
            }
        }
        
        // Initialize grid
        function initGrid() {
            grid = [];
            for (let y = 0; y < GRID_SIZE; y++) {
                grid[y] = [];
                for (let x = 0; x < GRID_SIZE; x++) {
                    grid[y][x] = null;
                }
            }
        }
        
        // Place initial entities
        function placeInitialEntities() {
            const positions = [];
            
            // Generate random positions
            while (positions.length < INITIAL_ENTITIES) {
                const x = Math.floor(Math.random() * GRID_SIZE);
                const y = Math.floor(Math.random() * GRID_SIZE);
                
                // Ensure spacing
                const tooClose = positions.some(pos => 
                    Math.abs(pos.x - x) < 20 && Math.abs(pos.y - y) < 20
                );
                
                if (!tooClose) {
                    positions.push({x, y});
                }
            }
            
            // Create entities with different starting configurations
            positions.forEach((pos, i) => {
                const hiddenNodes = 1 + (i % 4); // 1-4 hidden nodes
                const learningRate = 0.1 + (i * 0.15); // Varied learning rates
                const activation = ['tanh', 'sigmoid', 'relu'][i % 3];
                
                const network = new NeuralNetwork(hiddenNodes, learningRate, activation);
                const entity = new Entity(pos.x, pos.y, network, i);
                grid[pos.y][pos.x] = entity;
            });
        }
        
        // Heat map color calculation
        function getHeatmapColor(hp) {
            // Clamp HP to 0-100 range for color calculation
            const clampedHP = Math.max(0, Math.min(100, hp));
            const ratio = clampedHP / 100;
            
            let r, g, b;
            
            if (ratio < 0.25) {
                // Red to orange
                r = 255;
                g = Math.floor(ratio * 4 * 128);
                b = 0;
            } else if (ratio < 0.5) {
                // Orange to yellow
                r = 255;
                g = 128 + Math.floor((ratio - 0.25) * 4 * 127);
                b = 0;
            } else if (ratio < 0.75) {
                // Yellow to light green
                r = 255 - Math.floor((ratio - 0.5) * 4 * 128);
                g = 255;
                b = 0;
            } else {
                // Light green to green
                r = 127 - Math.floor((ratio - 0.75) * 4 * 127);
                g = 255;
                b = 0;
            }
            
            return `rgb(${r}, ${g}, ${b})`;
        }
        
        // Update simulation
        function update() {
            const params = {
                moveThreshold: parseFloat(document.getElementById('moveThreshold').value),
                divideThreshold: parseFloat(document.getElementById('divideThreshold').value),
                mutationRate: parseFloat(document.getElementById('mutationRate').value),
                epochsPerCycle: parseInt(document.getElementById('epochsPerCycle').value),
                hpLossRate: parseFloat(document.getElementById('hpLossRate').value)
            };
            
            const newEntities = [];
            let totalError = 0;
            let entityCount = 0;
            let bestError = 1;
            const speciesCounts = {};
            
            // Update all entities
            for (let y = 0; y < GRID_SIZE; y++) {
                for (let x = 0; x < GRID_SIZE; x++) {
                    const entity = grid[y][x];
                    if (entity) {
                        speciesCounts[entity.species] = (speciesCounts[entity.species] || 0) + 1;

                        const child = entity.update(generation, params);
                        if (child) {
                            newEntities.push(child);
                        }
                        
                        totalError += entity.network.error;
                        entityCount++;
                        bestError = Math.min(bestError, entity.network.error);
                        
                        // Remove if HP too low
                        if (entity.hp <= 0) {
                            grid[y][x] = null;
                        }
                    }
                }
            }
            
            // Place new entities
            newEntities.forEach(entity => {
                if (!grid[entity.y][entity.x]) {
                    grid[entity.y][entity.x] = entity;
                }
            });
            
            updateTerritoryInfo(speciesCounts);

            // Update stats
            generation++;
            document.getElementById('generation').textContent = generation;
            document.getElementById('entityCount').textContent = entityCount;
            document.getElementById('avgError').textContent = entityCount > 0 ? 
                (totalError / entityCount).toFixed(3) : '0.000';
            document.getElementById('bestError').textContent = bestError.toFixed(3);
        }
        
        // Render grid
        function render() {
            ctx.fillStyle = '#0a0a0a';
            ctx.fillRect(0, 0, CANVAS_SIZE, CANVAS_SIZE);
            
            // Draw entities with heat map
            for (let y = 0; y < GRID_SIZE; y++) {
                for (let x = 0; x < GRID_SIZE; x++) {
                    const entity = grid[y][x];
                    if (entity) {
                        ctx.fillStyle = getHeatmapColor(entity.hp);
                        ctx.fillRect(x * CELL_SIZE, y * CELL_SIZE, CELL_SIZE, CELL_SIZE);
                        
                        // Add subtle border for species identification
                        ctx.strokeStyle = `hsl(${entity.species * 60}, 70%, 50%)`;
                        ctx.lineWidth = 1;
                        ctx.strokeRect(x * CELL_SIZE + 0.5, y * CELL_SIZE + 0.5, CELL_SIZE - 1, CELL_SIZE - 1);
                    }
                }
            }
            
            // Grid lines for clarity
            ctx.strokeStyle = 'rgba(255, 255, 255, 0.05)';
            ctx.lineWidth = 0.5;
            for (let i = 0; i <= GRID_SIZE; i++) {
                ctx.beginPath();
                ctx.moveTo(i * CELL_SIZE, 0);
                ctx.lineTo(i * CELL_SIZE, CANVAS_SIZE);
                ctx.moveTo(0, i * CELL_SIZE);
                ctx.lineTo(CANVAS_SIZE, i * CELL_SIZE);
                ctx.stroke();
            }
        }
        
        // Animation loop
        function animate() {
            frameCount++;
            const speed = parseInt(document.getElementById('speed').value);
            
            if (frameCount % (121 - speed) === 0) {
                update();
            }
            
            render();
            animationId = requestAnimationFrame(animate);
        }
        
        // Handle canvas clicks
        canvas.addEventListener('click', (e) => {
            const rect = canvas.getBoundingClientRect();
            const x = Math.floor((e.clientX - rect.left) / CELL_SIZE);
            const y = Math.floor((e.clientY - rect.top) / CELL_SIZE);
            
            if (x >= 0 && x < GRID_SIZE && y >= 0 && y < GRID_SIZE) {
                const entity = grid[y][x];
                if (entity) {
                    selectedEntity = entity;
                    showInspector(entity);
                }
            }
        });
        
        // Show network inspector
        function showInspector(entity) {
            const inspector = document.getElementById('networkInspector');
            const overlay = document.getElementById('overlay');
            
            // Network details
            const details = document.getElementById('networkDetails');
            details.innerHTML = `
                <div class="network-viz">
                    <strong>Architecture:</strong> 2 → ${entity.network.hiddenNodes} → 1<br>
                    <strong>Activation:</strong> ${entity.network.activation}<br>
                    <strong>Learning Rate:</strong> ${entity.network.learningRate.toFixed(3)}
                </div>
            `;
            
            // Entity stats
            const stats = document.getElementById('entityStats');
            stats.innerHTML = `
                <strong>Position:</strong> (${entity.x}, ${entity.y})<br>
                <strong>HP:</strong> ${entity.hp.toFixed(1)}<br>
                <strong>Age:</strong> ${entity.age} generations<br>
                <strong>Error:</strong> ${entity.network.error.toFixed(4)}<br>
                <strong>Complexity:</strong> ${entity.network.getComplexity()} hidden nodes<br>
                <strong>Training Samples:</strong> ${entity.network.trainingSamples}<br>
                <strong>Species:</strong> ${entity.species}
            `;
            
            inspector.style.display = 'block';
            overlay.style.display = 'block';
        }
        
        // Close inspector
        function closeInspector() {
            document.getElementById('networkInspector').style.display = 'none';
            document.getElementById('overlay').style.display = 'none';
            selectedEntity = null;
        }
        
        // Test network with custom inputs
        function testNetwork() {
            if (!selectedEntity) return;
            
            const input1 = parseFloat(document.getElementById('input1').value);
            const input2 = parseFloat(document.getElementById('input2').value);
            
            if (isNaN(input1) || isNaN(input2)) return;

            const output = selectedEntity.network.predict([input1, input2]);
            const outputEl = document.getElementById('testOutput');
            
            outputEl.textContent = `Output: ${output.toFixed(4)}`;
            outputEl.style.color = 'white';
            outputEl.style.background = output > 0.5 ? '#2b9e49' : '#d63031';
        }
        
        function updateTerritoryInfo(speciesCounts) {
            const statsContainer = document.getElementById('speciesStats');
            statsContainer.innerHTML = '';

            const sortedSpecies = Object.entries(speciesCounts).sort(([, a], [, b]) => b - a);

            for (const [speciesId, count] of sortedSpecies) {
                const speciesEl = document.createElement('div');
                speciesEl.className = 'stat-badge';
                speciesEl.style.borderLeft = `5px solid hsl(${speciesId * 60}, 70%, 50%)`;
                speciesEl.style.paddingLeft = '8px';
                speciesEl.innerHTML = `Colony ${speciesId}: <strong>${count}</strong>`;
                statsContainer.appendChild(speciesEl);
            }
        }
        
        function findBest() {
            let bestEntity = null;
            let minError = Infinity;

            for (let y = 0; y < GRID_SIZE; y++) {
                for (let x = 0; x < GRID_SIZE; x++) {
                    const entity = grid[y][x];
                    if (entity && entity.network.error < minError) {
                        minError = entity.network.error;
                        bestEntity = entity;
                    }
                }
            }

            if (bestEntity) {
                selectedEntity = bestEntity;
                showInspector(bestEntity);
            } else {
                alert("No entities found in the simulation.");
            }
        }

        // Initialize simulation
        function initSimulation() {
            if (animationId) {
                cancelAnimationFrame(animationId);
            }
            
            generation = 0;
            frameCount = 0;
            selectedEntity = null;
            
            initGrid();
            placeInitialEntities();
            animate();
        }
        
        // Start simulation
        initSimulation();
    </script>
</body>
</html>