File size: 4,309 Bytes
e2a4174
 
fb8aa70
e2a4174
fb8aa70
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e2a4174
fb8aa70
 
 
 
 
e2a4174
fb8aa70
e2a4174
 
fb8aa70
e2a4174
 
fb8aa70
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
import streamlit as st
import os
from PIL import Image, ImageDraw
import random

# Function to arrange images dynamically
def arrange_images(image_files, output_path="dungeon_layout.png"):
    if not image_files:
        return None

    # Initialize layout
    positions = []  # Keeps track of image positions (x1, y1, x2, y2)
    canvas_size = (3000, 3000)  # Large canvas for positioning
    canvas = Image.new("RGBA", canvas_size, "white")
    draw = ImageDraw.Draw(canvas)

    def get_center(pos):
        """Calculate center of a bounding box (x1, y1, x2, y2)."""
        return ((pos[0] + pos[2]) // 2, (pos[1] + pos[3]) // 2)

    def does_overlap(new_box, existing_boxes):
        """Check if a new bounding box overlaps any existing boxes."""
        for box in existing_boxes:
            if (
                new_box[0] < box[2]
                and new_box[2] > box[0]
                and new_box[1] < box[3]
                and new_box[3] > box[1]
            ):
                return True
        return False

    # Place the first image at the center of the canvas
    first_img_path = os.path.join(map_dir, image_files[0])
    with Image.open(first_img_path) as img:
        width, height = img.size
        x1 = (canvas_size[0] - width) // 2
        y1 = (canvas_size[1] - height) // 2
        x2, y2 = x1 + width, y1 + height
        positions.append((x1, y1, x2, y2))
        canvas.paste(img, (x1, y1))

    # Place remaining images
    for img_file in image_files[1:]:
        placed = False
        img_path = os.path.join(map_dir, img_file)

        with Image.open(img_path) as img:
            width, height = img.size

            while not placed:
                # Choose a random existing image to connect to
                target_box = random.choice(positions)
                target_center = get_center(target_box)

                # Randomly choose a side of the target image
                side = random.choice(["top", "bottom", "left", "right"])

                # Calculate the new image's position based on the chosen side
                if side == "top":
                    x1 = target_center[0] - width // 2
                    y1 = target_box[1] - height
                elif side == "bottom":
                    x1 = target_center[0] - width // 2
                    y1 = target_box[3]
                elif side == "left":
                    x1 = target_box[0] - width
                    y1 = target_center[1] - height // 2
                elif side == "right":
                    x1 = target_box[2]
                    y1 = target_center[1] - height // 2

                x2, y2 = x1 + width, y1 + height

                # Check for overlap
                if not does_overlap((x1, y1, x2, y2), positions):
                    # Place the image
                    positions.append((x1, y1, x2, y2))
                    canvas.paste(img, (x1, y1))
                    placed = True

                    # Draw a connecting line
                    new_center = get_center((x1, y1, x2, y2))
                    draw.line([target_center, new_center], fill="black", width=5)

    canvas.save(output_path)
    return output_path

# Streamlit App
st.title("Dynamic Dungeon Map Generator")
st.write("Automatically generates dungeon maps by arranging PNG images dynamically.")

# Directory for images
map_dir = "."  # Top-level directory

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

if image_files:
    # Add "Create Map" button
    if st.button("🗺️ Create Map"):
        layout_image = arrange_images(image_files)
        if layout_image:
            st.image(layout_image, caption="Generated Dungeon Map Layout")
        else:
            st.write("Failed to generate a map. Please check the images in the directory.")
else:
    st.write("No PNG files found in the top-level directory.")

# 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.")