
import random
import math
import collections

# Constants
WIDTH, HEIGHT = 21, 21
FOV_RADIUS = 5
PLAYER_VISION_RADIUS = 5

# Directions
DIRS = [(0, -1), (1, 0), (0, 1), (-1, 0)]
DIR_NAMES = ['N', 'E', 'S', 'W']

# Room and corridor generation
def is_wall(x, y):
    return (x, y) in WALLS or (x < 0 or x >= WIDTH or y < 0 or y >= HEIGHT)

def in_bounds(x, y):
    return 0 <= x < WIDTH and 0 <= y < HEIGHT

def generate_dungeon(width, height):
    global WALLS
    WALLS = set()
    ROOMS = []

    # Start with a border of walls
    for x in range(width):
        WALLS.add((x, 0))
        WALLS.add((x, height - 1))
    for y in range(height):
        WALLS.add((0, y))
        WALLS.add((width - 1, y))

    # Randomly carve out rooms and corridors
    for _ in range(10):  # Number of rooms
        room_w = random.randint(3, 6)
        room_h = random.randint(3, 6)
        x = random.randint(1, width - room_w - 1)
        y = random.randint(1, height - room_h - 1)
        new_room = True
        for wx in range(x, x + room_w):
            for wy in range(y, y + room_h):
                if (wx, wy) not in WALLS:
                    new_room = False
                    for ox, oy in WALLS:
                        if ox == wx or ox == wx + 1 or oy == wy or oy == wy + 1:
                            WALLS.remove((ox, oy))
                    WALLS.add((wx, wy))
        if new_room:
            ROOMS.append((x, y, room_w, room_h))

    return WALLS, ROOMS

# Fog of War and Line of Sight
def compute_fov(player_x, player_y, radius):
    visible = set()
    for x in range(max(0, player_x - radius), min(WIDTH, player_x + radius + 1)):
        for y in range(max(0, player_y - radius), min(HEIGHT, player_y + radius + 1)):
            if not is_wall(x, y) and math.sqrt((x - player_x) ** 2 + (y - player_y) ** 2) <= radius:
                visible.add((x, y))
    return visible

# Simulation
def run_automated_dungeon_simulation():
    player_x, player_y = WIDTH // 2, HEIGHT // 2
    visible = set([(player_x, player_y)])
    last_visible = set()

    for _ in range(20):
        last_visible = visible
        visible = compute_fov(player_x, player_y, PLAYER_VISION_RADIUS)
        print("Turn:", _)
        print("Player Position:", player_x, player_y)
        print("Visible Tiles:", visible)
        print("Last Turn Visible Tiles:", last_visible)

        # Simulate movement (e.g., random walk)
        move = random.choice(DIRS)
        player_x += move[0]
        player_y += move[1]

if __name__ == "__main__":
    WALLS, ROOMS = generate_dungeon(WIDTH, HEIGHT)
    run_automated_dungeon_simulation()
