L’Agora joue avec l’IA

Répondre
Partager Rechercher
Citation :
Publié par Axoulotl08
En même temps c'est son taff. Les LLM (on devrait arrêter de dire IA, ca n'en est pas) c'est juste des supers algos pour faire de jolie trucs en assemblant le masse de donnée possible. Ca n'invente rien. D'où les soucis ici. Claude va pomper les repos git d'étudiants qui ont fait ca pour leur devoirs, fait un gloubi boulga de tout ca et pont ce truc. Il n'invente rien. Si demain on lui demande un truc qui n'existe pas, il est perdu. Il en est incapable.
Citation :
Publié par Axoulotl08
A quel moment c'est fabuleux ? Y'a tjs pas une version correcte de sortie... Pour un truc supposé être tout puissant c'est un peu la dèche...
L'IA a a créé ce petit jeu 3D avec moi en mode balec qui est parti d'un prompt de 2 lignes. y a quelques bugs mineurs qui se règlent en 1 prompt d'une ligne à chaque fois, et encore le coup des textures qui changent et des blocs qui décalent sils sont contre une bord quand on pivote, ce ne sont pas des bugs, juste des choses à préciser.

T'es tellement blasé du truc que tu vas louper non pas le wagon mais le train entier. Ta remarque sur "ce sont juste des algos", "ça n'invente rien" démontrent que t'es resté coincé à quelques années maintenant en arrière. Tu te trompes sur Claude.

Il va halluciner si tu lui demandes une nouvelle loi mathématique, évidemment, son job c'est de te répondre quoi qu'il arrive. Mais ça ne veut pas dire qu'il n'invente rien. Il ne pompe pas en faisant du C/c. Il recompose tout, tu peux obtenir des patterns absolument inédits.

voici la nouvelle version du Tetris :

Citation :
Publié par Malkav
Pour evaluer la capacité de l'IA a coder, faut lui filer des taches simples mais "nouvelles" sur le net.
Par exemple coder une gui en RUST (choix de la library gui au choix de l'IA), qui implemente une ouverture de fichier son wav, mp3, ogg, autre... une visualisation simple du spectre, possibilité de lecture, quelques outils simples genre un algo de nettoyage du bruit open source, ou de suppression des blancs.
Avec sauvegarde du resultat dans le format de notre choix bien sur.

L'IA sera super forte pour te pondre une architecture abstraite ou te proposer des technos pertinentes pour répondre au besoin, mais elle se mettra à halluciner en inventant des crates imaginaires dès qu'elle voudra cracher du code un peu plus compliqué qu'ouvrir une fenêtre et afficher un bouton.
Y a pas que pour l'architecture qu'elle sera balaise, sur les choix de techos etc elle va t'épater aussi.

J'ai bien envie de tester ton défi aussi ce soir. je note : coder une gui en RUST (choix de la library gui au choix de l'IA), qui implemente une ouverture de fichier son wav, mp3, ogg, autre... une visualisation simple du spectre, possibilité de lecture, quelques outils simples genre un algo de nettoyage du bruit open source, ou de suppression des blancs.


Citation :
Publié par Ex-voto
Voilà mon projet informatique :
je me suis permis de retravailler ton prompt :

Citation :

1. Définis un modèle de données pour un réseau de métro

Tu dois modéliser les entités suivantes :
  • Circuit de voie : état
    Code:
    libre
    ou
    Code:
    occupé
  • Aiguille : état
    Code:
    normal
    ou
    Code:
    reverse
  • Signal : état
    Code:
    permissif
    ou
    Code:
    restrictif
  • Itinéraire : état
    Code:
    détruit
    ,
    Code:
    enregistré
    ou
    Code:
    formé
    .
    Un itinéraire va d’un signal origine à un signal destination, en passant par une séquence de circuits et d’aiguilles.

2. Génère un exemple de base de données d’un réseau fictif

  • Propose un exemple complet de base de données correspondant à ce modèle, comprenant au moins :
    • 5 circuits de voie
    • 2 aiguilles
    • 3 signaux
    • 2 itinéraires
Structure-la au format JSON ou toute structure facilement exploitable en code.

3. Développe le code serveur et IHM pour animer la représentation du réseau

  • Choisis un framework web léger (ex : Flask, FastAPI, Express.js, etc.) pour le serveur et une IHM simple (ex : HTML/JS, React, etc.).
  • Affiche dynamiquement :
    • Les circuits de voie avec leur état (
      Code:
      libre
      /
      Code:
      occupé
      )
    • Les aiguilles avec leur état (
      Code:
      normal
      /
      Code:
      reverse
      )
    • Les signaux avec leur état (
      Code:
      permissif
      /
      Code:
      restrictif
      )
    • Les itinéraires avec leur état (
      Code:
      détruit
      /
      Code:
      enregistré
      /
      Code:
      formé
      )
  • Représentation :
    • Un train = un rectangle, affiché dès que deux circuits de voie consécutifs sont occupés.
  • Les états doivent pouvoir changer dynamiquement (par API ou websocket).

4. Génère un simulateur simple pour animer le logiciel

  • Crée un script/simulateur qui fait se déplacer un train unique sur le réseau fictif :
    • Le train occupe les circuits de voie de façon séquentielle, modifiant dynamiquement l’état des circuits, des aiguilles et des signaux selon la logique du réseau.
    • L’interface doit montrer visuellement ce déplacement en temps réel.

Objectif final :
Obtiens le projet complet, prêt à lancer localement, avec une IHM web interactive représentant le réseau, capable d’animer un train sur le réseau fictif.
voici le résultat, 1 prompt unique :


Citation :

Résumé du projet

J'ai créé un système complet de supervision d'un réseau de métro avec :

1. Architecture

  • Backend : FastAPI avec WebSocket pour les mises à jour temps réel
  • Frontend : HTML5 Canvas pour la visualisation dynamique
  • Communication : REST API + WebSocket bidirectionnel

2. Fonctionnalités principales

  • Visualisation en temps réel du réseau (circuits, aiguilles, signaux)
  • Détection automatique des trains (2 circuits consécutifs occupés)
  • Gestion des itinéraires avec vérification de sécurité
  • Simulateur de circulation de train
  • Contrôle manuel des éléments du réseau

