File size: 8,458 Bytes
abb4f04
e7e80be
1b19da6
 
 
 
 
16aec25
1b19da6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16aec25
 
 
1b19da6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16aec25
1b19da6
 
 
 
 
 
 
16aec25
 
 
 
 
1b19da6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
775b0e2
1b19da6
bbd20f8
775b0e2
 
1b19da6
 
 
 
 
 
 
bbd20f8
775b0e2
1b19da6
bbd20f8
775b0e2
 
b4a455a
bbd20f8
1b19da6
 
 
 
bbd20f8
16aec25
 
bbd20f8
1b19da6
 
 
bbd20f8
1b19da6
 
16aec25
 
 
 
 
 
1b19da6
 
 
 
 
 
abb4f04
1b19da6
588e283
1b19da6
abb4f04
1b19da6
 
775b0e2
b4a455a
1b19da6
 
16aec25
1b19da6
16aec25
1b19da6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b4a455a
1b19da6
 
 
 
 
 
16aec25
1b19da6
 
 
16aec25
1b19da6
 
9f8f775
775b0e2
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
import gradio as gr
from groq import Groq
import os
import json
import datetime
import copy

# Ordner für lokale Projekte
PROJECT_DIR = "projects"
os.makedirs(PROJECT_DIR, exist_ok=True)

# Aktuelles Projekt
current_project = {"name": None, "code": "", "chat_history": [], "checkpoints": []}

# ------------------------------
# Hilfsfunktionen
# ------------------------------

def list_projects():
    files = [f.replace(".json","") for f in os.listdir(PROJECT_DIR) if f.endswith(".json")]
    return files if files else ["Keine Projekte"]

def create_checkpoint():
    """Speichert aktuellen Code + Chat als Checkpoint"""
    global current_project
    checkpoint = {
        "timestamp": datetime.datetime.now().strftime("%Y%m%d_%H%M%S"),
        "code": copy.deepcopy(current_project["code"]),
        "chat_history": copy.deepcopy(current_project["chat_history"])
    }
    current_project["checkpoints"].append(checkpoint)

def update_checkpoint_list():
    return [c["timestamp"] for c in current_project["checkpoints"]] if current_project["checkpoints"] else []

def new_project():
    global current_project
    timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
    current_project = {
        "name": f"Projekt_{timestamp}",
        "code": """<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>Neues Spiel</title></head>
<body><canvas id="game"></canvas>
<script>
const canvas = document.getElementById('game');
const ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
let x=50,y=50;
function loop(){ctx.clearRect(0,0,canvas.width,canvas.height);ctx.fillStyle='lime';ctx.fillRect(x,y,50,50);x+=1;requestAnimationFrame(loop);}
loop();
</script></body></html>""",
        "chat_history": [],
        "checkpoints": []
    }
    create_checkpoint()
    return current_project["code"], "<p>Live Vorschau</p>", list_projects(), "Neues Projekt erstellt: " + current_project["name"], update_checkpoint_list()

def load_project(project_name):
    global current_project
    filepath = os.path.join(PROJECT_DIR,f"{project_name}.json")
    if os.path.exists(filepath):
        with open(filepath,"r",encoding="utf-8") as f:
            current_project = json.load(f)
        html_escaped = current_project["code"].replace('"', "&quot;")
        iframe_html = f"<iframe srcdoc='{html_escaped}' width='100%' height='400px' style='border:none;'></iframe>"
        return current_project["code"], iframe_html, list_projects(), f"Projekt geladen: {project_name}", update_checkpoint_list()
    else:
        return "", "<p>Keine Vorschau</p>", list_projects(), "Projekt nicht gefunden", []

def save_project():
    global current_project
    if not current_project["name"]:
        return "Kein Projekt aktiv!"
    filepath = os.path.join(PROJECT_DIR, f"{current_project['name']}.json")
    with open(filepath,"w",encoding="utf-8") as f:
        json.dump(current_project,f,indent=2,ensure_ascii=False)
    return f"Projekt gespeichert: {current_project['name']}"

def save_code_local(code):
    global current_project
    current_project["code"] = code
    create_checkpoint()
    return save_project(), update_checkpoint_list()

