<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Réseau Neuronal avec Poids</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            background: linear-gradient(135deg, #0a0a1a 0%, #1a0a2e 100%);
            min-height: 100vh;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            color: #ffffff;
            padding: 20px;
        }

        .header {
            text-align: center;
            margin-bottom: 40px;
        }

        h1 {
            color: #00d4ff;
            margin-bottom: 10px;
            font-size: 2.5em;
            text-shadow: 0 0 20px rgba(0, 212, 255, 0.5);
        }

        .subtitle {
            color: #00ff88;
            font-size: 1.2em;
        }

        .controls {
            margin-bottom: 30px;
            display: flex;
            gap: 15px;
        }

        button {
            padding: 15px 40px;
            background-color: #00d4ff;
            color: #000;
            border: none;
            border-radius: 8px;
            font-weight: bold;
            font-size: 1.1em;
            cursor: pointer;
            transition: all 0.3s;
            box-shadow: 0 0 15px rgba(0, 212, 255, 0.5);
        }

        button:hover {
            background-color: #00ff88;
            box-shadow: 0 0 25px rgba(0, 255, 136, 0.8);
            transform: scale(1.05);
        }

        .status {
            color: #00ff88;
            font-weight: bold;
            margin-left: 20px;
            padding: 10px 20px;
            background-color: rgba(0, 255, 136, 0.1);
            border-radius: 5px;
            border: 1px solid #00ff88;
        }

        .container {
            display: flex;
            gap: 80px;
            align-items: center;
            margin-bottom: 50px;
            position: relative;
            width: 100%;
            max-width: 1100px;
            justify-content: center;
        }

        canvas {
            position: absolute;
            top: 0;
            left: 0;
            pointer-events: none;
        }

        .layer {
            display: flex;
            flex-direction: column;
            align-items: center;
            z-index: 10;
        }

        .layer-label {
            font-weight: bold;
            margin-bottom: 20px;
            font-size: 1em;
            color: #ffd60a;
            text-transform: uppercase;
            letter-spacing: 2px;
        }

        .neurons {
            display: flex;
            flex-direction: column;
            gap: 25px;
        }

        .neuron {
            width: 60px;
            height: 60px;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            font-weight: bold;
            font-size: 1.1em;
            cursor: pointer;
            transition: all 0.3s ease;
            border: 3px solid;
            box-shadow: inset 0 0 10px rgba(255, 255, 255, 0.1);
        }

        .neuron-input {
            background: linear-gradient(135deg, #0066ff, #0099ff);
            border-color: #00d4ff;
            color: #ffffff;
        }

        .neuron-hidden {
            background: linear-gradient(135deg, #ffcc00, #ffee00);
            border-color: #ffd60a;
            color: #000;
        }

        .neuron-output {
            width: 80px;
            height: 80px;
            background: linear-gradient(135deg, #00ff88, #00dd77);
            border-color: #00ff88;
            color: #000;
            font-size: 2em;
        }

        .neuron:hover {
            transform: scale(1.1);
        }

        .neuron.active {
            box-shadow: 0 0 25px currentColor, 0 0 50px currentColor, inset 0 0 10px rgba(255, 255, 255, 0.2);
            transform: scale(1.25);
        }

        .explanation {
            max-width: 900px;
            background-color: rgba(26, 26, 42, 0.9);
            border: 2px solid #00d4ff;
            border-radius: 12px;
            padding: 40px;
            margin-top: 20px;
            box-shadow: 0 0 30px rgba(0, 212, 255, 0.2);
        }

        .explanation h2 {
            color: #00ff88;
            margin-bottom: 30px;
            font-size: 1.8em;
            text-align: center;
        }

        .explanation-item {
            display: flex;
            gap: 20px;
            margin-bottom: 25px;
            align-items: flex-start;
        }

        .explanation-number {
            width: 50px;
            height: 50px;
            background-color: #ffd60a;
            color: #000;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            font-weight: bold;
            font-size: 1.2em;
            flex-shrink: 0;
            box-shadow: 0 0 15px rgba(255, 214, 10, 0.5);
        }

        .explanation-text h3 {
            color: #00d4ff;
            margin-bottom: 8px;
            font-size: 1.1em;
        }

        .explanation-text p {
            color: #dddddd;
            font-size: 0.95em;
            line-height: 1.6;
        }

        .tip {
            background: linear-gradient(135deg, rgba(26, 42, 58, 0.8), rgba(0, 212, 255, 0.1));
            border-left: 5px solid #ff006e;
            padding: 20px;
            margin-top: 25px;
            border-radius: 8px;
            box-shadow: 0 0 15px rgba(255, 0, 110, 0.1);
        }

        .tip p {
            color: #ff006e;
            font-size: 0.95em;
            line-height: 1.6;
        }

        footer {
            position: fixed;
            bottom: 15px;
            right: 20px;
            color: #666666;
            font-size: 0.85em;
            background-color: rgba(0, 0, 0, 0.3);
            padding: 8px 15px;
            border-radius: 5px;
            border: 1px solid rgba(0, 212, 255, 0.2);
        }

        @media (max-width: 768px) {
            h1 {
                font-size: 1.8em;
            }

            .container {
                gap: 40px;
                margin-bottom: 30px;
            }

            .neuron {
                width: 50px;
                height: 50px;
                font-size: 0.9em;
            }

            .neuron-output {
                width: 65px;
                height: 65px;
                font-size: 1.5em;
            }

            .explanation {
                padding: 25px;
            }

            .controls {
                flex-direction: column;
            }

            .status {
                margin-left: 0;
            }
        }
    </style>
</head>
<body>
    <div class="header">
        <h1>🧠 Réseau Neuronal - Avec Poids</h1>
        <p class="subtitle">Vois comment les poids changent pendant l'apprentissage!</p>
    </div>

    <div class="controls">
        <button onclick="toggleAnimation()">▶ Lancer</button>
        <button onclick="resetWeights()" style="background-color: #ff006e;">🔄 Réinitialiser</button>
        <div class="status">
            Itération: <span id="iteration">0</span>
        </div>
    </div>

    <div class="container">
        <canvas id="canvas"></canvas>

        <!-- COUCHE INPUT -->
        <div class="layer">
            <div class="layer-label">Input</div>
            <div class="neurons" id="inputLayer">
                <div class="neuron neuron-input">1</div>
                <div class="neuron neuron-input">2</div>
                <div class="neuron neuron-input">3</div>
            </div>
        </div>

        <!-- COUCHE HIDDEN -->
        <div class="layer">
            <div class="layer-label">Hidden</div>
            <div class="neurons" id="hiddenLayer">
                <div class="neuron neuron-hidden">A</div>
                <div class="neuron neuron-hidden">B</div>
                <div class="neuron neuron-hidden">C</div>
                <div class="neuron neuron-hidden">D</div>
            </div>
        </div>

        <!-- COUCHE OUTPUT -->
        <div class="layer">
            <div class="layer-label">Output</div>
            <div class="neurons" id="outputLayer">
                <div class="neuron neuron-output">✓</div>
            </div>
        </div>
    </div>

    <!-- EXPLICATIONS -->
    <div class="explanation">
        <h2>Comment fonctionne un réseau neuronal?   © A.Boulot 2023</h2>

        <div class="explanation-item">
            <div class="explanation-number">1️⃣</div>
            <div class="explanation-text">
                <h3>INPUT (Les données)</h3>
                <p>Les neurones bleus reçoivent les données brutes (pixels d'une image, texte, etc.)</p>
            </div>
        </div>

        <div class="explanation-item">
            <div class="explanation-number">2️⃣</div>
            <div class="explanation-text">
                <h3>HIDDEN (Le traitement)</h3>
                <p>Les neurones jaunes traitent les données. Les nombres sur les lignes sont les POIDS - 
                ils contrôlent la "force" de chaque connexion.</p>
            </div>
        </div>

        <div class="explanation-item">
            <div class="explanation-number">3️⃣</div>
            <div class="explanation-text">
                <h3>OUTPUT (Le résultat)</h3>
                <p>Le neurone vert donne la réponse finale basée sur tous les calculs précédents.</p>
            </div>
        </div>

        <div class="tip">
            <p><strong>🔑 L'astuce IMPORTANTE - Les POIDS:</strong> 
            Chaque ligne entre les neurones a un poids (un nombre). 
            Pendant l'apprentissage, l'IA ajuste ces nombres pour donner de meilleures réponses. 
            C'EST LA CLÉ! Plus les poids sont ajustés correctement, meilleure est l'IA. 
            Observe comment les nombres sur les lignes changent à chaque itération!</p>
        </div>
    </div>

    <footer>© A.Boulot 2023</footer>

    <!-- JAVASCRIPT -->
    <script>
        const canvas = document.getElementById('canvas');
        const ctx = canvas.getContext('2d');
        let isAnimating = true;
        let activeNeuron = null;
        let iteration = 0;

        // Initialiser les poids aléatoirement
        let weights = {
            inputToHidden: [],
            hiddenToOutput: []
        };

        // Créer les poids INPUT → HIDDEN (3 inputs × 4 hidden)
        for (let i = 0; i < 3; i++) {
            weights.inputToHidden[i] = [];
            for (let j = 0; j < 4; j++) {
                weights.inputToHidden[i][j] = (Math.random() * 2 - 1).toFixed(2);
            }
        }

        // Créer les poids HIDDEN → OUTPUT (4 hidden × 1 output)
        for (let i = 0; i < 4; i++) {
            weights.hiddenToOutput[i] = (Math.random() * 2 - 1).toFixed(2);
        }

        function saveInitialWeights() {
            return JSON.parse(JSON.stringify(weights));
        }

        const initialWeights = saveInitialWeights();

        // Redimensionner le canvas
        function resizeCanvas() {
            const container = document.querySelector('.container');
            canvas.width = container.offsetWidth;
            canvas.height = container.offsetHeight;
            drawConnections();
        }

        // Obtenir les positions des neurones
        function getLayerPositions(layerId) {
            const layer = document.getElementById(layerId);
            const neurons = layer.querySelectorAll('.neuron');
            const positions = [];
            
            neurons.forEach(neuron => {
                const rect = neuron.getBoundingClientRect();
                const containerRect = canvas.getBoundingClientRect();
                positions.push({
                    x: rect.left - containerRect.left + rect.width / 2,
                    y: rect.top - containerRect.top + rect.height / 2
                });
            });
            
            return positions;
        }

        // Dessiner les connexions avec les poids
        function drawConnections() {
            ctx.clearRect(0, 0, canvas.width, canvas.height);

            const inputPos = getLayerPositions('inputLayer');
            const hiddenPos = getLayerPositions('hiddenLayer');
            const outputPos = getLayerPositions('outputLayer');

            // Connexions INPUT → HIDDEN avec poids
            inputPos.forEach((input, i) => {
                hiddenPos.forEach((hidden, j) => {
                    const weight = weights.inputToHidden[i][j];
                    const weightValue = parseFloat(weight);
                    
                    // Couleur basée sur la valeur du poids
                    let color;
                    if (weightValue > 0.5) {
                        color = `rgba(0, 255, 136, ${Math.abs(weightValue) / 2})`;
                    } else if (weightValue < -0.5) {
                        color = `rgba(255, 0, 110, ${Math.abs(weightValue) / 2})`;
                    } else {
                        color = `rgba(0, 212, 255, 0.4)`;
                    }

                    ctx.strokeStyle = color;
                    ctx.lineWidth = Math.abs(weightValue) * 3 + 1;
                    ctx.beginPath();
                    ctx.moveTo(input.x, input.y);
                    ctx.lineTo(hidden.x, hidden.y);
                    ctx.stroke();

                    // Afficher le poids au milieu de la ligne
                    const midX = (input.x + hidden.x) / 2;
                    const midY = (input.y + hidden.y) / 2;
                    ctx.fillStyle = '#00d4ff';
                    ctx.font = 'bold 11px Arial';
                    ctx.textAlign = 'center';
                    ctx.fillText(weight, midX, midY);
                });
            });

            // Connexions HIDDEN → OUTPUT avec poids
            hiddenPos.forEach((hidden, i) => {
                outputPos.forEach((output) => {
                    const weight = weights.hiddenToOutput[i];
                    const weightValue = parseFloat(weight);

                    let color;
                    if (weightValue > 0.5) {
                        color = `rgba(0, 255, 136, ${Math.abs(weightValue) / 2})`;
                    } else if (weightValue < -0.5) {
                        color = `rgba(255, 0, 110, ${Math.abs(weightValue) / 2})`;
                    } else {
                        color = `rgba(0, 255, 136, 0.4)`;
                    }

                    ctx.strokeStyle = color;
                    ctx.lineWidth = Math.abs(weightValue) * 3 + 1;
                    ctx.beginPath();
                    ctx.moveTo(hidden.x, hidden.y);
                    ctx.lineTo(output.x, output.y);
                    ctx.stroke();

                    const midX = (hidden.x + output.x) / 2;
                    const midY = (hidden.y + output.y) / 2;
                    ctx.fillStyle = '#00ff88';
                    ctx.font = 'bold 11px Arial';
                    ctx.textAlign = 'center';
                    ctx.fillText(weight, midX, midY);
                });
            });
        }

        // Mettre à jour les poids (simuler l'apprentissage)
        function updateWeights() {
            // Ajuster légèrement les poids pour simuler l'apprentissage
            for (let i = 0; i < 3; i++) {
                for (let j = 0; j < 4; j++) {
                    const change = (Math.random() - 0.5) * 0.1;
                    let newWeight = parseFloat(weights.inputToHidden[i][j]) + change;
                    newWeight = Math.max(-2, Math.min(2, newWeight)); // Limiter entre -2 et 2
                    weights.inputToHidden[i][j] = newWeight.toFixed(2);
                }
            }

            for (let i = 0; i < 4; i++) {
                const change = (Math.random() - 0.5) * 0.1;
                let newWeight = parseFloat(weights.hiddenToOutput[i]) + change;
                newWeight = Math.max(-2, Math.min(2, newWeight));
                weights.hiddenToOutput[i] = newWeight.toFixed(2);
            }
        }

        // Activer un neurone aléatoire
        function activateRandomNeuron() {
            const allNeurons = document.querySelectorAll('.neuron');
            
            if (activeNeuron) {
                activeNeuron.classList.remove('active');
            }

            const random = allNeurons[Math.floor(Math.random() * allNeurons.length)];
            random.classList.add('active');
            activeNeuron = random;
        }

        // Boucle d'animation
        function animate() {
            drawConnections();
            
            if (isAnimating) {
                activateRandomNeuron();
                updateWeights();
                iteration++;
                document.getElementById('iteration').textContent = iteration;
            }

            requestAnimationFrame(animate);
        }

        // Toggle animation
        function toggleAnimation() {
            isAnimating = !isAnimating;
            const button = document.querySelector('button');
            button.textContent = isAnimating ? '⏸ Pause' : '▶ Lancer';
        }

        // Réinitialiser les poids
        function resetWeights() {
            weights = JSON.parse(JSON.stringify(initialWeights));
            iteration = 0;
            document.getElementById('iteration').textContent = '0';
            if (activeNeuron) {
                activeNeuron.classList.remove('active');
            }
            drawConnections();
        }

        // Cliquer sur un neurone
        document.querySelectorAll('.neuron').forEach(neuron => {
            neuron.addEventListener('click', () => {
                isAnimating = false;
                if (activeNeuron) {
                    activeNeuron.classList.remove('active');
                }
                neuron.classList.add('active');
                activeNeuron = neuron;
                document.querySelector('button').textContent = '▶ Lancer';
            });
        });

        window.addEventListener('resize', resizeCanvas);
        resizeCanvas();
        animate();
    </script>
</body>
</html>