3. Points techniques notables

  • État centralisé côté serveur avec diffusion WebSocket
  • Rendu Canvas optimisé avec mise à jour différentielle
  • Logique métier respectant les contraintes ferroviaires
  • API RESTful complète pour toutes les opérations

4. Pour démarrer

  1. Créez les 3 fichiers (JSON, Python, HTML)
  2. Installez FastAPI :
    Code:
    pip install fastapi uvicorn websockets
  3. Lancez :
    Code:
    python main.py
  4. Ouvrez :
    Code:
    http://localhost:8000
Le système est prêt à l'emploi et peut être étendu facilement avec de nouveaux éléments de réseau ou des fonctionnalités supplémentaires comme plusieurs trains, la gestion des zones de manœuvre, ou l'intégration avec des systèmes SCADA réels.
modèle de données du réseau
Code:
{
  "circuits": {
    "C1": {
      "id": "C1",
      "nom": "Circuit 1",
      "etat": "libre",
      "position": { "x": 100, "y": 200 }
    },
    "C2": {
      "id": "C2",
      "nom": "Circuit 2",
      "etat": "libre",
      "position": { "x": 200, "y": 200 }
    },
    "C3": {
      "id": "C3",
      "nom": "Circuit 3",
      "etat": "libre",
      "position": { "x": 300, "y": 200 }
    },
    "C4": {
      "id": "C4",
      "nom": "Circuit 4",
      "etat": "libre",
      "position": { "x": 400, "y": 150 }
    },
    "C5": {
      "id": "C5",
      "nom": "Circuit 5",
      "etat": "libre",
      "position": { "x": 400, "y": 250 }
    }
  },
  "aiguilles": {
    "A1": {
      "id": "A1",
      "nom": "Aiguille 1",
      "etat": "normal",
      "position": { "x": 250, "y": 200 },
      "circuit_avant": "C2",
      "circuit_normal": "C3",
      "circuit_reverse": "C4"
    },
    "A2": {
      "id": "A2",
      "nom": "Aiguille 2",
      "etat": "normal",
      "position": { "x": 350, "y": 200 },
      "circuit_avant": "C3",
      "circuit_normal": "C5",
      "circuit_reverse": "C4"
    }
  },
  "signaux": {
    "S1": {
      "id": "S1",
      "nom": "Signal 1",
      "etat": "permissif",
      "position": { "x": 80, "y": 180 },
      "circuit_protege": "C1"
    },
    "S2": {
      "id": "S2",
      "nom": "Signal 2",
      "etat": "restrictif",
      "position": { "x": 280, "y": 180 },
      "circuit_protege": "C3"
    },
    "S3": {
      "id": "S3",
      "nom": "Signal 3",
      "etat": "restrictif",
      "position": { "x": 420, "y": 230 },
      "circuit_protege": "C5"
    }
  },
  "itineraires": {
    "I1": {
      "id": "I1",
      "nom": "Itinéraire 1",
      "etat": "detruit",
      "signal_origine": "S1",
      "signal_destination": "S3",
      "circuits": ["C1", "C2", "C3", "C5"],
      "aiguilles": {
        "A1": "normal",
        "A2": "normal"
      }
    },
    "I2": {
      "id": "I2",
      "nom": "Itinéraire 2",
      "etat": "detruit",
      "signal_origine": "S1",
      "signal_destination": "S2",
      "circuits": ["C1", "C2", "C3"],
      "aiguilles": {
        "A1": "normal"
      }
    }
  },
  "connexions": [
    { "de": "C1", "vers": "C2" },
    { "de": "C2", "vers": "A1" },
    { "de": "A1", "vers": "C3", "condition": "normal" },
    { "de": "A1", "vers": "C4", "condition": "reverse" },
    { "de": "C3", "vers": "A2" },
    { "de": "A2", "vers": "C5", "condition": "normal" },
    { "de": "A2", "vers": "C4", "condition": "reverse" }
  ]
}
Code serveur (FastAPI + WebSocket)
Code:
from fastapi import FastAPI, WebSocket, WebSocketDisconnect
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles
import json
import asyncio
from typing import List, Dict, Any
import time
from pathlib import Path

app = FastAPI()

# Configuration CORS
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# Chargement des données du réseau
with open('reseau_metro.json', 'r', encoding='utf-8') as f:
    reseau_data = json.load(f)

# État actuel du réseau
etat_reseau = {
    "circuits": reseau_data["circuits"].copy(),
    "aiguilles": reseau_data["aiguilles"].copy(),
    "signaux": reseau_data["signaux"].copy(),
    "itineraires": reseau_data["itineraires"].copy(),
    "trains": {}
}

# Gestionnaire de connexions WebSocket
class ConnectionManager:
    def __init__(self):
        self.active_connections: List[WebSocket] = []

    async def connect(self, websocket: WebSocket):
        await websocket.accept()
        self.active_connections.append(websocket)

    def disconnect(self, websocket: WebSocket):
        self.active_connections.remove(websocket)

    async def broadcast(self, message: dict):
        for connection in self.active_connections:
            try:
                await connection.send_json(message)
            except:
                pass

manager = ConnectionManager()

@app.get("/")
async def get():
    with open('index.html', 'r', encoding='utf-8') as f:
        return HTMLResponse(content=f.read())

@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
    await manager.connect(websocket)
    try:
        # Envoyer l'état initial
        await websocket.send_json({
            "type": "etat_complet",
            "data": etat_reseau
        })
        
        while True:
            data = await websocket.receive_text()
            # Garder la connexion active
    except WebSocketDisconnect:
        manager.disconnect(websocket)

@app.get("/api/etat")
async def get_etat():
    return etat_reseau

@app.post("/api/circuit/{circuit_id}/etat/{etat}")
async def update_circuit(circuit_id: str, etat: str):
    if circuit_id in etat_reseau["circuits"]:
        etat_reseau["circuits"][circuit_id]["etat"] = etat
        await manager.broadcast({
            "type": "update_circuit",
            "circuit_id": circuit_id,
            "etat": etat
        })
        # Mettre à jour les trains
        await update_trains()
    return {"status": "ok"}

