Spaces:
Sleeping
Sleeping
import gradio as gr | |
import os | |
from openai import OpenAI | |
# load API key | |
api_key = os.getenv("OPENAI_API_KEY") | |
client = OpenAI(api_key=api_key) | |
# initial game scenario | |
initial_scenario = "You wake up in a strange forest. Paths lead in all directions." | |
default_choices = [ | |
"Walk north into the dense forest.", | |
"Go south back towards a distant town.", | |
"Explore east towards the sound of water.", | |
"Move west where the land rises." | |
] | |
# template prompt | |
system_prompt = { | |
"role": "system", | |
"content": ( | |
"You are a text-based RPG engine. Continue the story based on the player's input. " | |
"Include vivid descriptions and always end your response with a few suggested choices. " | |
"Format them as a numbered list (1., 2., etc). Do not break character or give explanations." | |
) | |
} | |
history = [system_prompt, {"role": "user", "content": initial_scenario}] | |
story_log = initial_scenario | |
def parse_choices_from_response(text): | |
"""Extract numbered options from the assistant's response""" | |
lines = text.strip().split("\n") | |
options = [line.strip() for line in lines if line.strip().startswith(("1.", "2.", "3.", "4."))] | |
return options[:4] if options else default_choices | |
def update_story(player_input): | |
"""Add user input, get AI response, update story and extract new choices""" | |
global story_log | |
history.append({"role": "user", "content": f"> {player_input}"}) | |
response = client.chat.completions.create( | |
model="gpt-3.5-turbo", | |
messages=history, | |
temperature=0.9, | |
max_tokens=300 | |
) | |
continuation = response.choices[0].message.content.strip() | |
history.append({"role": "assistant", "content": continuation}) | |
story_log += f"\n\nYou: {player_input}\n{continuation}" | |
new_choices = parse_choices_from_response(continuation) | |
while len(new_choices) < 4: | |
new_choices.append("...") | |
return [story_log] + new_choices[:4] | |
def handle_button(choice_text): | |
return update_story(choice_text) | |
def handle_custom_input(text_input): | |
if not text_input.strip(): | |
return [story_log] + default_choices | |
return update_story(text_input.strip()) | |
def restart_game(): | |
global history, story_log | |
history = [system_prompt, {"role": "user", "content": initial_scenario}] | |
story_log = initial_scenario | |
return [story_log] + default_choices | |
with gr.Blocks() as app: | |
gr.Markdown("## Text-Based RPG Adventure") | |
story_display = gr.Textbox(value=initial_scenario, lines=20, interactive=False, label="Your Story") | |
with gr.Row(): | |
btn1 = gr.Button(default_choices[0]) | |
btn2 = gr.Button(default_choices[1]) | |
btn3 = gr.Button(default_choices[2]) | |
btn4 = gr.Button(default_choices[3]) | |
custom_input = gr.Textbox(lines=1, placeholder="Or type your action here...", label="Your Action") | |
restart_btn = gr.Button("π Restart Game") | |
# Bind buttons to handlers | |
btn1.click(fn=handle_button, inputs=btn1, outputs=[story_display, btn1, btn2, btn3, btn4]) | |
btn2.click(fn=handle_button, inputs=btn2, outputs=[story_display, btn1, btn2, btn3, btn4]) | |
btn3.click(fn=handle_button, inputs=btn3, outputs=[story_display, btn1, btn2, btn3, btn4]) | |
btn4.click(fn=handle_button, inputs=btn4, outputs=[story_display, btn1, btn2, btn3, btn4]) | |
custom_input.submit(fn=handle_custom_input, inputs=custom_input, outputs=[story_display, btn1, btn2, btn3, btn4]) | |
restart_btn.click(fn=restart_game, inputs=None, outputs=[story_display, btn1, btn2, btn3, btn4]) | |
app.launch() |