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() |