Spaces:
Sleeping
Sleeping
| import os | |
| import gradio as gr | |
| from huggingface_hub import InferenceClient | |
| # Token aus den Hugging Face Secrets laden | |
| token = os.environ.get("HF_TOKEN") | |
| text_client = InferenceClient("google/gemma-1.1-7b-it", token=token) | |
| # Wir brauchen SDXL Turbo für extrem schnelle Bilder am Handy! | |
| bild_client = InferenceClient("stabilityai/sdxl-turbo", token=token) | |
| # Unser neues, ultra-atmosphärisches CSS (Gestaltungscode) | |
| # Wir fügen die Styles für das gestapelte Logbuch hinzu. | |
| geiles_design = """ | |
| @import url('https://fonts.googleapis.com/css2?family=Special+Elite&display=swap'); | |
| body, .gradio-container { | |
| /* Düsteres Apokalypse-Hintergrundbild aus dem Netz */ | |
| background-image: url('https://images.unsplash.com/photo-1485603099951-40344d18721c?q=80&w=2000&auto=format&fit=crop') !important; | |
| background-size: cover !important; | |
| background-position: center !important; | |
| background-attachment: fixed !important; | |
| font-family: sans-serif; | |
| } | |
| /* Der Hauptbereich wird schwarz und leicht durchsichtig */ | |
| .haupt-bereich { | |
| background: rgba(0, 0, 0, 0.7) !important; | |
| border-radius: 10px; | |
| padding: 20px !important; | |
| max-width: 800px !important; | |
| margin: 0 auto !important; | |
| backdrop-filter: blur(3px); /* Macht das Hintergrundbild leicht unscharf */ | |
| border: 1px solid rgba(255, 255, 255, 0.1); | |
| } | |
| h1 { color: #d4af37 !important; text-align: center; text-transform: uppercase; font-size: 2.5em !important; text-shadow: 2px 2px 4px #000; margin-bottom: 20px !important;} | |
| /* Der Rucksack */ | |
| .rucksack-anzeige { | |
| background: rgba(0, 0, 0, 0.8) !important; | |
| border: 1px solid #8b0000 !important; | |
| padding: 12px !important; | |
| color: #d4af37 !important; | |
| text-align: center; | |
| border-radius: 5px; | |
| margin-bottom: 20px !important; | |
| font-weight: bold; | |
| } | |
| /* Der Notizzettel für die Story! */ | |
| .notizzettel { | |
| background: #e3dec6 !important; /* Schmutzige Papier-Farbe */ | |
| color: #1a1a1a !important; | |
| font-family: 'Special Elite', monospace !important; /* Echte Schreibmaschinen-Schrift */ | |
| font-size: 1.3em !important; | |
| line-height: 1.6 !important; | |
| padding: 25px !important; | |
| border-radius: 2px !important; | |
| box-shadow: 3px 3px 15px rgba(0,0,0,0.8) !important; | |
| transform: rotate(-1deg); /* Leichte Drehung für den echten Zettel-Look */ | |
| margin: 20px 5px !important; | |
| border-left: 4px solid #8b0000 !important; /* Roter Rand */ | |
| } | |
| /* Rahmen für das generierte Bild */ | |
| .output-bild { border: 2px solid #555 !important; border-radius: 3px !important; box-shadow: 0 5px 15px rgba(0,0,0,0.9) !important;} | |
| /* Eingabefeld durchsichtig machen */ | |
| input, textarea { | |
| background: rgba(0, 0, 0, 0.6) !important; | |
| color: #fff !important; | |
| border: 1px solid #8b0000 !important; | |
| font-size: 1.2em !important; | |
| border-radius: 5px !important; | |
| } | |
| /* Aggressiver Action-Button */ | |
| button { | |
| background: #8b0000 !important; | |
| color: #fff !important; | |
| border: none !important; | |
| font-weight: bold !important; | |
| text-transform: uppercase !important; | |
| font-size: 1.2em !important; | |
| padding: 12px !important; | |
| border-radius: 5px !important; | |
| box-shadow: 0 4px 6px rgba(0,0,0,0.6) !important; | |
| } | |
| button:hover { background: #aa0000 !important; } | |
| """ | |
| def spiel_zug(nachricht, aktueller_rucksack): | |
| if not nachricht: | |
| return None, "Du musst schon was tun!", aktueller_rucksack, f"🎒 INVENTAR: {aktueller_rucksack}", "" | |
| system_prompt = f"""Du bist 'Zombie Go'. | |
| Inventar des Spielers: {aktueller_rucksack}. | |
| Regel: Der Spieler darf NUR Dinge nutzen, die im Inventar sind. Erfinde keine Waffen für ihn. | |
| Füge neu gefundene Gegenstände oder gesammeltes 'Go' logisch zum Rucksack hinzu. | |
| Aktion des Spielers: '{nachricht}'. | |
| Antworte EXAKT in dieser Form (ohne Ausnahmen): | |
| STORY: [Beschreibe in max 3 spannenden Sätzen, was passiert] | |
| RUCKSACK: [Liste der Items] | GO: [Anzahl]""" | |
| try: | |
| antwort = text_client.text_generation(system_prompt, max_new_tokens=200) | |
| # Split (Text zerteilen): Wir trennen Story und Rucksack am Wort "RUCKSACK:" | |
| if "RUCKSACK:" in antwort: | |
| teile = antwort.split("RUCKSACK:") | |
| story_text = teile[0].replace("STORY:", "").strip() | |
| neuer_rucksack = teile[1].strip() | |
| else: | |
| # Falls die KI den Befehl vermasselt, behalten wir den alten Rucksack | |
| story_text = antwort.replace("STORY:", "").strip() | |
| neuer_rucksack = aktueller_rucksack | |
| except Exception as e: | |
| story_text = "Die Verbindung stottert... die KI schnappt nach Luft." | |
| neuer_rucksack = aktueller_rucksack | |
| # Bild-KI (SDXL Turbo - EXTREM SCHNELL!) | |
| # Wir fügen düstere englische Begriffe hinzu, damit die KI das Zombie-Go-Thema versteht | |
| bild_prompt = f"dark zombie apocalypse survival scene, first person view, {nachricht}, eerie green lighting from glowing crystals, highly detailed, realistic texture, derelict ruined city, atmospheric" | |
| try: | |
| # SDXL Turbo braucht extrem wenige Schritte und ist fast sofort fertig! | |
| bild = bild_client.text_to_image(bild_prompt, num_inference_steps=1) | |
| except: | |
| bild = None | |
| rucksack_ui_text = f"🎒 INVENTAR: {neuer_rucksack}" | |
| # Gibt alles zurück: Chat, Bild, leeres Textfeld, schicke Anzeige, unsichtbarer Speicher | |
| return bild, story_text, neuer_rucksack, rucksack_ui_text, "" | |
| with gr.Blocks(css=geiles_design, theme=gr.themes.Base()) as spiel_oberflaeche: | |
| # Wir geben dem Haupt-Bereich die CSS-Klasse 'haupt-bereich' | |
| with gr.Column(elem_classes="haupt-bereich"): | |
| gr.Markdown("# 🧟 ZOMBIE GO") | |
| # State (unsichtbarer Speicher) für deinen Start-Rucksack | |
| rucksack_speicher = gr.State("Taschenlampe, leere Wasserflasche | GO: 0") | |
| rucksack_ui = gr.Markdown("🎒 INVENTAR: Taschenlampe, leere Wasserflasche | GO: 0", elem_classes="rucksack-anzeige") | |
| # Das generierte Bild | |
| szene_bild = gr.Image(label="Visuelles Echo", type="pil", elem_classes="output-bild") | |
| # Der Notizzettel für die Story! | |
| story_ausgabe = gr.Markdown("*Warte auf Eingabe... (Tipp: 'Umschauen')*", elem_classes="notizzettel") | |
| gr.Markdown("---") | |
| # Eingabe-Bereich | |
| eingabe = gr.Textbox(label="", placeholder="Was tust du? (z.B. Zombies looten)", lines=1) | |
| senden_btn = gr.Button("▶ AKTION EINTRAGEN") | |
| # Verknüpfungen der Knöpfe (wichtige Reihenfolge der Outputs!) | |
| senden_btn.click( | |
| spiel_zug, | |
| inputs=[eingabe, rucksack_speicher], | |
| outputs=[szene_bild, story_ausgabe, rucksack_speicher, rucksack_ui, eingabe] | |
| ) | |
| eingabe.submit( | |
| spiel_zug, | |
| inputs=[eingabe, rucksack_speicher], | |
| outputs=[szene_bild, story_ausgabe, rucksack_speicher, rucksack_ui, eingabe] | |
| ) | |
| # Startet das Game | |
| spiel_oberflaeche.launch() | |