sunbal7 commited on
Commit
6e60411
ยท
verified ยท
1 Parent(s): 5389f67

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +773 -0
app.py ADDED
@@ -0,0 +1,773 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # app.py - Game-Based Learning Version
2
+ import streamlit as st
3
+ import os
4
+ import time
5
+ import random
6
+ import base64
7
+ import json
8
+ import requests
9
+ import re
10
+ from PIL import Image
11
+ import io
12
+ import matplotlib.pyplot as plt
13
+ import numpy as np
14
+ import pandas as pd
15
+ import plotly.express as px
16
+ import plotly.graph_objects as go
17
+
18
+ # Configure Streamlit page
19
+ st.set_page_config(
20
+ page_title="StoryCoder - Learn Coding Through Games",
21
+ page_icon="๐Ÿง™โ€โ™‚๏ธ",
22
+ layout="wide",
23
+ initial_sidebar_state="expanded"
24
+ )
25
+
26
+ # Custom CSS for colorful UI
27
+ st.markdown("""
28
+ <style>
29
+ @import url('https://fonts.googleapis.com/css2?family=Comic+Neue:wght@700&display=swap');
30
+
31
+ :root {
32
+ --primary: #FF6B6B;
33
+ --secondary: #4ECDC4;
34
+ --accent: #FFD166;
35
+ --dark: #1A535C;
36
+ --light: #F7FFF7;
37
+ }
38
+
39
+ body {
40
+ background: linear-gradient(135deg, var(--light) 0%, #E8F4F8 100%);
41
+ font-family: 'Comic Neue', cursive;
42
+ }
43
+
44
+ .stApp {
45
+ background: url('https://www.transparenttextures.com/patterns/cartographer.png');
46
+ }
47
+
48
+ .story-box {
49
+ background-color: white;
50
+ border-radius: 20px;
51
+ padding: 25px;
52
+ box-shadow: 0 8px 16px rgba(26, 83, 92, 0.15);
53
+ border: 3px solid var(--accent);
54
+ margin-bottom: 25px;
55
+ }
56
+
57
+ .header {
58
+ color: var(--dark);
59
+ text-shadow: 2px 2px 4px rgba(0,0,0,0.1);
60
+ }
61
+
62
+ .concept-card {
63
+ background: linear-gradient(145deg, #ffffff, #f0f0f0);
64
+ border-radius: 15px;
65
+ padding: 15px;
66
+ margin: 10px 0;
67
+ border-left: 5px solid var(--secondary);
68
+ box-shadow: 0 4px 8px rgba(0,0,0,0.05);
69
+ }
70
+
71
+ .stButton>button {
72
+ background: linear-gradient(45deg, var(--primary), var(--secondary));
73
+ color: white;
74
+ border-radius: 12px;
75
+ padding: 10px 24px;
76
+ font-weight: bold;
77
+ font-size: 18px;
78
+ border: none;
79
+ transition: all 0.3s;
80
+ }
81
+
82
+ .stButton>button:hover {
83
+ transform: scale(1.05);
84
+ box-shadow: 0 6px 12px rgba(0,0,0,0.15);
85
+ }
86
+
87
+ .stTextInput>div>div>input {
88
+ border-radius: 12px;
89
+ padding: 12px;
90
+ border: 2px solid var(--accent);
91
+ }
92
+
93
+ .tabs {
94
+ display: flex;
95
+ gap: 10px;
96
+ margin-bottom: 20px;
97
+ overflow-x: auto;
98
+ }
99
+
100
+ .tab {
101
+ padding: 10px 20px;
102
+ background-color: var(--accent);
103
+ border-radius: 10px;
104
+ cursor: pointer;
105
+ font-weight: bold;
106
+ white-space: nowrap;
107
+ }
108
+
109
+ .tab.active {
110
+ background-color: var(--secondary);
111
+ color: white;
112
+ }
113
+
114
+ @media (max-width: 768px) {
115
+ .tabs {
116
+ flex-wrap: wrap;
117
+ }
118
+ }
119
+
120
+ .game-container {
121
+ background-color: #1a1a2e;
122
+ border-radius: 15px;
123
+ padding: 20px;
124
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
125
+ margin-bottom: 25px;
126
+ position: relative;
127
+ overflow: hidden;
128
+ }
129
+
130
+ .game-preview {
131
+ border-radius: 10px;
132
+ overflow: hidden;
133
+ margin: 0 auto;
134
+ display: block;
135
+ max-width: 100%;
136
+ }
137
+
138
+ .character {
139
+ font-size: 48px;
140
+ text-align: center;
141
+ margin: 10px 0;
142
+ }
143
+
144
+ .game-instructions {
145
+ background-color: #f0f8ff;
146
+ border-radius: 15px;
147
+ padding: 15px;
148
+ margin: 15px 0;
149
+ }
150
+
151
+ .ai-game {
152
+ border: 3px solid var(--accent);
153
+ border-radius: 15px;
154
+ padding: 15px;
155
+ background: white;
156
+ margin: 20px 0;
157
+ }
158
+ </style>
159
+ """, unsafe_allow_html=True)
160
+
161
+ # Concept database
162
+ CONCEPTS = {
163
+ "loop": {
164
+ "name": "Loop",
165
+ "emoji": "๐Ÿ”„",
166
+ "description": "Loops repeat actions multiple times",
167
+ "example": "for i in range(5):\n print('Hello!')",
168
+ "color": "#FF9E6D"
169
+ },
170
+ "conditional": {
171
+ "name": "Conditional",
172
+ "emoji": "โ“",
173
+ "description": "Conditionals make decisions in code",
174
+ "example": "if sunny:\n go_outside()\nelse:\n stay_inside()",
175
+ "color": "#4ECDC4"
176
+ },
177
+ "function": {
178
+ "name": "Function",
179
+ "emoji": "โœจ",
180
+ "description": "Functions are reusable blocks of code",
181
+ "example": "def greet(name):\n print(f'Hello {name}!')",
182
+ "color": "#FFD166"
183
+ },
184
+ "variable": {
185
+ "name": "Variable",
186
+ "emoji": "๐Ÿ“ฆ",
187
+ "description": "Variables store information",
188
+ "example": "score = 10\nplayer = 'Alex'",
189
+ "color": "#FF6B6B"
190
+ },
191
+ "list": {
192
+ "name": "List",
193
+ "emoji": "๐Ÿ“",
194
+ "description": "Lists store collections of items",
195
+ "example": "fruits = ['apple', 'banana', 'orange']",
196
+ "color": "#1A535C"
197
+ }
198
+ }
199
+
200
+ # Pre-generated game examples
201
+ GAME_EXAMPLES = {
202
+ "loop": {
203
+ "image": "https://placehold.co/600x400/orange/white?text=Loop+Game",
204
+ "description": "Collect coins in a looping maze"
205
+ },
206
+ "conditional": {
207
+ "image": "https://placehold.co/600x400/blue/white?text=Conditional+Game",
208
+ "description": "Avoid obstacles by making decisions"
209
+ },
210
+ "function": {
211
+ "image": "https://placehold.co/600x400/green/white?text=Function+Game",
212
+ "description": "Cast spells using reusable functions"
213
+ }
214
+ }
215
+
216
+ # Initialize Groq client
217
+ def get_groq_client():
218
+ api_key = st.secrets.get("GROQ_API_KEY", "")
219
+ if not api_key:
220
+ st.warning("Groq API key not found. Using simpler game generation.")
221
+ return None
222
+ try:
223
+ from groq import Groq
224
+ return Groq(api_key=api_key)
225
+ except ImportError:
226
+ st.error("Groq library not installed. Please install with `pip install groq`")
227
+ return None
228
+ except Exception as e:
229
+ st.error(f"Error initializing Groq client: {str(e)}")
230
+ return None
231
+
232
+ # Analyze story and identify programming concepts
233
+ def analyze_story(story):
234
+ story_lower = story.lower()
235
+ detected_concepts = []
236
+
237
+ # Check for loops
238
+ if any(word in story_lower for word in ["times", "repeat", "again", "multiple", "many"]):
239
+ detected_concepts.append("loop")
240
+
241
+ # Check for conditionals
242
+ if any(word in story_lower for word in ["if", "when", "unless", "whether", "decision"]):
243
+ detected_concepts.append("conditional")
244
+
245
+ # Check for functions
246
+ if any(word in story_lower for word in ["make", "create", "do", "perform", "cast", "spell"]):
247
+ detected_concepts.append("function")
248
+
249
+ # Check for variables
250
+ if any(word in story_lower for word in ["is", "has", "set to", "value", "store"]):
251
+ detected_concepts.append("variable")
252
+
253
+ # Check for lists
254
+ if any(word in story_lower for word in ["and", "many", "several", "collection", "items", "group"]):
255
+ detected_concepts.append("list")
256
+
257
+ return list(set(detected_concepts))
258
+
259
+ # Extract entities from story using regex
260
+ def extract_entities(story):
261
+ entities = {
262
+ "characters": [],
263
+ "objects": [],
264
+ "actions": [],
265
+ "locations": []
266
+ }
267
+
268
+ # Extract characters (proper nouns)
269
+ entities["characters"] = list(set(re.findall(r'\b[A-Z][a-z]+\b', story)))
270
+
271
+ # Extract objects (nouns after "the")
272
+ entities["objects"] = list(set(re.findall(r'\bthe\s+(\w+)', story, re.I)))
273
+
274
+ # Extract actions (verbs)
275
+ entities["actions"] = list(set(re.findall(r'\b(\w+ed|\w+ing)\b', story)))
276
+
277
+ # Extract locations (nouns after "in", "on", "at")
278
+ locations = re.findall(r'\b(in|on|at)\s+the?\s?(\w+)', story)
279
+ entities["locations"] = list(set([loc[1] for loc in locations]))
280
+
281
+ # Filter out common words
282
+ common_words = ["the", "a", "an", "and", "or", "but", "if", "then", "when", "where"]
283
+ for key in entities:
284
+ entities[key] = [word for word in entities[key]
285
+ if isinstance(word, str) and
286
+ word.lower() not in common_words and
287
+ len(word) > 2]
288
+
289
+ return entities
290
+
291
+ # Generate game concept using Groq
292
+ def generate_game_concept(story, concepts, entities):
293
+ groq_client = get_groq_client()
294
+ if not groq_client:
295
+ # Fallback concept
296
+ return {
297
+ "title": "Adventure Game",
298
+ "description": "An exciting game based on your story!",
299
+ "mechanics": "Collect items and avoid obstacles",
300
+ "code_concepts": ", ".join(concepts),
301
+ "instructions": "Use arrow keys to move and space to jump"
302
+ }
303
+
304
+ try:
305
+ prompt = f"""
306
+ You are a game designer creating educational games for kids aged 6-12.
307
+ Create a simple 2D game concept based on the following story:
308
+
309
+ Story: "{story}"
310
+
311
+ Programming concepts to include: {', '.join(concepts)}
312
+
313
+ Extracted entities:
314
+ - Characters: {', '.join(entities['characters'])}
315
+ - Objects: {', '.join(entities['objects'])}
316
+ - Actions: {', '.join(entities['actions'])}
317
+ - Locations: {', '.join(entities['locations'])}
318
+
319
+ Respond in JSON format with these keys:
320
+ - title: Game title (max 5 words)
321
+ - description: Game description (1-2 sentences)
322
+ - mechanics: Core game mechanics (1 sentence)
323
+ - code_concepts: How programming concepts are used in the game
324
+ - instructions: Simple game controls (max 10 words)
325
+ """
326
+
327
+ response = groq_client.chat.completions.create(
328
+ model="llama3-8b-8192",
329
+ messages=[{"role": "user", "content": prompt}],
330
+ temperature=0.7,
331
+ max_tokens=512,
332
+ response_format={"type": "json_object"}
333
+ )
334
+
335
+ game_data = json.loads(response.choices[0].message.content)
336
+ return game_data
337
+
338
+ except Exception as e:
339
+ st.error(f"Game concept generation error: {str(e)}")
340
+ return {
341
+ "title": "Adventure Game",
342
+ "description": "An exciting game based on your story!",
343
+ "mechanics": "Collect items and avoid obstacles",
344
+ "code_concepts": ", ".join(concepts),
345
+ "instructions": "Use arrow keys to move and space to jump"
346
+ }
347
+
348
+ # Generate game code using Groq
349
+ def generate_game_code(story, game_concept):
350
+ groq_client = get_groq_client()
351
+ if not groq_client:
352
+ # Fallback game code
353
+ return """# Simple Game Template
354
+ import pygame
355
+ import sys
356
+
357
+ # Initialize pygame
358
+ pygame.init()
359
+
360
+ # Set up display
361
+ WIDTH, HEIGHT = 800, 600
362
+ screen = pygame.display.set_mode((WIDTH, HEIGHT))
363
+ pygame.display.set_caption("Your Adventure Game")
364
+
365
+ # Colors
366
+ WHITE = (255, 255, 255)
367
+ BLUE = (0, 0, 255)
368
+ RED = (255, 0, 0)
369
+ GREEN = (0, 255, 0)
370
+
371
+ # Player
372
+ player = pygame.Rect(400, 300, 50, 50)
373
+ player_speed = 5
374
+
375
+ # Game loop
376
+ clock = pygame.time.Clock()
377
+ running = True
378
+
379
+ while running:
380
+ for event in pygame.event.get():
381
+ if event.type == pygame.QUIT:
382
+ running = False
383
+
384
+ # Player movement
385
+ keys = pygame.key.get_pressed()
386
+ if keys[pygame.K_LEFT]:
387
+ player.x -= player_speed
388
+ if keys[pygame.K_RIGHT]:
389
+ player.x += player_speed
390
+ if keys[pygame.K_UP]:
391
+ player.y -= player_speed
392
+ if keys[pygame.K_DOWN]:
393
+ player.y += player_speed
394
+
395
+ # Drawing
396
+ screen.fill(WHITE)
397
+ pygame.draw.rect(screen, BLUE, player)
398
+
399
+ # Display instructions
400
+ font = pygame.font.SysFont(None, 36)
401
+ text = font.render("Your Adventure Game - Move with arrow keys", True, (0, 0, 0))
402
+ screen.blit(text, (50, 50))
403
+
404
+ pygame.display.flip()
405
+ clock.tick(60)
406
+
407
+ pygame.quit()
408
+ sys.exit()
409
+ """, "Success"
410
+
411
+ try:
412
+ prompt = f"""
413
+ You are a Python game developer creating educational games for kids using Pygame.
414
+ Create a simple 2D game based on the following concept:
415
+
416
+ Game Title: {game_concept['title']}
417
+ Description: {game_concept['description']}
418
+ Mechanics: {game_concept['mechanics']}
419
+ Instructions: {game_concept['instructions']}
420
+
421
+ Requirements:
422
+ - Use Pygame library
423
+ - Simple graphics (shapes and colors)
424
+ - Include at least one character the player controls
425
+ - Include collectible items
426
+ - Include obstacles to avoid
427
+ - Score tracking
428
+ - Game over condition
429
+
430
+ Output ONLY the Python code with no additional text or explanations.
431
+ """
432
+
433
+ response = groq_client.chat.completions.create(
434
+ model="llama3-70b-8192",
435
+ messages=[{"role": "user", "content": prompt}],
436
+ temperature=0.5,
437
+ max_tokens=2048
438
+ )
439
+
440
+ game_code = response.choices[0].message.content
441
+
442
+ # Clean up the code
443
+ if "```python" in game_code:
444
+ game_code = game_code.split("```python")[1].split("```")[0]
445
+ elif "```" in game_code:
446
+ game_code = game_code.split("```")[1]
447
+
448
+ return game_code, "Success"
449
+
450
+ except Exception as e:
451
+ return f"# Error generating game code\nprint('{str(e)}')", str(e)
452
+
453
+ # Create placeholder game preview
454
+ def generate_game_preview(game_concept):
455
+ try:
456
+ # Create a simple placeholder image
457
+ img = Image.new('RGB', (600, 400), color=(73, 109, 137))
458
+
459
+ # Add text to the image
460
+ try:
461
+ from PIL import ImageDraw, ImageFont
462
+ draw = ImageDraw.Draw(img)
463
+
464
+ # Try to use a default font
465
+ try:
466
+ font = ImageFont.truetype("arial.ttf", 30)
467
+ except:
468
+ # Fallback to basic font
469
+ font = ImageFont.load_default()
470
+
471
+ title = f"{game_concept['title']}"
472
+ draw.text((150, 150), title, fill=(255, 255, 0), font=font)
473
+ draw.text((100, 200), "Game Preview", fill=(255, 255, 255), font=font)
474
+ except:
475
+ pass
476
+
477
+ # Convert to bytes
478
+ buf = io.BytesIO()
479
+ img.save(buf, format='PNG')
480
+ buf.seek(0)
481
+ return buf
482
+
483
+ except Exception as e:
484
+ st.error(f"Game preview generation error: {str(e)}")
485
+ return None
486
+
487
+ # Create interactive visualization of game mechanics
488
+ def create_game_visualization(game_concept):
489
+ try:
490
+ # Create a simple visualization using Plotly
491
+ fig = go.Figure()
492
+
493
+ # Add player character
494
+ fig.add_trace(go.Scatter(
495
+ x=[0.5], y=[0.5],
496
+ mode='markers+text',
497
+ marker=dict(size=50, color='blue'),
498
+ text='Player',
499
+ textposition='bottom center',
500
+ name='Player'
501
+ ))
502
+
503
+ # Add collectibles
504
+ for i in range(5):
505
+ fig.add_trace(go.Scatter(
506
+ x=[random.uniform(0.2, 0.8)], y=[random.uniform(0.2, 0.8)],
507
+ mode='markers',
508
+ marker=dict(size=30, color='gold', symbol='star'),
509
+ name='Collectible'
510
+ ))
511
+
512
+ # Add obstacles
513
+ for i in range(3):
514
+ fig.add_trace(go.Scatter(
515
+ x=[random.uniform(0.1, 0.9)], y=[random.uniform(0.1, 0.9)],
516
+ mode='markers',
517
+ marker=dict(size=40, color='red', symbol='x'),
518
+ name='Obstacle'
519
+ ))
520
+
521
+ # Update layout
522
+ fig.update_layout(
523
+ title=f"Game Visualization: {game_concept.get('title', 'Your Game')}",
524
+ xaxis=dict(showgrid=False, zeroline=False, visible=False, range=[0, 1]),
525
+ yaxis=dict(showgrid=False, zeroline=False, visible=False, range=[0, 1]),
526
+ showlegend=False,
527
+ margin=dict(l=20, r=20, t=40, b=20),
528
+ height=400,
529
+ paper_bgcolor='rgba(0,0,0,0)',
530
+ plot_bgcolor='rgba(0,0,0,0)'
531
+ )
532
+
533
+ return fig
534
+
535
+ except Exception as e:
536
+ st.error(f"Visualization error: {str(e)}")
537
+ return None
538
+
539
+ def main():
540
+ """Main application function"""
541
+ st.title("๐Ÿง™โ€โ™‚๏ธ StoryCoder - Learn Coding Through Games!")
542
+ st.subheader("Turn your story into a game and discover coding secrets!")
543
+
544
+ # Initialize session state
545
+ if 'story' not in st.session_state:
546
+ st.session_state.story = ""
547
+ if 'concepts' not in st.session_state:
548
+ st.session_state.concepts = []
549
+ if 'entities' not in st.session_state:
550
+ st.session_state.entities = {}
551
+ if 'game_concept' not in st.session_state:
552
+ st.session_state.game_concept = {}
553
+ if 'game_code' not in st.session_state:
554
+ st.session_state.game_code = ""
555
+ if 'game_preview' not in st.session_state:
556
+ st.session_state.game_preview = None
557
+ if 'active_tab' not in st.session_state:
558
+ st.session_state.active_tab = "story"
559
+
560
+ # Create tabs
561
+ tab_cols = st.columns(5)
562
+ with tab_cols[0]:
563
+ if st.button("๐Ÿ“– Create Story"):
564
+ st.session_state.active_tab = "story"
565
+ with tab_cols[1]:
566
+ if st.button("๐ŸŽฎ Game"):
567
+ st.session_state.active_tab = "game"
568
+ with tab_cols[2]:
569
+ if st.button("๐Ÿ” Concepts"):
570
+ st.session_state.active_tab = "concepts"
571
+ with tab_cols[3]:
572
+ if st.button("๐Ÿ’ป Code"):
573
+ st.session_state.active_tab = "code"
574
+ with tab_cols[4]:
575
+ if st.button("๐Ÿ”„ Reset"):
576
+ for key in list(st.session_state.keys()):
577
+ if key != 'active_tab':
578
+ del st.session_state[key]
579
+ st.session_state.active_tab = "story"
580
+ st.rerun()
581
+
582
+ # Story creation tab
583
+ if st.session_state.active_tab == "story":
584
+ with st.container():
585
+ st.header("๐Ÿ“– Create Your Story")
586
+ st.write("Write a short story (2-5 sentences) and I'll turn it into a game!")
587
+
588
+ story = st.text_area(
589
+ "Your story:",
590
+ height=200,
591
+ placeholder="Once upon a time, a rabbit named Ruby needed to collect 5 magical carrots in the enchanted forest while avoiding mischievous squirrels...",
592
+ value=st.session_state.story,
593
+ key="story_input"
594
+ )
595
+
596
+ if st.button("Create Game!", use_container_width=True):
597
+ if len(story) < 20:
598
+ st.error("Your story needs to be at least 20 characters long!")
599
+ else:
600
+ st.session_state.story = story
601
+ with st.spinner("๐Ÿง  Analyzing your story..."):
602
+ st.session_state.concepts = analyze_story(story)
603
+ st.session_state.entities = extract_entities(story)
604
+
605
+ with st.spinner("๐ŸŽฎ Designing your game..."):
606
+ st.session_state.game_concept = generate_game_concept(
607
+ story,
608
+ st.session_state.concepts,
609
+ st.session_state.entities
610
+ )
611
+
612
+ with st.spinner("๐Ÿ‘พ Generating game preview..."):
613
+ st.session_state.game_preview = generate_game_preview(
614
+ st.session_state.game_concept
615
+ )
616
+
617
+ with st.spinner("๐Ÿ’ป Creating game code..."):
618
+ st.session_state.game_code, error = generate_game_code(
619
+ story,
620
+ st.session_state.game_concept
621
+ )
622
+ if error and "Error" in error:
623
+ st.error(f"Code generation error: {error}")
624
+
625
+ st.session_state.active_tab = "game"
626
+ st.rerun()
627
+
628
+ # Show examples
629
+ st.subheader("โœจ Story Examples")
630
+ col1, col2, col3 = st.columns(3)
631
+ with col1:
632
+ st.caption("Loop Example")
633
+ st.code('"Ruby the rabbit needs to collect 5 magical carrots that appear every 10 seconds in the enchanted forest"', language="text")
634
+ st.image(GAME_EXAMPLES["loop"]["image"],
635
+ use_container_width=True,
636
+ caption=GAME_EXAMPLES["loop"]["description"])
637
+ with col2:
638
+ st.caption("Conditional Example")
639
+ st.code('"If Alex the wizard sees a dragon, he casts a fire spell, otherwise he walks forward to find treasures"', language="text")
640
+ st.image(GAME_EXAMPLES["conditional"]["image"],
641
+ use_container_width=True,
642
+ caption=GAME_EXAMPLES["conditional"]["description"])
643
+ with col3:
644
+ st.caption("Function Example")
645
+ st.code('"Wizard Lily creates magic spells to solve puzzles - each spell is a special function"', language="text")
646
+ st.image(GAME_EXAMPLES["function"]["image"],
647
+ use_container_width=True,
648
+ caption=GAME_EXAMPLES["function"]["description"])
649
+
650
+ # Game tab
651
+ elif st.session_state.active_tab == "game":
652
+ st.header("๐ŸŽฎ Your Story Game")
653
+
654
+ if not st.session_state.get('story'):
655
+ st.warning("Please create a story first!")
656
+ st.session_state.active_tab = "story"
657
+ st.rerun()
658
+
659
+ # Display game concept
660
+ st.subheader(f"โœจ {st.session_state.game_concept.get('title', 'Your Adventure Game')}")
661
+ st.write(st.session_state.game_concept.get('description', 'An exciting game based on your story!'))
662
+
663
+ # Display game preview
664
+ st.subheader("๐Ÿ–ผ๏ธ Game Preview")
665
+ if st.session_state.game_preview:
666
+ st.image(st.session_state.game_preview, use_container_width=True)
667
+ else:
668
+ concept = st.session_state.concepts[0] if st.session_state.concepts else "loop"
669
+ st.image(GAME_EXAMPLES[concept]["image"],
670
+ use_container_width=True,
671
+ caption="Example game preview")
672
+
673
+ # Game mechanics visualization
674
+ st.subheader("๐ŸŽฎ Game Mechanics")
675
+ if st.session_state.game_concept:
676
+ fig = create_game_visualization(st.session_state.game_concept)
677
+ if fig:
678
+ st.plotly_chart(fig, use_container_width=True)
679
+ else:
680
+ st.info("Game mechanics visualization would appear here")
681
+
682
+ # Game instructions
683
+ st.subheader("๐Ÿ“œ How to Play")
684
+ st.markdown(f"""
685
+ <div class="game-instructions">
686
+ <h4>Game Controls:</h4>
687
+ <p>{st.session_state.game_concept.get('instructions', 'Use arrow keys to move and space to jump')}</p>
688
+
689
+ <h4>Game Mechanics:</h4>
690
+ <p>{st.session_state.game_concept.get('mechanics', 'Collect items and avoid obstacles')}</p>
691
+
692
+ <h4>Coding Concepts:</h4>
693
+ <p>{st.session_state.game_concept.get('code_concepts', 'Loops, conditionals, and functions')}</p>
694
+ </div>
695
+ """, unsafe_allow_html=True)
696
+
697
+ if st.button("Show Coding Secrets!", use_container_width=True):
698
+ st.session_state.active_tab = "concepts"
699
+ st.rerun()
700
+
701
+ # Concepts tab
702
+ elif st.session_state.active_tab == "concepts":
703
+ st.header("๐Ÿ” Coding Concepts in Your Game")
704
+ st.subheader("We used these programming concepts in your game:")
705
+
706
+ if not st.session_state.concepts:
707
+ st.warning("No concepts detected in your story! Try adding words like '3 times', 'if', or 'make'.")
708
+ else:
709
+ for concept in st.session_state.concepts:
710
+ if concept in CONCEPTS:
711
+ details = CONCEPTS[concept]
712
+ st.markdown(f"""
713
+ <div class="concept-card" style="border-left: 5px solid {details['color']};">
714
+ <div style="display:flex; align-items:center; gap:15px;">
715
+ <span style="font-size:36px;">{details['emoji']}</span>
716
+ <h3 style="color:{details['color']};">{details['name']}</h3>
717
+ </div>
718
+ <p>{details['description']}</p>
719
+ <pre style="background:#f0f0f0; padding:10px; border-radius:8px;">{details['example']}</pre>
720
+ </div>
721
+ """, unsafe_allow_html=True)
722
+
723
+ st.subheader("๐ŸŽฎ How Concepts Are Used in Your Game")
724
+ st.write(st.session_state.game_concept.get('code_concepts', 'These concepts power the mechanics of your game'))
725
+
726
+ if st.button("See the Game Code!", use_container_width=True):
727
+ st.session_state.active_tab = "code"
728
+ st.rerun()
729
+
730
+ # Code tab
731
+ elif st.session_state.active_tab == "code":
732
+ st.header("๐Ÿ’ป Game Code")
733
+ st.write("Here's the Python code for your game. You can run it on your computer!")
734
+
735
+ if st.session_state.game_code:
736
+ st.subheader("๐ŸŽฎ Game Implementation")
737
+ st.code(st.session_state.game_code, language="python")
738
+
739
+ # Download button
740
+ st.download_button(
741
+ label="Download Game Code",
742
+ data=st.session_state.game_code,
743
+ file_name="story_game.py",
744
+ mime="text/python",
745
+ use_container_width=True
746
+ )
747
+
748
+ st.info("๐Ÿ’ก How to run your game:")
749
+ st.markdown("""
750
+ 1. Install Python from [python.org](https://python.org)
751
+ 2. Install Pygame: `pip install pygame`
752
+ 3. Download the code above
753
+ 4. Run it with: `python story_game.py`
754
+ """)
755
+
756
+ st.success("๐ŸŽ‰ When you run this code, you'll see your story come to life as a playable game!")
757
+
758
+ # Game preview
759
+ st.subheader("๐ŸŽฎ What Your Game Looks Like")
760
+ concept = st.session_state.concepts[0] if st.session_state.concepts else "loop"
761
+ st.image(GAME_EXAMPLES[concept]["image"],
762
+ caption="Your game will look similar to this",
763
+ use_container_width=True)
764
+ else:
765
+ st.warning("No game code generated yet!")
766
+
767
+ if st.button("Create Another Game!", use_container_width=True):
768
+ st.session_state.active_tab = "story"
769
+ st.session_state.story = ""
770
+ st.rerun()
771
+
772
+ if __name__ == "__main__":
773
+ main()