import numpy as np
from sklearn.preprocessing import MinMaxScaler
import logging
import traceback
from pathlib import Path
from main import MapGenerator
import xml.etree.ElementTree as ET

class AIMapController:
    def __init__(self):
        self.logger = logging.getLogger(__name__)
        self.scaler = MinMaxScaler()
        
        # Parameters for different entity types
        self.params = {
            'enemy_density': 0.15,  # Enemies per tile area
            'police_density': 0.08,  # Police per tile area
            'worker_density': 0.2,   # Workers per tile area
            'trap_density': 0.1,     # Traps per tile area
            'min_distance': 100,     # Minimum distance between entities
            'view_range': {
                'enemy': 200,
                'police': 250,
                'worker': 150,
                'boss': 400
            }
        }

    def generate_map(self, map_path, difficulty=0.5):
        """Generate a complete map with AI-controlled placement"""
        try:
            self.logger.info(f"Starting AI map generation with difficulty {difficulty}")
            
            # Initialize map generator
            generator = MapGenerator(map_path)
            
            # Analyze map structure
            map_data = self._analyze_map(map_path)
            
            # Adjust parameters based on difficulty
            self._adjust_parameters(difficulty)
            
            # Generate entity positions
            positions = self._generate_positions(map_data)
            
            # Apply positions to map
            self._apply_positions(generator, positions)
            
            # Generate the final map
            generator.generate()
            
            self.logger.info("AI map generation completed successfully")
            return True
            
        except Exception as e:
            self.logger.error(f"AI map generation failed: {e}\n{traceback.format_exc()}")
            return False

    def _analyze_map(self, map_path):
        """Analyze map structure and return useful data"""
        try:
            # Get map dimensions and walkable areas
            map_size = self._get_map_size(map_path)
            walkable_areas = self._get_walkable_areas(map_path)
            
            return {
                'size': map_size,
                'walkable_areas': walkable_areas,
                'complexity': self._calculate_complexity(walkable_areas)
            }
        except Exception as e:
            self.logger.error(f"Map analysis failed: {e}\n{traceback.format_exc()}")
            raise

    def _adjust_parameters(self, difficulty):
        """Adjust entity parameters based on difficulty"""
        try:
            scale = 0.5 + difficulty  # Scale from 0.5 to 1.5
            
            self.params['enemy_density'] *= scale
            self.params['police_density'] *= scale
            self.params['trap_density'] *= scale
            
            # Adjust view ranges
            for entity_type in self.params['view_range']:
                self.params['view_range'][entity_type] = int(
                    self.params['view_range'][entity_type] * scale
                )
        except Exception as e:
            self.logger.error(f"Error adjusting parameters: {e}\n{traceback.format_exc()}")
            raise

    def _generate_positions(self, map_data):
        """Generate optimal positions for all entities"""
        try:
            positions = {
                'enemies': [],
                'police': [],
                'workers': [],
                'traps': [],
                'bosses': []
            }
            
            map_size = map_data['size']
            walkable = map_data['walkable_areas']
            
            # Calculate number of entities based on density and map size
            area = map_size[0] * map_size[1]
            
            num_enemies = int(area * self.params['enemy_density'])
            num_police = int(area * self.params['police_density'])
            num_workers = int(area * self.params['worker_density'])
            
            # Generate positions ensuring minimum distance between entities
            positions['enemies'] = self._place_entities(
                num_enemies, walkable, self.params['min_distance']
            )
            positions['police'] = self._place_entities(
                num_police, walkable, self.params['min_distance']
            )
            positions['workers'] = self._place_entities(
                num_workers, walkable, self.params['min_distance']
            )
            
            # Place boss at strategic location
            positions['bosses'] = self._place_boss(walkable, positions)
            
            return positions
        except Exception as e:
            self.logger.error(f"Error generating positions: {e}\n{traceback.format_exc()}")
            raise

    def _place_entities(self, num_entities, walkable_areas, min_distance):
        """Place entities with minimum distance constraints"""
        try:
            positions = []
            attempts = 0
            max_attempts = num_entities * 10
            
            while len(positions) < num_entities and attempts < max_attempts:
                pos = self._get_random_walkable_position(walkable_areas)
                
                # Check minimum distance from other entities
                if all(self._calculate_distance(pos, p) >= min_distance 
                      for p in positions):
                    positions.append(pos)
                
                attempts += 1
            
            return positions
        except Exception as e:
            self.logger.error(f"Error placing entities: {e}\n{traceback.format_exc()}")
            raise

    def _place_boss(self, walkable_areas, existing_positions):
        """Place boss in strategic location"""
        try:
            # Find position far from other entities but in walkable area
            best_pos = None
            max_min_distance = 0
            
            for _ in range(100):  # Try 100 random positions
                pos = self._get_random_walkable_position(walkable_areas)
                min_distance = float('inf')
                
                # Check distance from all other entities
                for entity_type, positions in existing_positions.items():
                    for p in positions:
                        dist = self._calculate_distance(pos, p)
                        min_distance = min(min_distance, dist)
                
                if min_distance > max_min_distance:
                    max_min_distance = min_distance
                    best_pos = pos
            
            return [best_pos] if best_pos else []
        except Exception as e:
            self.logger.error(f"Error placing boss: {e}\n{traceback.format_exc()}")
            raise

    def _get_random_walkable_position(self, walkable_areas):
        """Get random position in walkable area"""
        try:
            area = np.random.choice(walkable_areas)
            x = np.random.uniform(area['x'], area['x'] + area['width'])
            y = np.random.uniform(area['y'], area['y'] + area['height'])
            return {'x': x, 'y': y}
        except Exception as e:
            self.logger.error(f"Error getting random walkable position: {e}\n{traceback.format_exc()}")
            raise

    def _calculate_distance(self, pos1, pos2):
        """Calculate Euclidean distance between two positions"""
        try:
            return np.sqrt(
                (pos1['x'] - pos2['x'])**2 + 
                (pos1['y'] - pos2['y'])**2
            )
        except Exception as e:
            self.logger.error(f"Error calculating distance: {e}\n{traceback.format_exc()}")
            raise

    def _apply_positions(self, generator, positions):
        """Apply generated positions to the map"""
        try:
            for entity_type, pos_list in positions.items():
                for pos in pos_list:
                    if entity_type == 'enemies':
                        generator.layers['enemies'].add_enemy(pos['x'], pos['y'])
                    elif entity_type == 'police':
                        generator.layers['police'].add_police(pos['x'], pos['y'])
                    elif entity_type == 'workers':
                        generator.layers['workers'].add_worker(pos['x'], pos['y'])
                    elif entity_type == 'bosses':
                        generator.layers['bosses'].add_boss(pos['x'], pos['y'])
        except Exception as e:
            self.logger.error(f"Error applying positions: {e}\n{traceback.format_exc()}")
            raise

    @staticmethod
    def _get_map_size(map_path):
        """Get map dimensions from TMX file"""
        try:
            tree = ET.parse(map_path)
            root = tree.getroot()
            return (
                int(root.get('width', 0)) * int(root.get('tilewidth', 0)),
                int(root.get('height', 0)) * int(root.get('tileheight', 0))
            )
        except Exception as e:
            logging.error(f"Error getting map size: {e}\n{traceback.format_exc()}")
            raise

    @staticmethod
    def _get_walkable_areas(map_path):
        """Get walkable areas from collision layer"""
        try:
            # Implementation depends on map format
            # Returns list of rectangles representing walkable areas
            pass
        except Exception as e:
            logging.error(f"Error getting walkable areas: {e}\n{traceback.format_exc()}")
            raise

    @staticmethod
    def _calculate_complexity(walkable_areas):
        """Calculate map complexity score"""
        try:
            # Implementation depends on how complexity is defined
            return len(walkable_areas)
        except Exception as e:
            logging.error(f"Error calculating map complexity: {e}\n{traceback.format_exc()}")
            raise
