import numpy as np
import opensimplex
import random

class WorldGenerator:
    def __init__(self, width=200, height=200, seed=None):
        self.width = width
        self.height = height
        self.seed = seed if seed is not None else random.randint(0, 1000000)
        self.noise = opensimplex.OpenSimplex(seed=self.seed)
        random.seed(self.seed)
    
    def generate_land_only(self):
        return np.ones((self.height, self.width))
    
    def generate_continent(self, size=0.7, roughness=0.5):
        world = np.zeros((self.height, self.width))
        center_x, center_y = self.width//2, self.height//2
        
        for y in range(self.height):
            for x in range(self.width):
                nx = (x - center_x) / (self.width * 0.8)
                ny = (y - center_y) / (self.height * 0.8)
                dist = np.sqrt(nx**2 + ny**2) * (1.0/size)
                noise_val = self.noise.noise2(x * roughness/10, y * roughness/10)
                world[y][x] = 1 if (1 - dist) + noise_val * 0.5 > 0.4 else 0
        return world
    
    def generate_islands(self, density=0.6, island_size=0.3, roughness=0.5):
        world = np.zeros((self.height, self.width))
        scale = 20 / (island_size + 0.1)
        
        temp_map = np.zeros((self.height, self.width))
        for y in range(self.height):
            for x in range(self.width):
                nx = x / scale * (1 + roughness)
                ny = y / scale * (1 + roughness)
                noise_val = self.noise.noise2(nx, ny)
                threshold = 0.5 - density*0.4
                if noise_val > threshold:
                    temp_map[y][x] = 1
        
        islands = []
        visited = np.zeros_like(temp_map)
        for y in range(self.height):
            for x in range(self.width):
                if temp_map[y][x] == 1 and visited[y][x] == 0:
                    island = []
                    queue = [(y, x)]
                    visited[y][x] = 1
                    
                    min_y, max_y = y, y
                    min_x, max_x = x, x
                    
                    while queue:
                        cy, cx = queue.pop()
                        island.append((cy, cx))
                        
                        min_y = min(min_y, cy)
                        max_y = max(max_y, cy)
                        min_x = min(min_x, cx)
                        max_x = max(max_x, cx)
                        
                        for dy, dx in [(-1,0),(1,0),(0,-1),(0,1)]:
                            ny, nx = cy+dy, cx+dx
                            if (0 <= ny < self.height and 0 <= nx < self.width and 
                                temp_map[ny][nx] == 1 and visited[ny][nx] == 0):
                                visited[ny][nx] = 1
                                queue.append((ny, nx))
                    
                    if (min_y > 0 and max_y < self.height-1 and 
                        min_x > 0 and max_x < self.width-1):
                        islands.append(island)
        
        for island in islands:
            for y, x in island:
                world[y][x] = 1
        
        return world