``` ╔══════════════════════════════════════════════════════════════════════════╗ ║ HARVESTER AI - COMPARAISON AVANT/APRÈS ║ ╚══════════════════════════════════════════════════════════════════════════╝ ═══════════════════════════════════════════════════════════════════════════ ❌ AVANT CORRECTION - Harvester reste immobile ═══════════════════════════════════════════════════════════════════════════ ┌─────────────────┐ │ HQ (Spawn) │ │ Position: │ │ (200, 200) │ └────────┬────────┘ │ Produit Harvester ↓ ┌─────────────────────────────────────────┐ │ Harvester spawné │ │ ├─ cargo = 0 │ │ ├─ gathering = False │ │ ├─ returning = False │ │ ├─ ore_target = None │ │ └─ target = (220, 220) [RÉSIDUEL!] ❌ │ └────────┬────────────────────────────────┘ │ ↓ Tick 1: update_harvester() │ ┌────────▼────────────────────────────────┐ │ Condition de recherche minerai: │ │ if not gathering AND not target: │ │ │ │ not False = True ✓ │ │ not (220,220) = False ❌ │ │ │ │ True AND False = FALSE ❌ │ └────────┬────────────────────────────────┘ │ ↓ find_nearest_ore() JAMAIS APPELÉ │ ┌────────▼────────────────────────────────┐ │ Harvester reste IMMOBILE │ │ ├─ ore_target = None │ │ ├─ gathering = False │ │ └─ target = (220, 220) [BLOQUÉ] │ └─────────────────────────────────────────┘ │ ↓ Ticks 2, 3, 4, 5...∞ │ 🔴 RESTE IMMOBILE INDÉFINIMENT ═══════════════════════════════════════════════════════════════════════════ ✅ APRÈS CORRECTION - Harvester cherche automatiquement ═══════════════════════════════════════════════════════════════════════════ ┌─────────────────┐ │ HQ (Spawn) │ │ Position: │ │ (200, 200) │ └────────┬────────┘ │ Produit Harvester ↓ ┌─────────────────────────────────────────┐ │ Harvester spawné │ │ ├─ cargo = 0 │ │ ├─ gathering = False │ │ ├─ returning = False │ │ ├─ ore_target = None │ │ └─ target = (220, 220) [IGNORÉ] ✓ │ └────────┬────────────────────────────────┘ │ ↓ Tick 1: update_harvester() │ ┌────────▼────────────────────────────────┐ │ Condition de recherche minerai: │ │ if not gathering AND not ore_target: │ │ │ │ not False = True ✓ │ │ not None = True ✓ │ │ │ │ True AND True = TRUE ✅ │ └────────┬────────────────────────────────┘ │ ↓ find_nearest_ore() APPELÉ │ ┌────────▼────────────────────────────────┐ │ Minerai trouvé! │ │ nearest_ore = Position(1200, 800) │ └────────┬────────────────────────────────┘ │ ↓ Assignation automatique │ ┌────────▼────────────────────────────────┐ │ Harvester activé │ │ ├─ ore_target = (1200, 800) ✅ │ │ ├─ gathering = True ✅ │ │ └─ target = (1200, 800) ✅ │ └────────┬────────────────────────────────┘ │ ↓ Ticks 2-50: Mouvement automatique │ ┌────────▼────────────────────────────────┐ │ 🚜 Harvester SE DÉPLACE │ │ Position: (200,200) → (400,300) → │ │ (600,400) → (800,500) → │ │ (1000,600) → (1200,800) ✓ │ └────────┬────────────────────────────────┘ │ ↓ Distance < 20px │ ┌────────▼────────────────────────────────┐ │ Récolte automatique │ │ ├─ cargo += 50 (ORE) ou +100 (GEM) │ │ ├─ terrain[y][x] = GRASS │ │ └─ ore_target = None │ └────────┬────────────────────────────────┘ │ ↓ cargo < 180? │ ┌──┴───┐ │ │ OUI ↓ ↓ NON (cargo ≥ 180) │ │ Cherche Retourne dépôt nouveau returning = True minerai (Retour Tick 1) ↓ Dépose au HQ/Refinery credits += cargo cargo = 0 target = None ✅ ↓ Retour Tick 1 (Cherche automatiquement) 🟢 CYCLE AUTOMATIQUE INFINI ✅ ═══════════════════════════════════════════════════════════════════════════ 📊 TABLEAU COMPARATIF ═══════════════════════════════════════════════════════════════════════════ ┌─────────────────────┬─────────────────┬─────────────────────┐ │ Étape │ AVANT (❌) │ APRÈS (✅) │ ├─────────────────────┼─────────────────┼─────────────────────┤ │ Spawn depuis HQ │ target résiduel │ target résiduel │ │ │ │ (mais IGNORÉ) │ ├─────────────────────┼─────────────────┼─────────────────────┤ │ Condition check │ not target │ not ore_target │ │ │ = False ❌ │ = True ✅ │ ├─────────────────────┼─────────────────┼─────────────────────┤ │ find_nearest_ore() │ JAMAIS appelé │ Appelé Tick 1 │ ├─────────────────────┼─────────────────┼─────────────────────┤ │ ore_target assigné │ Non (None) │ Oui (1200, 800) │ ├─────────────────────┼─────────────────┼─────────────────────┤ │ gathering activé │ Non (False) │ Oui (True) │ ├─────────────────────┼─────────────────┼─────────────────────┤ │ Mouvement │ Immobile │ Bouge vers minerai │ ├─────────────────────┼─────────────────┼─────────────────────┤ │ Récolte │ Non (bloqué) │ Oui (automatique) │ ├─────────────────────┼─────────────────┼─────────────────────┤ │ Cycle complet │ Non (bloqué) │ Oui (infini) │ └─────────────────────┴─────────────────┴─────────────────────┘ ═══════════════════════════════════════════════════════════════════════════ 🔧 CORRECTIONS APPORTÉES (Code) ═══════════════════════════════════════════════════════════════════════════ Ligne 530 - Nettoyage après dépôt: ────────────────────────────────────────── AVANT: self.game_state.players[unit.player_id].credits += unit.cargo unit.cargo = 0 unit.returning = False unit.gathering = False unit.ore_target = None # target pas nettoyé ❌ APRÈS: self.game_state.players[unit.player_id].credits += unit.cargo unit.cargo = 0 unit.returning = False unit.gathering = False unit.ore_target = None unit.target = None # ✅ AJOUTÉ Lignes 571-577 - Condition de recherche: ────────────────────────────────────────── AVANT: if not unit.gathering and not unit.target: # ❌ Vérifie target nearest_ore = self.find_nearest_ore(unit.position) if nearest_ore: unit.ore_target = nearest_ore unit.gathering = True unit.target = nearest_ore APRÈS: if not unit.gathering and not unit.ore_target: # ✅ Vérifie ore_target nearest_ore = self.find_nearest_ore(unit.position) if nearest_ore: unit.ore_target = nearest_ore unit.gathering = True unit.target = nearest_ore elif unit.target: # ✅ AJOUTÉ unit.target = None # Nettoie résiduel si pas de minerai ═══════════════════════════════════════════════════════════════════════════ 🎯 RÉSULTAT FINAL ═══════════════════════════════════════════════════════════════════════════ Le Harvester fonctionne maintenant comme dans Red Alert classique: ✅ Sort du HQ automatiquement ✅ Cherche le minerai le plus proche ✅ Se déplace vers le minerai automatiquement ✅ Récolte automatiquement (ORE +50, GEM +100) ✅ Retourne au dépôt (HQ ou Refinery) automatiquement ✅ Dépose les crédits automatiquement ✅ Recommence le cycle automatiquement ✅ Continue indéfiniment jusqu'à épuisement des ressources "The Harvester must flow... and now it does!" 🚜💰✨ ```