@app.post("/api/aiguille/{aiguille_id}/etat/{etat}")
async def update_aiguille(aiguille_id: str, etat: str):
    if aiguille_id in etat_reseau["aiguilles"]:
        etat_reseau["aiguilles"][aiguille_id]["etat"] = etat
        await manager.broadcast({
            "type": "update_aiguille",
            "aiguille_id": aiguille_id,
            "etat": etat
        })
    return {"status": "ok"}

@app.post("/api/signal/{signal_id}/etat/{etat}")
async def update_signal(signal_id: str, etat: str):
    if signal_id in etat_reseau["signaux"]:
        etat_reseau["signaux"][signal_id]["etat"] = etat
        await manager.broadcast({
            "type": "update_signal",
            "signal_id": signal_id,
            "etat": etat
        })
    return {"status": "ok"}

@app.post("/api/itineraire/{itineraire_id}/activer")
async def activer_itineraire(itineraire_id: str):
    if itineraire_id in etat_reseau["itineraires"]:
        itineraire = etat_reseau["itineraires"][itineraire_id]
        
        # Vérifier que tous les circuits sont libres
        for circuit_id in itineraire["circuits"]:
            if etat_reseau["circuits"][circuit_id]["etat"] == "occupe":
                return {"status": "error", "message": "Circuit occupé"}
        
        # Positionner les aiguilles
        for aiguille_id, position in itineraire["aiguilles"].items():
            etat_reseau["aiguilles"][aiguille_id]["etat"] = position
        
        # Mettre le signal origine en permissif
        signal_origine = itineraire["signal_origine"]
        etat_reseau["signaux"][signal_origine]["etat"] = "permissif"
        
        # Changer l'état de l'itinéraire
        etat_reseau["itineraires"][itineraire_id]["etat"] = "forme"
        
        await manager.broadcast({
            "type": "etat_complet",
            "data": etat_reseau
        })
    
    return {"status": "ok"}

async def update_trains():
    """Détecte les trains (2 circuits consécutifs occupés)"""
    trains = {}
    connexions = reseau_data["connexions"]
    
    for conn in connexions:
        circuit1 = conn["de"]
        circuit2 = conn["vers"]
        
        # Vérifier si les deux circuits sont occupés
        if (circuit1 in etat_reseau["circuits"] and 
            circuit2 in etat_reseau["circuits"] and
            etat_reseau["circuits"][circuit1]["etat"] == "occupe" and
            etat_reseau["circuits"][circuit2]["etat"] == "occupe"):
            
            # Vérifier les conditions d'aiguillage si nécessaire
            if "condition" in conn:
                # Trouver l'aiguille concernée
                aiguille_id = circuit1 if circuit1.startswith("A") else None
                if aiguille_id and etat_reseau["aiguilles"][aiguille_id]["etat"] != conn["condition"]:
                    continue
            
            # Créer un train
            train_id = f"T_{circuit1}_{circuit2}"
            pos1 = etat_reseau["circuits"][circuit1]["position"]
            pos2 = etat_reseau["circuits"][circuit2]["position"]
            trains[train_id] = {
                "id": train_id,
                "position": {
                    "x": (pos1["x"] + pos2["x"]) / 2,
                    "y": (pos1["y"] + pos2["y"]) / 2
                },
                "circuits": [circuit1, circuit2]
            }
    
    etat_reseau["trains"] = trains
    await manager.broadcast({
        "type": "update_trains",
        "trains": trains
    })

# Simulateur de train
class TrainSimulator:
    def __init__(self):
        self.position_actuelle = 0
        self.chemin = ["C1", "C2", "C3", "C5"]  # Chemin par défaut
        self.running = False
        
    async def start(self):
        self.running = True
        while self.running:
            # Libérer l'ancien circuit
            if self.position_actuelle > 0:
                ancien_circuit = self.chemin[self.position_actuelle - 1]
                await update_circuit(ancien_circuit, "libre")
            
            # Occuper le circuit actuel et le suivant
            circuit_actuel = self.chemin[self.position_actuelle]
            await update_circuit(circuit_actuel, "occupe")
            
            if self.position_actuelle < len(self.chemin) - 1:
                circuit_suivant = self.chemin[self.position_actuelle + 1]
                await update_circuit(circuit_suivant, "occupe")
            
            # Avancer
            self.position_actuelle += 1
            if self.position_actuelle >= len(self.chemin):
                # Libérer le dernier circuit
                await update_circuit(self.chemin[-1], "libre")
                self.position_actuelle = 0
            
            await asyncio.sleep(2)  # Pause de 2 secondes
    
    def stop(self):
        self.running = False

simulator = TrainSimulator()

@app.post("/api/simulation/start")
async def start_simulation():
    asyncio.create_task(simulator.start())
    return {"status": "simulation démarrée"}

