Spaces:
Sleeping
Sleeping
File size: 6,982 Bytes
16c8bb1 8362100 16c8bb1 56fee53 4cff81a 866e648 56fee53 8362100 866e648 8362100 494dcd4 33d1e4c 8362100 494dcd4 33d1e4c 8362100 494dcd4 33d1e4c 8362100 494dcd4 8362100 494dcd4 8362100 494dcd4 8362100 494dcd4 8362100 494dcd4 8362100 33d1e4c 8362100 33d1e4c 8362100 33d1e4c 8362100 33d1e4c 866e648 494dcd4 33d1e4c 866e648 33d1e4c 8362100 33d1e4c 8362100 0452b8d 33d1e4c 494dcd4 33d1e4c 494dcd4 866e648 33d1e4c 866e648 56fee53 866e648 33d1e4c 866e648 56fee53 33d1e4c 0452b8d 866e648 0452b8d 866e648 0452b8d 866e648 0452b8d 33d1e4c 0452b8d 866e648 33d1e4c 866e648 0452b8d 866e648 56fee53 494dcd4 56fee53 33d1e4c 0452b8d 56fee53 8362100 33d1e4c 8362100 494dcd4 33d1e4c 494dcd4 866e648 8362100 33d1e4c 494dcd4 866e648 33d1e4c 8362100 16c8bb1 866e648 0452b8d 33d1e4c 0452b8d 33d1e4c 0452b8d 16c8bb1 866e648 16c8bb1 | 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 | 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()
|