def chat_generate(api_key, model_name, user_input, current_code):
    global current_project
    if not api_key:
        return current_code, "<p>Keine Vorschau</p>", "Bitte API-Key eingeben!", update_checkpoint_list()

    try:
        client = Groq(api_key=api_key)
        system_prompt = {"role":"system","content":(
            "Du bist ein professioneller Game Developer und AI-Coding-Assistent. "
            "Bearbeite oder erweitere den gegebenen HTML5-Code, nur gültiges HTML+JS, "
            "Canvas-basiertes Spiel, sofort spielbar, keine Erklärungen."
        )}
        user_message = {"role":"user","content": f"Aktueller Code:\n{current_code}\n\nAnfrage:\n{user_input}"}
        messages = [system_prompt] + current_project["chat_history"] + [user_message]

        completion = client.chat.completions.create(
            model=model_name,
            messages=messages,
            temperature=0.8
        )

        model_response = completion.choices[0].message.content
        current_project["code"] = model_response
        current_project["chat_history"].append(user_message)
        current_project["chat_history"].append({"role":"assistant","content":model_response})
        create_checkpoint()

        html_escaped = model_response.replace('"', "&quot;")
        preview_html = f"<iframe srcdoc='{html_escaped}' width='100%' height='400px' style='border:none;'></iframe>"

        return model_response, preview_html, "✅ KI Update fertig", update_checkpoint_list()
    except Exception as e:
        return current_code, "<p>Fehler bei der Vorschau</p>", f"Fehler: {e}", update_checkpoint_list()

def load_checkpoint(checkpoint_time):
    for c in current_project["checkpoints"]:
        if c["timestamp"] == checkpoint_time:
            current_project["code"] = c["code"]
            current_project["chat_history"] = c["chat_history"]
            html_escaped = c["code"].replace('"', "&quot;")
            iframe_html = f"<iframe srcdoc='{html_escaped}' width='100%' height='400px' style='border:none;'></iframe>"
            return current_project["code"], iframe_html, "✅ Checkpoint geladen"
    return current_project["code"], "<p>Keine Vorschau</p>", "Checkpoint nicht gefunden"

def delete_checkpoint(checkpoint_time):
    global current_project
    current_project["checkpoints"] = [c for c in current_project["checkpoints"] if c["timestamp"] != checkpoint_time]
    return update_checkpoint_list(), "✅ Checkpoint gelöscht"

# ------------------------------
# Gradio UI
# ------------------------------
with gr.Blocks() as demo:
    gr.Markdown("# 🕹️ HTML5 Game Studio mit AI & Checkpoints")
    
    with gr.Row():
        with gr.Column(scale=1):
            gr.Markdown("### KI Beschreibung / Hinweise")
            ki_desc = gr.HTML("<p>Hier erscheinen Hinweise der KI und aktuelle Anfrage</p>")
            
            api_key_input = gr.Textbox(label="GROQ API-Key", placeholder="Hier API-Key einfügen", type="password")
            model_input = gr.Textbox(label="AI Modell", placeholder="Beispiel: llama3-70b-8192 oder gpt-os", value="llama3-70b-8192")
            user_input = gr.Textbox(label="Spielidee / Follow-up", placeholder="Beispiel: Gegner hinzufügen", lines=3)
            
            with gr.Row():
                btn_new = gr.Button("🆕 New Project")
                btn_save_code = gr.Button("💾 Save Code")
                btn_ai = gr.Button("🤖 Mit AI aktualisieren")
            
            project_dropdown = gr.Dropdown(list_projects(), label="Projekt laden")
            btn_load = gr.Button("📂 Load Project")
            btn_save_project = gr.Button("💾 Save Project")
            
            gr.Markdown("### Checkpoints")
            checkpoint_dropdown = gr.Dropdown([], label="Checkpoint auswählen")
            btn_load_checkpoint = gr.Button("⬅️ Wiederherstellen")
            btn_delete_checkpoint = gr.Button("❌ Löschen")
            
            code_editor = gr.Code(language="html", label="HTML5 Game Code", lines=20, value="")
            status_output = gr.Textbox(label="Status", interactive=False)
        
        with gr.Column(scale=1):
            gr.Markdown("### Live Vorschau")
            preview_output = gr.HTML("<p>Vorschau erscheint hier</p>")

    # ------------------------------
    # Events
    # ------------------------------
    btn_new.click(new_project, outputs=[code_editor, preview_output, project_dropdown, status_output, checkpoint_dropdown])
    btn_load.click(load_project, inputs=[project_dropdown], outputs=[code_editor, preview_output, project_dropdown, status_output, checkpoint_dropdown])
    btn_save_code.click(save_code_local, inputs=[code_editor], outputs=[status_output, checkpoint_dropdown])
    btn_save_project.click(save_project, outputs=[status_output])
    btn_ai.click(chat_generate, inputs=[api_key_input, model_input, user_input, code_editor], outputs=[code_editor, preview_output, status_output, checkpoint_dropdown])
    btn_load_checkpoint.click(load_checkpoint, inputs=[checkpoint_dropdown], outputs=[code_editor, preview_output, status_output])
    btn_delete_checkpoint.click(delete_checkpoint, inputs=[checkpoint_dropdown], outputs=[checkpoint_dropdown, status_output])

demo.launch()