File size: 4,291 Bytes
389d620
 
 
bec86a9
 
 
389d620
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bec86a9
 
 
 
 
 
 
 
 
 
 
 
 
389d620
 
 
bec86a9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
389d620
 
 
 
 
 
 
 
 
 
 
 
bec86a9
389d620
bec86a9
 
 
 
389d620
bec86a9
389d620
bec86a9
 
 
 
389d620
bec86a9
 
389d620
bec86a9
 
 
 
389d620
 
 
 
 
bec86a9
389d620
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import streamlit as st
import os
import random
from PIL import Image
import networkx as nx
import matplotlib.pyplot as plt

# Function to calculate aspect ratio
def calculate_aspect_ratio(image_path):
    with Image.open(image_path) as img:
        width, height = img.size
        gcd = lambda a, b: a if not b else gcd(b, a % b)
        divisor = gcd(width, height)
        return width // divisor, height // divisor

# Function to classify room types based on aspect ratio
def classify_room(aspect_ratio):
    if aspect_ratio == (16, 9) or aspect_ratio == (19, 6):
        return "Hallway"
    elif aspect_ratio[0] < 8 and aspect_ratio[1] < 8:
        return "Door"
    else:
        return "Room"

# Function to generate a layout
def generate_dungeon_map(image_files):
    dungeon = {"Hallways": [], "Doors": [], "Rooms": []}

    for img_file in image_files:
        img_path = os.path.join(map_dir, img_file)
        aspect_ratio = calculate_aspect_ratio(img_path)
        room_type = classify_room(aspect_ratio)

        if room_type == "Hallway":
            dungeon["Hallways"].append(img_file)
        elif room_type == "Door":
            dungeon["Doors"].append(img_file)
        else:
            dungeon["Rooms"].append(img_file)

    # Generate connections between elements
    layout = nx.Graph()
    for i, hallway in enumerate(dungeon["Hallways"]):
        layout.add_node(f"Hallway {i+1}", type="Hallway")
        if dungeon["Rooms"]:
            room = dungeon["Rooms"].pop(0)
            layout.add_node(room, type="Room")
            layout.add_edge(f"Hallway {i+1}", room)

        if dungeon["Doors"]:
            door = dungeon["Doors"].pop(0)
            layout.add_node(door, type="Door")
            layout.add_edge(f"Hallway {i+1}", door)

    return layout, dungeon

# Function to visualize the dungeon layout
def visualize_dungeon(layout, output_path="dungeon_tree.png"):
    plt.figure(figsize=(12, 8))
    pos = nx.spring_layout(layout)  # Positions for nodes
    types = nx.get_node_attributes(layout, 'type')

    # Draw nodes with different colors
    color_map = {
        "Hallway": "blue",
        "Door": "green",
        "Room": "orange"
    }
    colors = [color_map[types[node]] for node in layout.nodes]

    nx.draw(
        layout, pos, with_labels=True, node_color=colors, node_size=2000,
        font_size=10, font_color="white", font_weight="bold", edge_color="gray"
    )
    plt.savefig(output_path)
    plt.close()

# Streamlit App
st.title("Dynamic Dungeon Map Generator")
st.write("Automatically generates dungeon maps by analyzing PNG images in a directory.")

# Directory for images
map_dir = "maps"  # Replace with the actual directory path

# Scan the directory for .png files
if os.path.exists(map_dir):
    image_files = [f for f in os.listdir(map_dir) if f.endswith(".png")]

    if image_files:
        st.subheader("Generate Dungeon Map")

        # Add emoji buttons
        if st.button("🔄 Regenerate Dungeon"):
            layout, dungeon = generate_dungeon_map(image_files)
            visualize_dungeon(layout)

            st.image("dungeon_tree.png", caption="Dungeon Layout Tree")

            # Display classified rooms
            st.subheader("Classified Rooms")
            st.write("### Hallways")
            st.write(", ".join(dungeon["Hallways"]) if dungeon["Hallways"] else "No hallways found.")

            st.write("### Doors")
            st.write(", ".join(dungeon["Doors"]) if dungeon["Doors"] else "No doors found.")

            st.write("### Rooms")
            st.write(", ".join(dungeon["Rooms"]) if dungeon["Rooms"] else "No rooms found.")
        else:
            st.write("Click the button above to generate a dungeon map.")
    else:
        st.write("No PNG files found in the specified directory.")
else:
    st.write("The specified directory does not exist. Please check the path.")

# Sidebar for file upload
st.sidebar.title("Options")
uploaded_file = st.sidebar.file_uploader("Upload a PNG file", type="png")

if uploaded_file:
    # Save uploaded file to the directory
    with open(os.path.join(map_dir, uploaded_file.name), "wb") as f:
        f.write(uploaded_file.getbuffer())
    st.sidebar.success("File uploaded successfully! Refresh the app to include it in the dungeon map.")