#!/usr/bin/env python3 """ Test du comportement IA du Harvester Vérifie que le Harvester cherche automatiquement les ressources après spawn """ import sys import json import time import requests API_URL = "http://localhost:7860" def test_harvester_auto_collect(): """Test que le Harvester commence automatiquement à collecter""" print("\n" + "="*80) print("🧪 TEST: Harvester Auto-Collection AI") print("="*80) # 1. Get initial state print("\n📊 1. État initial...") resp = requests.get(f"{API_URL}/health") if resp.status_code != 200: print("❌ Serveur non accessible") return False data = resp.json() initial_units = len(data.get('units', [])) initial_credits_p0 = data.get('players', [{}])[0].get('credits', 0) print(f" Units initiaux: {initial_units}") print(f" Crédits Joueur 0: {initial_credits_p0}") # 2. Build a Harvester from HQ print("\n🏗️ 2. Construction d'un Harvester depuis HQ...") # Assuming player 0 has HQ at position (5*40, 5*40) = (200, 200) build_resp = requests.post(f"{API_URL}/ws", json={ "action": "build_unit", "player_id": 0, "unit_type": "harvester" }) # Wait for production (assume instant for test) time.sleep(2) # 3. Check Harvester created print("\n🔍 3. Vérification du Harvester créé...") resp = requests.get(f"{API_URL}/health") data = resp.json() current_units = len(data.get('units', [])) harvesters = [u for u in data.get('units', []) if u.get('type') == 'harvester'] print(f" Units actuels: {current_units}") print(f" Harvesters trouvés: {len(harvesters)}") if len(harvesters) == 0: print("❌ Aucun Harvester trouvé") print(" Vérifiez que le HQ peut produire des Harvesters") print(" Vérifiez que vous avez ≥200 crédits") return False # 4. Monitor Harvester behavior for 10 seconds print("\n👀 4. Surveillance du comportement (10 secondes)...") harvester = harvesters[0] harvester_id = harvester.get('id') initial_pos = harvester.get('position', {}) print(f" Harvester ID: {harvester_id}") print(f" Position initiale: ({initial_pos.get('x', 0):.1f}, {initial_pos.get('y', 0):.1f})") print(f" État: gathering={harvester.get('gathering')}, returning={harvester.get('returning')}, cargo={harvester.get('cargo')}") movements = [] for i in range(10): time.sleep(1) resp = requests.get(f"{API_URL}/health") data = resp.json() harvesters = [u for u in data.get('units', []) if u.get('id') == harvester_id] if not harvesters: print(f"\n ❌ Tick {i+1}: Harvester disparu!") return False h = harvesters[0] pos = h.get('position', {}) target = h.get('target') ore_target = h.get('ore_target') gathering = h.get('gathering') returning = h.get('returning') cargo = h.get('cargo') # Calculate distance moved dist = ((pos.get('x', 0) - initial_pos.get('x', 0))**2 + (pos.get('y', 0) - initial_pos.get('y', 0))**2)**0.5 movements.append({ 'tick': i+1, 'position': pos, 'distance': dist, 'target': target, 'ore_target': ore_target, 'gathering': gathering, 'returning': returning, 'cargo': cargo }) status = f" 📍 Tick {i+1}: pos=({pos.get('x', 0):.1f},{pos.get('y', 0):.1f}) dist={dist:.1f}px" if gathering: status += " 🔍GATHERING" if ore_target: status += f" 🎯ORE_TARGET=({ore_target.get('x', 0):.0f},{ore_target.get('y', 0):.0f})" if returning: status += " 🔙RETURNING" if cargo > 0: status += f" 💰cargo={cargo}" if target: status += f" ➡️target=({target.get('x', 0):.0f},{target.get('y', 0):.0f})" print(status) # 5. Analysis print("\n📊 5. Analyse du comportement...") # Check if moved final_dist = movements[-1]['distance'] if final_dist < 10: print(f" ❌ ÉCHEC: Harvester n'a pas bougé (distance={final_dist:.1f}px)") print(" 🐛 Problème: L'IA ne démarre pas automatiquement") return False else: print(f" ✅ Harvester a bougé: {final_dist:.1f}px") # Check if gathering flag set gathering_ticks = sum(1 for m in movements if m['gathering']) if gathering_ticks > 0: print(f" ✅ Mode GATHERING activé ({gathering_ticks}/10 ticks)") else: print(f" ⚠️ Mode GATHERING jamais activé") # Check if ore target found ore_target_ticks = sum(1 for m in movements if m['ore_target']) if ore_target_ticks > 0: print(f" ✅ ORE_TARGET trouvé ({ore_target_ticks}/10 ticks)") else: print(f" ❌ ORE_TARGET jamais trouvé") print(" 🐛 Problème: find_nearest_ore() ne trouve rien ou n'est pas appelé") return False # Check if moving toward target target_ticks = sum(1 for m in movements if m['target']) if target_ticks > 0: print(f" ✅ TARGET assigné ({target_ticks}/10 ticks)") else: print(f" ⚠️ TARGET jamais assigné") # Success criteria: moved AND found ore target if final_dist > 10 and ore_target_ticks > 0: print("\n✅ TEST RÉUSSI: Harvester cherche automatiquement les ressources!") return True else: print("\n❌ TEST ÉCHOUÉ: Harvester ne fonctionne pas correctement") return False def show_terrain_info(): """Affiche les informations du terrain""" print("\n" + "="*80) print("🌍 TERRAIN: Vérification des ressources disponibles") print("="*80) resp = requests.get(f"{API_URL}/health") if resp.status_code != 200: print("❌ Serveur non accessible") return data = resp.json() terrain = data.get('terrain', []) if not terrain: print("❌ Pas de données terrain") return # Count terrain types ore_count = 0 gem_count = 0 water_count = 0 grass_count = 0 ore_positions = [] gem_positions = [] for y, row in enumerate(terrain): for x, cell in enumerate(row): if cell == 'ore': ore_count += 1 ore_positions.append((x, y)) elif cell == 'gem': gem_count += 1 gem_positions.append((x, y)) elif cell == 'water': water_count += 1 elif cell == 'grass': grass_count += 1 print(f"\n📊 Statistiques terrain:") print(f" 🟩 GRASS: {grass_count} tiles") print(f" 🟨 ORE: {ore_count} tiles") print(f" 💎 GEM: {gem_count} tiles") print(f" 🟦 WATER: {water_count} tiles") print(f" 📏 Total: {len(terrain) * len(terrain[0])} tiles") if ore_count + gem_count == 0: print("\n❌ PROBLÈME CRITIQUE: Aucune ressource sur la carte!") print(" Le Harvester ne peut rien collecter.") return print(f"\n✅ {ore_count + gem_count} ressources disponibles") # Show first 5 ore positions if ore_positions: print(f"\n🟨 Premiers patches ORE (max 5):") for i, (x, y) in enumerate(ore_positions[:5]): px = x * 40 + 20 py = y * 40 + 20 print(f" {i+1}. Tile ({x},{y}) → Position ({px},{py})px") if gem_positions: print(f"\n💎 Premiers patches GEM (max 5):") for i, (x, y) in enumerate(gem_positions[:5]): px = x * 40 + 20 py = y * 40 + 20 print(f" {i+1}. Tile ({x},{y}) → Position ({px},{py})px") if __name__ == "__main__": print("\n" + "="*80) print("🚜 HARVESTER AI TEST SUITE") print("="*80) print("\n⚠️ Assurez-vous que le serveur tourne sur http://localhost:7860") print(" (docker run ou python web/app.py)") input("\nAppuyez sur Entrée pour continuer...") # First check terrain show_terrain_info() # Then test Harvester AI print("\n") input("Appuyez sur Entrée pour lancer le test Harvester...") success = test_harvester_auto_collect() print("\n" + "="*80) if success: print("✅ TOUS LES TESTS RÉUSSIS") print("="*80) sys.exit(0) else: print("❌ TESTS ÉCHOUÉS") print("="*80) sys.exit(1)