@app.post("/api/simulation/stop")
async def stop_simulation():
    simulator.stop()
    # Libérer tous les circuits
    for circuit_id in etat_reseau["circuits"]:
        await update_circuit(circuit_id, "libre")
    return {"status": "simulation arrêtée"}

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)
Interface HTML/JavaScript :
Code:
<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Réseau de Métro - Supervision</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 20px;
            background-color: #1a1a1a;
            color: #fff;
        }
        
        .container {
            max-width: 1400px;
            margin: 0 auto;
        }
        
        h1 {
            text-align: center;
            color: #4CAF50;
        }
        
        .controls {
            display: flex;
            gap: 20px;
            margin-bottom: 20px;
            flex-wrap: wrap;
        }
        
        .control-group {
            background: #2a2a2a;
            padding: 15px;
            border-radius: 8px;
            flex: 1;
            min-width: 250px;
        }
        
        .control-group h3 {
            margin-top: 0;
            color: #4CAF50;
        }
        
        button {
            background: #4CAF50;
            color: white;
            border: none;
            padding: 10px 20px;
            margin: 5px;
            border-radius: 5px;
            cursor: pointer;
            transition: background 0.3s;
        }
        
        button:hover {
            background: #45a049;
        }
        
        button.danger {
            background: #f44336;
        }
        
        button.danger:hover {
            background: #da190b;
        }
        
        #reseau-canvas {
            background: #2a2a2a;
            border: 2px solid #4CAF50;
            border-radius: 10px;
            display: block;
            margin: 0 auto;
        }
        
        .status {
            margin-top: 20px;
            padding: 10px;
            background: #2a2a2a;
            border-radius: 8px;
        }
        
        .status-item {
            display: inline-block;
            margin: 5px 10px;
            padding: 5px 10px;
            background: #3a3a3a;
            border-radius: 5px;
        }
        
        .circuit-libre { color: #4CAF50; }
        .circuit-occupe { color: #f44336; }
        .signal-permissif { color: #4CAF50; }
        .signal-restrictif { color: #f44336; }
        .aiguille-normal { color: #2196F3; }
        .aiguille-reverse { color: #FF9800; }
        
        .legend {
            display: flex;
            gap: 20px;
            margin: 20px 0;
            flex-wrap: wrap;
            justify-content: center;
        }
        
        .legend-item {
            display: flex;
            align-items: center;
            gap: 10px;
        }
        
        .legend-color {
            width: 20px;
            height: 20px;
            border-radius: 3px;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>Système de Supervision du Réseau de Métro</h1>
        
        <div class="controls">
            <div class="control-group">
                <h3>Simulation</h3>
                <button onclick="startSimulation()">▶️ Démarrer la simulation</button>
                <button onclick="stopSimulation()" class="danger">⏹️ Arrêter la simulation</button>
            </div>
            
            <div class="control-group">
                <h3>Itinéraires</h3>
                <button onclick="activerItineraire('I1')">Activer Itinéraire 1 (S1→S3)</button>
                <button onclick="activerItineraire('I2')">Activer Itinéraire 2 (S1→S2)</button>
            </div>
            
            <div class="control-group">
                <h3>Aiguilles</h3>
                <button onclick="toggleAiguille('A1')">Basculer Aiguille 1</button>
                <button onclick="toggleAiguille('A2')">Basculer Aiguille 2</button>
            </div>
        </div>
        
        <div class="legend">
            <div class="legend-item">
                <div class="legend-color" style="background: #4CAF50;"></div>
                <span>Circuit libre</span>
            </div>
            <div class="legend-item">
                <div class="legend-color" style="background: #f44336;"></div>
                <span>Circuit occupé</span>
            </div>
            <div class="legend-item">
                <div class="legend-color" style="background: #FFD700;"></div>
                <span>Train</span>
            </div>
            <div class="legend-item">
                <div class="legend-color" style="background: #2196F3;"></div>
                <span>Aiguille normale</span>
            </div>
            <div class="legend-item">
                <div class="legend-color" style="background: #FF9800;"></div>
                <span>Aiguille inversée</span>
            </div>
        </div>
        
        <canvas id="reseau-canvas" width="600" height="400"></canvas>
        
        <div class="status" id="status">
            <h3>État du réseau</h3>
            <div id="status-content"></div>
        </div>
    </div>

    <script>
        const canvas = document.getElementById('reseau-canvas');
        const ctx = canvas.getContext('2d');
        let ws = null;
        let etatReseau = null;

        // Connexion WebSocket
        function connectWebSocket() {
            ws = new WebSocket('ws://localhost:8000/ws');
            
            ws.onopen = () => {
                console.log('Connecté au serveur');
            };
            
            ws.onmessage = (event) => {
                const message = JSON.parse(event.data);
                handleMessage(message);
            };
            
            ws.onclose = () => {
                console.log('Déconnecté du serveur');
                setTimeout(connectWebSocket, 2000);
            };
        }

        function handleMessage(message) {
            switch(message.type) {
                case 'etat_complet':
                    etatReseau = message.data;
                    updateDisplay();
                    break;
                case 'update_circuit':
                    if (etatReseau) {
                        etatReseau.circuits[message.circuit_id].etat = message.etat;
                        updateDisplay();
                    }
                    break;
                case 'update_aiguille':
                    if (etatReseau) {
                        etatReseau.aiguilles[message.aiguille_id].etat = message.etat;
                        updateDisplay();
                    }
                    break;
                case 'update_signal':
                    if (etatReseau) {
                        etatReseau.signaux[message.signal_id].etat = message.etat;
                        updateDisplay();
                    }
                    break;
                case 'update_trains':
                    if (etatReseau) {
                        etatReseau.trains = message.trains;
                        updateDisplay();
                    }
                    break;
            }
        }

        function updateDisplay() {
            drawNetwork();
            updateStatus();
        }

        function drawNetwork() {
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            
            if (!etatReseau) return;
            
            // Dessiner les voies (connexions)
            ctx.strokeStyle = '#666';
            ctx.lineWidth = 3;
            
            // Connexions simples entre circuits
            drawLine('C1', 'C2');
            drawLine('C2', 'C3');
            drawLine('C3', 'C5');
            drawLine('C2', 'C4');
            drawLine('C3', 'C4');
            
            // Dessiner les circuits de voie
            for (const [id, circuit] of Object.entries(etatReseau.circuits)) {
                const color = circuit.etat === 'libre' ? '#4CAF50' : '#f44336';
                drawCircuit(circuit.position.x, circuit.position.y, id, color);
            }
            
            // Dessiner les aiguilles
            for (const [id, aiguille] of Object.entries(etatReseau.aiguilles)) {
                const color = aiguille.etat === 'normal' ? '#2196F3' : '#FF9800';
                drawAiguille(aiguille.position.x, aiguille.position.y, id, color);
            }
            
            // Dessiner les signaux
            for (const [id, signal] of Object.entries(etatReseau.signaux)) {
                const color = signal.etat === 'permissif' ? '#4CAF50' : '#f44336';
                drawSignal(signal.position.x, signal.position.y, id, color);
            }
            
            // Dessiner les trains
            for (const [id, train] of Object.entries(etatReseau.trains || {})) {
                drawTrain(train.position.x, train.position.y);
            }
        }

        function drawLine(from, to) {
            const posFrom = etatReseau.circuits[from]?.position || etatReseau.aiguilles[from]?.position;
            const posTo = etatReseau.circuits[to]?.position || etatReseau.aiguilles[to]?.position;
            
            if (posFrom && posTo) {
                ctx.beginPath();
                ctx.moveTo(posFrom.x, posFrom.y);
                ctx.lineTo(posTo.x, posTo.y);
                ctx.stroke();
            }
        }

        function drawCircuit(x, y, id, color) {
            ctx.fillStyle = color;
            ctx.fillRect(x - 20, y - 10, 40, 20);
            
            ctx.fillStyle = '#fff';
            ctx.font = '12px Arial';
            ctx.textAlign = 'center';
            ctx.fillText(id, x, y + 4);
        }

        function drawAiguille(x, y, id, color) {
            ctx.fillStyle = color;
            ctx.beginPath();
            ctx.moveTo(x, y - 15);
            ctx.lineTo(x - 15, y + 15);
            ctx.lineTo(x + 15, y + 15);
            ctx.closePath();
            ctx.fill();
            
            ctx.fillStyle = '#fff';
            ctx.font = '12px Arial';
            ctx.textAlign = 'center';
            ctx.fillText(id, x, y + 30);
        }

        function drawSignal(x, y, id, color) {
            ctx.fillStyle = color;
            ctx.beginPath();
            ctx.arc(x, y, 12, 0, 2 * Math.PI);
            ctx.fill();
            
            ctx.fillStyle = '#fff';
            ctx.font = '10px Arial';
            ctx.textAlign = 'center';
            ctx.fillText(id, x, y + 4);
        }

        function drawTrain(x, y) {
            ctx.fillStyle = '#FFD700';
            ctx.fillRect(x - 25, y - 12, 50, 24);
            
            ctx.fillStyle = '#000';
            ctx.font = '14px Arial';
            ctx.textAlign = 'center';
            ctx.fillText('��', x, y + 5);
        }

        function updateStatus() {
            if (!etatReseau) return;
            
            let html = '<div>';
            
            // Circuits
            html += '<h4>Circuits de voie:</h4>';
            for (const [id, circuit] of Object.entries(etatReseau.circuits)) {
                const className = circuit.etat === 'libre' ? 'circuit-libre' : 'circuit-occupe';
                html += `<span class="status-item ${className}">${id}: ${circuit.etat}</span>`;
            }
            
            // Aiguilles
            html += '<h4>Aiguilles:</h4>';
            for (const [id, aiguille] of Object.entries(etatReseau.aiguilles)) {
                const className = aiguille.etat === 'normal' ? 'aiguille-normal' : 'aiguille-reverse';
                html += `<span class="status-item ${className}">${id}: ${aiguille.etat}</span>`;
            }
            
            // Signaux
            html += '<h4>Signaux:</h4>';
            for (const [id, signal] of Object.entries(etatReseau.signaux)) {
                const className = signal.etat === 'permissif' ? 'signal-permissif' : 'signal-restrictif';
                html += `<span class="status-item ${className}">${id}: ${signal.etat}</span>`;
            }
            
            html += '</div>';
            document.getElementById('status-content').innerHTML = html;
        }

        // Fonctions de contrôle
        async function startSimulation() {
            const response = await fetch('/api/simulation/start', { method: 'POST' });
            console.log('Simulation démarrée');
        }

        async function stopSimulation() {
            const response = await fetch('/api/simulation/stop', { method: 'POST' });
            console.log('Simulation arrêtée');
        }

        async function activerItineraire(id) {
            const response = await fetch(`/api/itineraire/${id}/activer`, { method: 'POST' });
            console.log(`Itinéraire ${id} activé`);
        }

        async function toggleAiguille(id) {
            if (!etatReseau) return;
            const nouvelEtat = etatReseau.aiguilles[id].etat === 'normal' ? 'reverse' : 'normal';
            const response = await fetch(`/api/aiguille/${id}/etat/${nouvelEtat}`, { method: 'POST' });
            console.log(`Aiguille ${id} basculée en ${nouvelEtat}`);
        }

        // Initialisation
        connectWebSocket();
    </script>
</body>
</html>
instructions d'installation et d'utilisation :
Code:
Système de Supervision du Réseau de Métro


Prérequis




Python 3.8+


pip (gestionnaire de paquets Python)




Installation




Créer un nouveau dossier pour le projet




mkdir metro-supervision
cd metro-supervision





Créer les fichiers nécessaires




Créez les trois fichiers suivants dans le dossier :




reseau_metro.json
 (copier le contenu de l'artifact "Modèle de données")


main.py
 (copier le contenu de l'artifact "Serveur FastAPI")


index.html
 (copier le contenu de l'artifact "Interface web")






Installer les dépendances Python




pip install fastapi uvicorn websockets



Lancement




Démarrer le serveur




python main.py



Le serveur démarrera sur 
http://localhost:8000




Ouvrir l'interface web




Ouvrez votre navigateur et accédez à : 
http://localhost:8000


Utilisation


Interface principale


L'interface affiche :




Le réseau de voies : circuits (rectangles), aiguilles (triangles), signaux (cercles)


Les états en temps réel :



Circuits : vert (libre) ou rouge (occupé)


Aiguilles : bleu (position normale) ou orange (position inversée)


Signaux : vert (permissif) ou rouge (restrictif)






Les trains : rectangles jaunes avec emoji ��




Commandes disponibles






Simulation automatique




Démarrer la simulation
 : Un train parcourt automatiquement le réseau


Arrêter la simulation
 : Arrête le train et libère tous les circuits








Gestion des itinéraires




Activer Itinéraire 1
 : Configure le chemin S1→S3 (via C1-C2-C3-C5)


Activer Itinéraire 2
 : Configure le chemin S1→S2 (via C1-C2-C3)








Contrôle manuel des aiguilles




Basculer Aiguille 1
 : Change la position de l'aiguille A1


Basculer Aiguille 2
 : Change la position de l'aiguille A2








Logique du système






Détection des trains




Un train apparaît automatiquement quand 2 circuits consécutifs sont occupés


Le train est positionné entre les deux circuits








Itinéraires




Un itinéraire réserve un chemin complet avec :



Vérification que tous les circuits sont libres


Positionnement automatique des aiguilles


Signal origine mis en permissif


État de l'itinéraire : détruit → enregistré → formé












Simulation




Le train se déplace de circuit en circuit


Occupe 2 circuits à la fois (position actuelle et suivante)


Libère automatiquement les circuits derrière lui


Boucle sur le parcours (retour au début à la fin)








Structure du réseau


Le réseau exemple comprend :




5 circuits de voie (C1 à C5) formant une voie avec embranchement


2 aiguilles (A1, A2) permettant de choisir le chemin


3 signaux (S1, S2, S3) protégeant les zones


2 itinéraires prédéfinis pour la circulation




S1 → C1 → C2 → A1 → C3 → A2 → C5 → S3
                ↓        ↓
                C4 ←------┘
                ↓
                S2



API REST disponible


Le serveur expose les endpoints suivants :




GET /api/etat
 : Obtenir l'état complet du réseau


POST /api/circuit/{id}/etat/{libre|occupe}
 : Modifier l'état d'un circuit


POST /api/aiguille/{id}/etat/{normal|reverse}
 : Modifier l'état d'une aiguille


POST /api/signal/{id}/etat/{permissif|restrictif}
 : Modifier l'état d'un signal


POST /api/itineraire/{id}/activer
 : Activer un itinéraire


POST /api/simulation/start
 : Démarrer la simulation


POST /api/simulation/stop
 : Arrêter la simulation




WebSocket


L'interface utilise une connexion WebSocket (
ws://localhost:8000/ws
) pour recevoir les mises à jour en temps réel :




etat_complet
 : État complet du réseau


update_circuit
 : Mise à jour d'un circuit


update_aiguille
 : Mise à jour d'une aiguille


update_signal
 : Mise à jour d'un signal


update_trains
 : Mise à jour de la position des trains




Personnalisation


Pour modifier le réseau :




Éditez le fichier 
reseau_metro.json


Ajoutez/modifiez les circuits, aiguilles, signaux et itinéraires


Mettez à jour les connexions pour définir la topologie


Ajustez les positions (x, y) pour l'affichage




Dépannage




Le serveur ne démarre pas : Vérifiez que le port 8000 est libre


L'interface ne se charge pas : Vérifiez que les 3 fichiers sont dans le même dossier


La simulation ne fonctionne pas : Actualisez la page et reconnectez-vous au WebSocket
qu'en penses tu ?

Non


Pour le Tetris je continuerai ce soir.

Dernière modification par Tonton Jack ; 30/05/2025 à 14h58.
Citation :
Publié par Ron Jack Auboulot
L'IA a a créé ce petit jeu 3D avec moi en mode balec qui est parti d'un prompt de 2 lignes. y a quelques bugs mineurs qui se règlent en 1 prompt d'une ligne à chaque fois, et encore le coup des textures qui changent et des blocs qui décalent sils sont contre une bord quand on pivote, ce ne sont pas des bugs, juste des choses à préciser.

T'es tellement blasé du truc que tu vas louper non pas le wagon mais le train entier. Ta remarque sur "ce sont juste des algos", "ça n'invente rien" démontrent que t'es resté coincé à quelques années maintenant en arrière. Tu te trompes sur Claude.
Un étudiant fait ça aussi vite en 1 ligne d'énoncé (et on aura pas besoin de 3 versions).
Non ça n'invente rien. Ça apprends et repompe très vite ce que la machine a engranger comme infos.
Ah et non je ne suis pas blasé. Juste que t'es pas dev, ta aucune idée de l'arrière d'une grosse appli. Rien que la sécurité, les IA c'est dans les chou. Je suis repassé sur pas mal de merde générer par IA... D'ailleurs dans tes exemples y'a jamais le code back qu'on rigole. Rien que la calculette j'aurais aimé voir, je suis sur que y'a des failles de sécurité énormes... Les LLM sont magnifique pour centrer un texte en HTML mais c'est tout. Ca peu aidé le junior sur une questions mais rien de plus.
Citation :
Publié par Axoulotl08
Je suis repassé sur pas mal de merde générer par IA...
Oui oui, t'es certainement repassé sur du Claude 4 Opus qui est sorti il y a 8 jours, tu sais donc déjà ce qu'il sort comme code, n'est-ce pas ?
Citation :
Publié par Ron Jack Auboulot
Oui oui, t'es certainement repassé sur du Claude 4 Opus qui est sorti il y a 8 jours, tu sais donc déjà ce qu'il sort comme code, n'est-ce pas ?
Aucune idée, mais je suis certaine que ça sera pas mieux qu'avant...
Citation :
Publié par Ron Jack Auboulot
Oui oui, t'es certainement repassé sur du Claude 4 Opus qui est sorti il y a 8 jours, tu sais donc déjà ce qu'il sort comme code, n'est-ce pas ?
Sortie il y'a 8 jours et utilise une version dépréciée de node, c'est rassurant en effet :/
Citation :
Publié par Dr. Troy
à l'inverse les outils d'Adobe eux ont du sens (détourage, generative fill, ...).
Bordel j'adorerais pouvoir utiliser cette fonction... Elle est bluffante, et permets vraiment de créer une image avec ici ou là des pièces de puzzles rapportées. Du reste, leur génération est meilleur que les IA les plus connues. Clairement. Je fais parfois de la génération d'images via ChatGPT ou Gemini, et franchement, on est souvent déçu. Pire, quand tu veux reformuler une itération, même si tu stipules de conserver tel et tel éléments, l'IA s'en contrefout, et tu te retrouves à difficilement avancer parfois. En fait c'est un peu la loterie. Parfois elle te sortira un truc inattendu avec des détails pas mêmes "promptés", et d'autres fois, ce que tu mets dans ton prompt n'est pas le moins du monde respecté. Les LLM ont encore beaucoup de progrès à faire pour appréhender les concepts.
Citation :
Publié par Airmed / Ildefonse
C'est surtout qu'elle ne passe pas le test de base d'une calculette
En ayant des attentes beaucoup plus raisonnables. Combien de temps il faut compter à un dev pour structurer quelque chose d'équivalent à ce qu'a donné le LLM ?
Créer les fichiers, les nommer, mettre quelques variables, api, fonctions etc. Est-ce plus efficient et ou qualitatif qu'un dev sur un IDE dopé avec des outils de complétions/autres ?
Citation :
Publié par kéwa
En ayant des attentes beaucoup plus raisonnables. Combien de temps il faut compter à un dev pour structurer quelque chose d'équivalent à ce qu'a donné le LLM ?
Le problème c'est pas d'avoir des attentes raisonnables. Le problème c'est d'avoir un programme qui fonctionne sans bug majeur
Citation :
Publié par Jet
c'est pour Alstom ou Siemens ?

c'est compatible ERTMS de niveau 3 ?
C'est de l'urbain, il n'y a pas d'ertms. Et c'est de la techno du 19eme pour le moment vu ce que j'ai demandé


@Ron_Jack_Auboulot je regarde plus tard.

Je serais indulgent car il y a bcp de métier derrière.
Le prompt du 2 semble foireux mais c'est pas grave pour cette itération.

Dernière modification par Ex-voto ; 30/05/2025 à 21h06.
Citation :
Publié par Airmed / Ildefonse
Le problème c'est pas d'avoir des attentes raisonnables. Le problème c'est d'avoir un programme qui fonctionne sans bug majeur
Et qui peu être amélioré sans devoir casser tout le code après avoir passé 2 jours à comprendre le code de l'IA.
Citation :
Publié par Touful Khan
Vous vous prenez la tête pour rien.
Le Tetris ne fonctionne pas. Poubelle, fin du match.
"Le Tetris ne marche pas" :

https://claude.ai/public/artifacts/c...5-1244619a835d

J'ai éliminé les rotations des points de fuites, qui étaient déjà démontrées dans les versions précédentes mais qui ne servent à rien. On peut les remettre si besoin, mais je ne vois pas l'intérêt.

Faut réaliser qu'en tout et pour tout, pour obtenir ça, j'ai utilisé quelques prompts, suite aux remarques de Airmed.
Il aurait été à côté de moi, on obtenait ça en moins de 10 minutes.

Imaginez que nous passions une journée dessus, à demander des trucs spécifiques...
Citation :
Publié par Ron Jack Auboulot
"Le Tetris ne marche pas" :

https://claude.ai/public/artifacts/c...5-1244619a835d

J'ai éliminé les rotations des points de fuites, qui étaient déjà démontrées dans les versions précédentes mais qui ne servent à rien. On peut les remettre si besoin, mais je ne vois pas l'intérêt.

Faut réaliser qu'en tout et pour tout, pour obtenir ça, j'ai utilisé quelques prompts, suite aux remarques de Airmed.
La rotation de la barre n'est toujours pas bonne (les autres aussi, mais c'est particulèrement visible sur la barre). Cela serait peut etre bien que tu test tes versions avant de les balancer.

Mais ce qui est rigolo, c'est que maintenant qu'il respect les nombres, on peut voir le code dégueulasse derriere. Ensuite, en pratique, l'essentiel c'est que ca marche on va dire.
D'ailleurs dans le jeu original, il y a rotation dans les deux sens

Pour l'histoire de comment il gère la rotation :
Cliquez ce bouton ou survolez le contenu pour afficher le spoiler

En faite il n'y a pas de gestion globale de rotation, cela se voit avec le cube qui ne tourne pas. Ce qui induit qu'il ne vaut mieux pas voir le code.

Pour revenir à ton histoire que "on serait à côté, cela serait super rapide" la réponse est double. D'une part si je suis dev, cela n'a aucun interet, l'IA est sensé remplacer mon poste. D'autre part, contrairement à un vrai développement, des bugs ne peuvent pas réapparaitre, la correction des bugs précédents fait qu'il ne peut pas y avoir de nouveau bugs. Sur programme aussi simple, evidemment.

Dernière modification par Airmed / Ildefonse ; 31/05/2025 à 09h37.
Citation :
Publié par Airmed / Ildefonse
La rotation de la barre n'est toujours pas bonne.
Jai testé, je ne vois pas de problème avec la rotation de la barre

Est-ce une règle ou un bug réel ? Je l'ai testée, contre un bord elle ne décale pas.

Contre le bord droit elle est bloquée, contre le bord gauche elle peut, ce qui est logique puisqu'elle tourne toujours dans le même sens.

C'est valable pour d'autres pièces, elles peuvent pivoter sur un bord et/ou pas l'autre.

Quel est selon toi le problème de la rotation de la barre ?
Les rotations se font par le centre des pièces. Pas par un point au pif.
Qui plus est, elles peuvent tourner dans les deux sens.

Ensuite faudrait revoir pour la barre dans le jeu originel, j'ai un doute qu'il y a 4 positions.

Et le système d'une couleur par carre ne fonctionne toujours pas.
Citation :
Publié par Airmed / Ildefonse
Les rotations se font par le centre des pièces. Pas par un point au pif.
Mais à quel moment tu avais précisé ceci ?

Effectivement, la rotation de la barre se fait par son bloc à l'extrémité haute.

C'est pas un bug ça.

Tu reproches à l'IA de ne pas respecter un cahier des charges que tu n'as absolument pas défini.

Cest la démonstration de ce que je disais : tout dépend du prompt initial.

Demain si je demande un monopoly like, le résultat sera bien meilleur si j'ai documenté l'ensemble des règles dans un document au lieu d'un simple prompt :

Citation :
Fais moi un monopoly mais avec les rues de Rouen
Si au lieu de ça je lui fourni des informations précises, de la doc, des images, des règles, le plan des rues de Rouen, les prix au m2 par rue etc le résultat n'aura rien à voir.

La rotation de la barre n'est pas un bug. Cest juste que si toutes les pièces doivent avoir une rotation par le centre, cest juste une instruction de quelques mots.
Citation :
Publié par Ron Jack Auboulot
Tu reproches à l'IA de ne pas respecter un cahier des charges que tu n'as absolument pas défini.
Le cahier des charges c'était "fait un tétris". Et dans tétris, la barre (et les autres pièces) ne tourne pas comme cela. Doit y avoir des millions de référence sur les règles de fonctionnement de tétris, l'IA est sensée les trouver facilement.
Je pense pour le coup qu'il est difficile de faire plus précis. Doit y avoir des tétris dans tous les langages existants, respectant normalement la même norme.

Et si c'est un bug, car cela limite énormément le game play. C'est impossible de placer la barre dans un emplacement vide horizontal en passant par la droite. Ce qui avec une vrai rotation est possible. Par contre, cela va etre possible en passant par la gauche sur un emplacement de 3 vide, ce qui n'est pas autorisé dans le jeu original.

Exemple :
Code:
Tu as :
    O |
xxxxO |
xx  O |
xxxxO |
-------
Tu peux faire ça par rotation direct de la pièce (ici la barre) :

xxxx  |
xxOOOO|
xxxx  |
-------
Avec ta rotation, cela donne ça et ne permet pas de placer la pièce à cause de la vitesse de descente :
xxxx
xx  OOOO
xxxx
Citation :
Cest la démonstration de ce que je disais : tout dépend du prompt initial.
Et c'est ce que plusieurs personnes t'ont répété, cela donne un résultat à peu pret aléatoire qui au final n'est pas acceptable.
Pour ton monopoly, les problèmes seront exactement les même qu'avec le tétris. Cela va être aléatoirement à peu prêt.

---------

Faut bien comprendre que pour ma part, des tétris j'en ai fait sous plusieurs langages quand j'étais plus jeune, donc je connais bien le fonctionnement. Si je dis à l'IA exactement toutes les étapes de développement et de fonctionnement du tétris, on se retrouve dans le cas que citait Dr Troy, à savoir au mieux un support de dev. Mais on n'est pas du tout dans le cas de figure que toi tu cherches à démontrer.
Et effectivement, j'ai utilisé chatGPT3 pour m'aider dans la conception d'une musique sous arduino car c'était plus rapide que de convertire les notes d'une partition en fréquence. ChatGPT m'a fournit directement une matrice avec les fréquences des notes. C'était en partie faux, et j'ai du apporter des moditications, mais au final, il y a eu gain de temps.

Dernière modification par Airmed / Ildefonse ; 31/05/2025 à 10h15.
Citation :
Publié par Airmed / Ildefonse
Le cahier des charges c'était "fait un tétris".

une recherche google :
Citation :
Comment les pièces tournent-elles dans Tetris ?
réponse :
Citation :
La rotation proprement dite s'effectue en modifiant la liste bidimensionnelle de booléens représentant la pièce qui tombe . Une nouvelle liste bidimensionnelle est créée, et les cellules de l'ancienne liste sont mappées sur celles de la nouvelle liste selon une rotation de 90 degrés dans le sens inverse des aiguilles d'une montre.
J'ai aucune idée de si l'IA fait bien ça en booléen et tout, mais les pièces tournent. En tout cas la rotation par le centre, c'est juste un truc arbitraire.

Doit y avoir 12000 tetris différents avec des centaines de variantes de rotation.

Tout ça pour persister dans ton "l'IA est incapable".

Vu ta mauvaise foi, je vais arrêter avec Tetris et m'attaquer cet aprem au défi de@Malkav qui semble vachement plus pertinent pour tester les limites de l'IA.
Citation :
Publié par Ron Jack Auboulot
J'ai aucune idée de si l'IA fait bien ça en booléen et tout, mais les pièces tournent. En tout cas la rotation par le centre, c'est juste un truc arbitraire.
Elle le fait pas, c'est visible sur toutes les pièces. Donc bon, si tu inventes de nouvelles règles au motif que le prompt n'est pas précis ...
Tu peux arguer que la position de départ dans la matrice se fait comme on veut. Pourquoi pas, mais à un moment donné cela donne un gameplay non conforme. Car si la barre est centrée, en dehors du faite que c'est logique, c'est bien qu'il y a une raison, cf mon exemple du dessus. Dans ta version, cela donne une imprévisibilité de la rotation (hormis le carré).

Et le prompt d'une couleur différente par carré ne fonctionne toujours pas.

Tétris, c'est vraiment une norme à part entière. Mais disons qu'il n'y a pas de norme, cela n'explique pas pourquoi le carré est centré et pas les autres pièces C'est pas logique

(je passe sur le "booléen et tout" qui prouve que t'y piges que dalle Surtout que ici, c'est pas booléen)
RonJ ta mauvaise foie est pathologique.

Tu dis que les IA remplacent 90% des codeurs et elle n'est pas capable de comprendre des demandes aussi simple que pic1 != pic2. Et ça n'est que l'exemple le plus simple. Bilan t'as un programme inutilisable, sur lequel il faudrait passer autant de temps à le corriger (voire plus) que de repartir de zéro.

On te dit que non ça ne peut pas gérer un projet même aussi simple sans y passer plus de temps qu'un dev classique (si tu n'étais pas au courant, même sans IA un dev ne tape pas tout à la main), mais que oui ça aide comme outils.

Ajouter à ça ton incompréhension et la projection de tes fantasmes sur le fonctionnement d'un LLM, je trouvais ça marrant mais tu me fatigues avec ton charlatanisme.

Monte donc des dossiers pour vendre des jus aux électrolytes et autres bullshits jobs, la ça fera surement illusion.
Citation :
Publié par Dr. Troy
RonJ ta mauvaise foie est pathologique.
C'est la même sur le libéralisme.

Le plus gros enfumage de RonJ reste quand même le :


Citation :
Publié par Ron Jack Auboulot
Faut réaliser qu'en tout et pour tout, pour obtenir ça, j'ai utilisé quelques prompts, suite aux remarques de Airmed.
Il aurait été à côté de moi, on obtenait ça en moins de 10 minutes.
Si effectivement il suffisait d'un prompt et que c'était aussi rapide. Pendant le temps qu'il tape sur JoL il aurait pu demander à l'IA de modifier en fonction des commentaires et donner une nouvelle version.
Bizarrement, ce n'est pas le cas.


Citation :
Publié par Ron Jack Auboulot
Vu ta mauvaise foi, je vais arrêter avec Tetris et m'attaquer cet aprem au défi de@Malkav qui semble vachement plus pertinent pour tester les limites de l'IA.
Je lui souhaite bonne chance, déjà que la calculette a un bug standard qu'elle ne gère pas, j'ose pas imaginer le résultat
Répondre

Connectés sur ce fil

 
1 connecté (0 membre et 1 invité) Afficher la liste détaillée des connectés