_____
import os
import traceback
from core.map_loader import MapLoader
from core.object_handler import ObjectHandler
from layers.bg_layer import BackgroundLayer
from layers.stories_layer import StoriesLayer
from layers.important_coords import ImportantCoordsLayer
from layers.ladders_layer import LaddersLayer
from layers.dangerous_layer import DangerousLayer
from layers.mission_layer import MissionLayer
from layers.texts_layer import TextsLayer
from entities.enemy_placer import EnemyPlacer
from entities.police_placer import PolicePlacer
from entities.worker_placer import WorkerPlacer
from entities.mover_placer import MoverPlacer
from entities.boss_placer import BossPlacer

class MapGenerator:
    def __init__(self, map_path):
        self.map_loader = MapLoader(map_path)
        self.object_handler = ObjectHandler()
        self.layers = {
            'background': BackgroundLayer(),
            'stories': StoriesLayer(),
            'important_coords': ImportantCoordsLayer(),
            'ladders': LaddersLayer(),
            'dangerous': DangerousLayer(),
            'mission': MissionLayer(),
            'texts': TextsLayer(),
            'enemies': EnemyPlacer(),
            'police': PolicePlacer(),
            'workers': WorkerPlacer(),
            'movers': MoverPlacer(),
            'bosses': BossPlacer()
        }
    def generate(self):
        """Generate the complete map with all layers and entities"""
        map_data = self.map_loader.load()
        if map_data is None:
            print("Failed to load map data")
            return
            
        for layer_name, layer in self.layers.items():
            try:
                layer.process(map_data)
                print(f"Processed {layer_name} layer")
            except Exception as e:
                print(f"Error processing {layer_name} layer: {e}")
                # Adding traceback for more detailed error information
                traceback.print_exc()
        self.map_loader.save(map_data)
        print("Map generation completed")
