File size: 3,556 Bytes
f26aef8
40e41e9
6940dc5
f26aef8
2d57ddf
6940dc5
 
f26aef8
2d57ddf
514ad06
 
f26aef8
 
 
 
 
 
2d57ddf
514ad06
 
 
 
 
 
 
 
 
 
 
 
 
 
aec5662
514ad06
 
 
40e41e9
514ad06
 
aec5662
514ad06
 
 
8260dfb
6940dc5
514ad06
8260dfb
514ad06
 
8260dfb
 
6940dc5
8260dfb
 
514ad06
 
 
aec5662
 
 
 
514ad06
 
 
 
 
 
 
 
aec5662
514ad06
 
 
 
 
 
 
aec5662
6940dc5
f26aef8
 
2d57ddf
aec5662
514ad06
 
f26aef8
aec5662
 
 
 
514ad06
 
 
 
aec5662
 
 
 
 
09add94
aec5662
 
f26aef8
 
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
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()