File size: 11,801 Bytes
4b6484b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
import gradio as gr
from src.game_logic import RPGGame
from src.database import interactions

def create_interface():
    game = RPGGame()
    
    with gr.Blocks(theme=gr.themes.Base()) as demo:
        # Header with title and description
        gr.Markdown(
            """

            <div style="margin-bottom: 20px;">

                <h1 style="margin-bottom: 0.5em;">🎲 AI RPG Adventure</h1>

                <p>An interactive RPG experience from Pixeltable and powered by OpenAI! Get started with an example below.</p>

            </div>

            """
        )
        
        # Side-by-side accordions
        with gr.Row():
            with gr.Column():
                with gr.Accordion("🎯 What does it do?", open=False):
                    gr.Markdown("""

                    This AI RPG Adventure demonstrates Pixeltable's capabilities:

                    

                    - 🎮 Creates dynamic, AI-driven interactive stories

                    - 🔄 Maintains game state and history using Pixeltable tables 

                    - 💭 Generates contextual options based on player actions

                    - 📝 Processes natural language inputs for custom actions

                    - 🤖 Uses LLMs to create engaging narratives

                    - 📊 Tracks and displays game progression

                    

                    Perfect for understanding how Pixeltable can manage complex,

                    stateful applications with AI integration! ✨

                    """)
            
            with gr.Column():
                with gr.Accordion("🛠️ How does it work?", open=False):
                    gr.Markdown("""

                    The app leverages several Pixeltable features:

                    

                    1. 📦 **Data Management**: Uses Pixeltable tables to store game state, 

                       player actions, and AI responses

                    

                    2. 🤖 **AI Integration**: Seamlessly connects with language models 

                       for story generation and response processing

                    

                    3. 🔄 **State Tracking**: Maintains session history and player 

                       choices using Pixeltable's computed columns

                    

                    4. ⚙️ **Custom Processing**: Uses Pixeltable UDFs to handle game 

                       logic and AI prompt generation

                    

                    5. 🎯 **Interactive Flow**: Processes player inputs and generates 

                       contextual responses in real-time

                    """)
        
        with gr.Row():
            # Setup column
            with gr.Column():
                player_name = gr.Textbox(
                    label="👤 Your Character's Name",
                    placeholder="Enter your character's name..."
                )
                genre = gr.Dropdown(
                    choices=[
                        "🧙‍♂️ Fantasy",
                        "🚀 Sci-Fi",
                        "👻 Horror",
                        "🔍 Mystery",
                        "🌋 Post-Apocalyptic",
                        "🤖 Cyberpunk",
                        "⚙️ Steampunk"
                    ],
                    label="🎭 Choose Your Genre"
                )
                scenario = gr.Textbox(
                    label="📖 Starting Scenario",
                    lines=3,
                    placeholder="Describe the initial setting and situation..."
                )
                start_button = gr.Button("🎮 Begin Adventure", variant="primary")
            
            # Game interaction column
            with gr.Column():
                story_display = gr.Textbox(
                    label="📜 Story",
                    lines=8,
                    interactive=False
                )
                
                gr.Markdown("### 🎯 Choose Your Action")
                
                with gr.Row():
                    with gr.Column():
                        action_input = gr.Radio(
                            choices=[],
                            label="🎲 Select an action or write your own below:",
                            interactive=True
                        )
                        custom_action = gr.Textbox(
                            label="✨ Custom Action",
                            placeholder="Write your own action here...",
                            lines=2
                        )
                        submit_action = gr.Button("⚡ Take Action", variant="secondary")
        
        # History display
        history_df = gr.Dataframe(
            headers=["📅 Turn", "🎯 Player Action", "💬 Game Response"],
            label="📚 Adventure History",
            wrap=True,
            row_count=5,
            col_count=(3, "fixed")
        )
        def start_new_game(name, genre_choice, scenario_text):
            if not name or not genre_choice or not scenario_text:
                return "Please fill in all fields before starting.", [], "", []
            
            try:
                _, initial_response = game.start_game(name, genre_choice, scenario_text)
                
                # Get options from the initial response
                options = interactions.select(interactions.options).where(
                    (interactions.session_id == game.current_session_id) & 
                    (interactions.turn_number == 0)
                ).collect()['options'][0]
                
                # Get initial history
                history_df = interactions.select(
                    turn=interactions.turn_number,
                    action=interactions.player_input,
                    response=interactions.story_text
                ).where(
                    interactions.session_id == game.current_session_id
                ).order_by(
                    interactions.turn_number
                ).collect().to_pandas()
                
                history_data = [
                    [str(row['turn']), row['action'], row['response']] 
                    for _, row in history_df.iterrows()
                ]
                
                return initial_response, gr.Radio(choices=options, interactive=True), "", history_data
            except Exception as e:
                return f"Error starting game: {str(e)}", [], "", []
        
        def process_player_action(action_choice, custom_action):
            try:
                # Use custom action if provided, otherwise use selected choice
                action = custom_action if custom_action else action_choice
                if not action:
                    return "Please either select an action or write your own.", [], "", []
                    
                response = game.process_action(action)
                
                # Get new options
                options = interactions.select(interactions.options).where(
                    (interactions.session_id == game.current_session_id) & 
                    (interactions.turn_number == game.turn_number)
                ).collect()['options'][0]
                
                # Get updated history
                history_df = interactions.select(
                    turn=interactions.turn_number,
                    action=interactions.player_input,
                    response=interactions.story_text
                ).where(
                    interactions.session_id == game.current_session_id
                ).order_by(
                    interactions.turn_number
                ).collect().to_pandas()
                
                history_data = [
                    [str(row['turn']), row['action'], row['response']] 
                    for _, row in history_df.iterrows()
                ]
                
                return response, gr.Radio(choices=options, interactive=True), "", history_data
            except Exception as e:
                return f"Error: {str(e)}", [], "", []
        
        # Connect the start button
        start_button.click(
            start_new_game,
            inputs=[player_name, genre, scenario],
            outputs=[story_display, action_input, custom_action, history_df]
        )
        
        # Single action submit button
        submit_action.click(
            process_player_action,
            inputs=[action_input, custom_action],
            outputs=[story_display, action_input, custom_action, history_df]
        )
        
               # Example scenarios
        gr.Markdown("### 💫 Example Adventures")
        gr.Examples(
            examples=[
                ["Eldric", "🧙‍♂️ Fantasy", "You find yourself in an ancient forest clearing, standing before a mysterious glowing portal. Your journey begins..."],
                ["Commander Nova", "🚀 Sci-Fi", "Aboard the starship Nebula, alarms blare as unknown entities approach. The fate of the crew rests in your hands..."],
                ["Detective Blake", "🔍 Mystery", "In the fog-shrouded streets of Victorian London, a peculiar letter arrives at your doorstep..."],
            ],
            inputs=[player_name, genre, scenario]
        )
        
        # Footer with links
        gr.HTML(
            """

            <div style="margin-top: 2rem; padding-top: 1rem; border-top: 1px solid #e5e7eb;">

                <div style="display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 1rem;">

                    <div style="flex: 1;">

                        <h4 style="margin: 0; color: #374151;">🚀 Built with Pixeltable</h4>

                        <p style="margin: 0.5rem 0; color: #6b7280;">

                            AI Data infrastructure providing a declarative, incremental approach for multimodal workloads.

                        </p>

                    </div>

                    <div style="flex: 1;">

                        <h4 style="margin: 0; color: #374151;">🔗 Resources</h4>

                        <div style="display: flex; gap: 1.5rem; margin-top: 0.5rem;">

                            <a href="https://github.com/pixeltable/pixeltable" target="_blank" style="color: #4F46E5; text-decoration: none; display: flex; align-items: center; gap: 0.25rem;">

                                💻 GitHub

                            </a>

                            <a href="https://docs.pixeltable.com" target="_blank" style="color: #4F46E5; text-decoration: none; display: flex; align-items: center; gap: 0.25rem;">

                                📚 Documentation

                            </a>

                            <a href="https://huggingface.co/Pixeltable" target="_blank" style="color: #4F46E5; text-decoration: none; display: flex; align-items: center; gap: 0.25rem;">

                                🤗 Hugging Face

                            </a>

                        </div>

                    </div>

                </div>

                <p style="margin: 1rem 0 0; text-align: center; color: #9CA3AF; font-size: 0.875rem;">

                    ✨ © 2024 Pixeltable. This demo is open source and available on 

                    <a href="https://huggingface.co/spaces/Pixeltable/AI-RPG-Adventure" target="_blank" style="color: #4F46E5; text-decoration: none;">

                        Hugging Face Spaces 🚀

                    </a>

                </p>

            </div>

            """
        )

    return demo