if __name__ == "__main__":
    import argparse
    parser = argparse.ArgumentParser(description="Generate game map with all layers and entities")
    parser.add_argument("map_path", help="Path to the TMX map file")
    args = parser.parse_args()
    generator = MapGenerator(args.map_path)
    generator.generate()
_____

import xml.etree.ElementTree as ET
from pathlib import Path
import traceback

class MapLoader:
    def __init__(self, map_path):
        self.map_path = Path(map_path)

    def load(self):
        """Load TMX map file"""
        try:
            tree = ET.parse(self.map_path)
            return tree
        except Exception as e:
            print(f"Error loading map: {e}")
            traceback.print_exc()  # Traceback ekle
            return None

    def save(self, map_data):
        """Save modified map"""
        try:
            map_data.write(self.map_path)
        except Exception as e:
            print(f"Error saving map: {e}")
            traceback.print_exc()  # Traceback ekle


________
description:

this is an python tildd based phaser game ai manager
error:
> generate
> node index.js --map=map.tmx --difficulty=0.5

Debugger attached.
No results returned.
Map generation failed: Error: No results returned.
    at C:\Users\Casper\Downloads\tiledai_scripts\project\index.js:31:28
    at PythonShell._endCallback (C:\Users\Casper\Downloads\tiledai_scripts\project\node_modules\python-shell\index.js:254:20)      
    at terminateIfNeeded (C:\Users\Casper\Downloads\tiledai_scripts\project\node_modules\python-shell\index.js:209:39)
    at ChildProcess.<anonymous> (C:\Users\Casper\Downloads\tiledai_scripts\project\node_modules\python-shell\index.js:182:13)      
    at ChildProcess.emit (node:events:519:28)
    at ChildProcess._handle.onexit (node:internal/child_process:294:12)
Waiting for the debugger to disconnect...
Waiting for the debugger to disconnect...