Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
# app.py -
|
2 |
import streamlit as st
|
3 |
import os
|
4 |
import time
|
@@ -10,8 +10,7 @@ import re
|
|
10 |
from PIL import Image
|
11 |
import io
|
12 |
import matplotlib.pyplot as plt
|
13 |
-
from transformers import pipeline
|
14 |
-
import torch
|
15 |
|
16 |
# Configure Streamlit page
|
17 |
st.set_page_config(
|
@@ -201,7 +200,7 @@ def init_session_state():
|
|
201 |
if 'game_explanation' not in st.session_state:
|
202 |
st.session_state.game_explanation = ""
|
203 |
if 'game_preview' not in st.session_state:
|
204 |
-
st.session_state.game_preview =
|
205 |
if 'active_tab' not in st.session_state:
|
206 |
st.session_state.active_tab = "story"
|
207 |
if 'loading' not in st.session_state:
|
@@ -251,13 +250,12 @@ CONCEPTS = {
|
|
251 |
}
|
252 |
}
|
253 |
|
254 |
-
# Load
|
255 |
-
@st.cache_resource
|
256 |
def load_text_generator():
|
257 |
-
"""Load a
|
258 |
try:
|
259 |
-
|
260 |
-
return pipeline("text-generation", model="gpt2")
|
261 |
except:
|
262 |
return None
|
263 |
|
@@ -292,104 +290,67 @@ def analyze_story(story):
|
|
292 |
# Generate game scenario using free models
|
293 |
def generate_game_scenario(story, concepts):
|
294 |
"""Generate a game scenario based on the story and concepts"""
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
# Fallback scenario
|
324 |
-
concept_names = [CONCEPTS[c]["name"] for c in concepts]
|
325 |
-
return (
|
326 |
-
f"Game Title: {story[:20]} Adventure\n\n"
|
327 |
-
f"Game Objective: Complete challenges based on the story: {story[:100]}...\n\n"
|
328 |
-
"Characters: Hero character based on the story\n\n"
|
329 |
-
"Game Mechanics: Navigate through levels, collect items, solve puzzles\n\n"
|
330 |
-
f"Coding Concepts: This game teaches {', '.join(concept_names)} through gameplay\n\n"
|
331 |
-
"Visual Description: Colorful 3D world with characters and obstacles"
|
332 |
-
)
|
333 |
|
334 |
# Generate game code explanation
|
335 |
def generate_game_explanation(story, concepts, game_scenario):
|
336 |
"""Generate explanation of game code"""
|
337 |
-
|
338 |
-
# Create prompt
|
339 |
-
prompt = (
|
340 |
-
f"Explain how a game based on this story teaches programming concepts to children: {story}\n"
|
341 |
-
f"Game Scenario: {game_scenario}\n"
|
342 |
-
f"Concepts: {', '.join(concepts)}\n"
|
343 |
-
"Use simple language and analogies for kids aged 6-12."
|
344 |
-
)
|
345 |
-
|
346 |
-
# Generate with free model
|
347 |
-
generator = load_text_generator()
|
348 |
-
if generator:
|
349 |
-
result = generator(
|
350 |
-
prompt,
|
351 |
-
max_length=300,
|
352 |
-
do_sample=True,
|
353 |
-
temperature=0.7,
|
354 |
-
num_return_sequences=1
|
355 |
-
)
|
356 |
-
return result[0]['generated_text']
|
357 |
-
except:
|
358 |
-
pass
|
359 |
-
|
360 |
-
# Fallback explanation
|
361 |
concept_explanations = "\n".join(
|
362 |
[f"- {CONCEPTS[c]['name']}: {CONCEPTS[c]['game_example']}" for c in concepts]
|
363 |
)
|
364 |
-
return
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
369 |
|
370 |
# Generate simple game code
|
371 |
def generate_game_code(story, concepts):
|
372 |
"""Generate simple PyGame code for the game"""
|
373 |
-
#
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
character = "knight"
|
380 |
-
goal = "dragon"
|
381 |
-
elif "space" in story.lower():
|
382 |
-
character = "astronaut"
|
383 |
-
goal = "planet"
|
384 |
-
elif "jungle" in story.lower():
|
385 |
-
character = "explorer"
|
386 |
-
goal = "temple"
|
387 |
-
|
388 |
-
# Generate dynamic game code
|
389 |
return f"""
|
390 |
# {story[:30]} Adventure Game
|
391 |
import pygame
|
392 |
import random
|
|
|
393 |
|
394 |
# Initialize pygame
|
395 |
pygame.init()
|
@@ -397,14 +358,15 @@ pygame.init()
|
|
397 |
# Game setup
|
398 |
WIDTH, HEIGHT = 800, 600
|
399 |
screen = pygame.display.set_mode((WIDTH, HEIGHT))
|
400 |
-
pygame.display.set_caption("{
|
401 |
clock = pygame.time.Clock()
|
402 |
|
403 |
# Colors
|
404 |
BACKGROUND = (173, 216, 230) # Light blue
|
405 |
PLAYER_COLOR = (255, 0, 0) # Red
|
406 |
-
GOAL_COLOR = (
|
407 |
OBSTACLE_COLOR = (139, 69, 19) # Brown
|
|
|
408 |
|
409 |
# Player setup
|
410 |
player_size = 50
|
@@ -481,28 +443,29 @@ while running:
|
|
481 |
(goal_x, goal_y, goal_size, goal_size))
|
482 |
|
483 |
# Display score
|
484 |
-
score_text = font.render(f"
|
485 |
screen.blit(score_text, (20, 20))
|
486 |
|
487 |
-
# Display
|
488 |
-
|
489 |
-
screen.blit(
|
|
|
|
|
|
|
|
|
490 |
|
491 |
# Update display
|
492 |
pygame.display.flip()
|
493 |
clock.tick(60)
|
494 |
|
495 |
pygame.quit()
|
|
|
496 |
"""
|
497 |
|
498 |
# Generate game preview visualization
|
499 |
-
def generate_game_preview(
|
500 |
"""Generate a visual preview of the game"""
|
501 |
try:
|
502 |
-
# Extract title from game scenario
|
503 |
-
title_match = re.search(r"Game Title: (.+)", game_scenario)
|
504 |
-
title = title_match.group(1) if title_match else "Your Adventure"
|
505 |
-
|
506 |
# Create a simple visualization
|
507 |
fig, ax = plt.subplots(figsize=(10, 6))
|
508 |
ax.set_facecolor('#a2d2ff')
|
@@ -510,33 +473,37 @@ def generate_game_preview(game_scenario):
|
|
510 |
ax.set_ylim(0, 6)
|
511 |
|
512 |
# Draw game elements
|
513 |
-
ax.text(5, 5,
|
514 |
ax.plot([1, 9], [3, 3], 'k-', linewidth=2) # Ground
|
515 |
|
516 |
# Player character
|
517 |
ax.plot(2, 3.5, 'ro', markersize=15)
|
|
|
518 |
|
519 |
# Goal
|
520 |
-
ax.plot(8, 3.5, '
|
|
|
521 |
|
522 |
# Obstacles
|
523 |
for i in range(3):
|
524 |
x = random.uniform(3, 7)
|
525 |
y = random.uniform(3.2, 4)
|
526 |
ax.plot(x, y, 's', color='#8d99ae', markersize=12)
|
|
|
527 |
|
528 |
# Path
|
529 |
ax.plot([2, 8], [3.5, 3.5], 'y--', linewidth=2)
|
530 |
|
531 |
ax.axis('off')
|
532 |
-
ax.set_title("Game Preview", fontsize=
|
533 |
|
534 |
# Save to bytes
|
535 |
buf = io.BytesIO()
|
536 |
plt.savefig(buf, format='png', dpi=100, bbox_inches='tight')
|
537 |
buf.seek(0)
|
538 |
return buf
|
539 |
-
except:
|
|
|
540 |
return None
|
541 |
|
542 |
# Main application function
|
@@ -568,7 +535,7 @@ def main():
|
|
568 |
st.session_state.game_scenario = ""
|
569 |
st.session_state.game_code = ""
|
570 |
st.session_state.game_explanation = ""
|
571 |
-
st.session_state.game_preview =
|
572 |
st.session_state.active_tab = "story"
|
573 |
st.markdown('</div>', unsafe_allow_html=True)
|
574 |
|
@@ -612,9 +579,7 @@ def main():
|
|
612 |
)
|
613 |
|
614 |
with st.spinner("🖼️ Generating game preview..."):
|
615 |
-
|
616 |
-
if preview:
|
617 |
-
st.session_state.game_preview = preview
|
618 |
|
619 |
st.session_state.active_tab = "game"
|
620 |
st.session_state.loading = False
|
@@ -660,7 +625,7 @@ def main():
|
|
660 |
if st.session_state.game_preview:
|
661 |
st.image(st.session_state.game_preview, use_container_width=True)
|
662 |
else:
|
663 |
-
st.
|
664 |
st.image("https://i.imgur.com/7zQY1eE.gif", use_container_width=True)
|
665 |
|
666 |
# Game explanation
|
@@ -751,7 +716,7 @@ def main():
|
|
751 |
<div class="game-card">
|
752 |
<ul>
|
753 |
<li>Move your character (red square) with arrow keys</li>
|
754 |
-
<li>Collect the
|
755 |
<li>Avoid the brown obstacles</li>
|
756 |
<li>See how programming concepts make the game work!</li>
|
757 |
</ul>
|
|
|
1 |
+
# app.py - Fixed Version with Free Models
|
2 |
import streamlit as st
|
3 |
import os
|
4 |
import time
|
|
|
10 |
from PIL import Image
|
11 |
import io
|
12 |
import matplotlib.pyplot as plt
|
13 |
+
from transformers import pipeline, set_seed
|
|
|
14 |
|
15 |
# Configure Streamlit page
|
16 |
st.set_page_config(
|
|
|
200 |
if 'game_explanation' not in st.session_state:
|
201 |
st.session_state.game_explanation = ""
|
202 |
if 'game_preview' not in st.session_state:
|
203 |
+
st.session_state.game_preview = None
|
204 |
if 'active_tab' not in st.session_state:
|
205 |
st.session_state.active_tab = "story"
|
206 |
if 'loading' not in st.session_state:
|
|
|
250 |
}
|
251 |
}
|
252 |
|
253 |
+
# Load text generation model
|
254 |
+
@st.cache_resource(show_spinner=False)
|
255 |
def load_text_generator():
|
256 |
+
"""Load a lightweight text generation model"""
|
257 |
try:
|
258 |
+
return pipeline('text-generation', model='gpt2', framework='pt', device=-1)
|
|
|
259 |
except:
|
260 |
return None
|
261 |
|
|
|
290 |
# Generate game scenario using free models
|
291 |
def generate_game_scenario(story, concepts):
|
292 |
"""Generate a game scenario based on the story and concepts"""
|
293 |
+
# Create a simple template-based scenario
|
294 |
+
concept_names = [CONCEPTS[c]['name'] for c in concepts]
|
295 |
+
concept_list = ", ".join(concept_names)
|
296 |
+
|
297 |
+
return f"""
|
298 |
+
Game Title: {story[:15]} Adventure
|
299 |
+
Game Objective: Complete challenges based on the story: {story[:100]}...
|
300 |
+
Characters:
|
301 |
+
- Hero: The main character from your story
|
302 |
+
- Helper: A friendly guide who explains coding concepts
|
303 |
+
- Villain: A character that creates obstacles (if applicable)
|
304 |
+
|
305 |
+
Game Mechanics:
|
306 |
+
1. The player controls the hero using arrow keys
|
307 |
+
2. Collect items mentioned in the story
|
308 |
+
3. Avoid obstacles and solve simple puzzles
|
309 |
+
4. Helper characters appear to teach {concept_list}
|
310 |
+
|
311 |
+
Coding Concepts: This game teaches {concept_list} through:
|
312 |
+
- Using loops to repeat actions
|
313 |
+
- Making decisions with conditionals
|
314 |
+
- Creating reusable functions
|
315 |
+
- Tracking progress with variables
|
316 |
+
- Managing collections with lists
|
317 |
+
|
318 |
+
Visual Description: Colorful 3D world with cartoon-style characters, vibrant landscapes, and magical effects.
|
319 |
+
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
320 |
|
321 |
# Generate game code explanation
|
322 |
def generate_game_explanation(story, concepts, game_scenario):
|
323 |
"""Generate explanation of game code"""
|
324 |
+
# Create simple explanation based on concepts
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
325 |
concept_explanations = "\n".join(
|
326 |
[f"- {CONCEPTS[c]['name']}: {CONCEPTS[c]['game_example']}" for c in concepts]
|
327 |
)
|
328 |
+
return f"""
|
329 |
+
In this game based on your story "{story[:20]}...", we use programming concepts to make it work:
|
330 |
+
|
331 |
+
{concept_explanations}
|
332 |
+
|
333 |
+
As you play the game, think about:
|
334 |
+
1. How the game uses these concepts to create challenges
|
335 |
+
2. How you might change the code to make the game easier or harder
|
336 |
+
|
337 |
+
The code brings your story to life in a 3D game world!
|
338 |
+
"""
|
339 |
|
340 |
# Generate simple game code
|
341 |
def generate_game_code(story, concepts):
|
342 |
"""Generate simple PyGame code for the game"""
|
343 |
+
# Generate a unique game based on story keywords
|
344 |
+
keywords = re.findall(r'\b\w{4,}\b', story)[:3]
|
345 |
+
player_char = keywords[0] if keywords else "hero"
|
346 |
+
collect_item = keywords[1] if len(keywords) > 1 else "star"
|
347 |
+
obstacle = keywords[2] if len(keywords) > 2 else "rock"
|
348 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
349 |
return f"""
|
350 |
# {story[:30]} Adventure Game
|
351 |
import pygame
|
352 |
import random
|
353 |
+
import sys
|
354 |
|
355 |
# Initialize pygame
|
356 |
pygame.init()
|
|
|
358 |
# Game setup
|
359 |
WIDTH, HEIGHT = 800, 600
|
360 |
screen = pygame.display.set_mode((WIDTH, HEIGHT))
|
361 |
+
pygame.display.set_caption("{player_char.capitalize()} Adventure")
|
362 |
clock = pygame.time.Clock()
|
363 |
|
364 |
# Colors
|
365 |
BACKGROUND = (173, 216, 230) # Light blue
|
366 |
PLAYER_COLOR = (255, 0, 0) # Red
|
367 |
+
GOAL_COLOR = (255, 223, 0) # Gold
|
368 |
OBSTACLE_COLOR = (139, 69, 19) # Brown
|
369 |
+
TEXT_COLOR = (0, 0, 0) # Black
|
370 |
|
371 |
# Player setup
|
372 |
player_size = 50
|
|
|
443 |
(goal_x, goal_y, goal_size, goal_size))
|
444 |
|
445 |
# Display score
|
446 |
+
score_text = font.render(f"{collect_item.capitalize()}s: {{score}}", True, TEXT_COLOR)
|
447 |
screen.blit(score_text, (20, 20))
|
448 |
|
449 |
+
# Display story title
|
450 |
+
title_text = font.render(f"{player_char.capitalize()} Adventure", True, TEXT_COLOR)
|
451 |
+
screen.blit(title_text, (WIDTH // 2 - 100, 20))
|
452 |
+
|
453 |
+
# Display instructions
|
454 |
+
help_text = font.render("Arrow keys to move - Collect the gold squares!", True, TEXT_COLOR)
|
455 |
+
screen.blit(help_text, (WIDTH // 2 - 200, HEIGHT - 40))
|
456 |
|
457 |
# Update display
|
458 |
pygame.display.flip()
|
459 |
clock.tick(60)
|
460 |
|
461 |
pygame.quit()
|
462 |
+
sys.exit()
|
463 |
"""
|
464 |
|
465 |
# Generate game preview visualization
|
466 |
+
def generate_game_preview():
|
467 |
"""Generate a visual preview of the game"""
|
468 |
try:
|
|
|
|
|
|
|
|
|
469 |
# Create a simple visualization
|
470 |
fig, ax = plt.subplots(figsize=(10, 6))
|
471 |
ax.set_facecolor('#a2d2ff')
|
|
|
473 |
ax.set_ylim(0, 6)
|
474 |
|
475 |
# Draw game elements
|
476 |
+
ax.text(5, 5, "Your Adventure", fontsize=20, ha='center', color='#9b5de5')
|
477 |
ax.plot([1, 9], [3, 3], 'k-', linewidth=2) # Ground
|
478 |
|
479 |
# Player character
|
480 |
ax.plot(2, 3.5, 'ro', markersize=15)
|
481 |
+
ax.text(2, 4, 'Player', ha='center')
|
482 |
|
483 |
# Goal
|
484 |
+
ax.plot(8, 3.5, 'yo', markersize=15)
|
485 |
+
ax.text(8, 4, 'Goal', ha='center')
|
486 |
|
487 |
# Obstacles
|
488 |
for i in range(3):
|
489 |
x = random.uniform(3, 7)
|
490 |
y = random.uniform(3.2, 4)
|
491 |
ax.plot(x, y, 's', color='#8d99ae', markersize=12)
|
492 |
+
ax.text(x, y+0.3, 'Obstacle', ha='center', fontsize=8)
|
493 |
|
494 |
# Path
|
495 |
ax.plot([2, 8], [3.5, 3.5], 'y--', linewidth=2)
|
496 |
|
497 |
ax.axis('off')
|
498 |
+
ax.set_title("Game Preview - Move player to collect goals while avoiding obstacles", fontsize=14)
|
499 |
|
500 |
# Save to bytes
|
501 |
buf = io.BytesIO()
|
502 |
plt.savefig(buf, format='png', dpi=100, bbox_inches='tight')
|
503 |
buf.seek(0)
|
504 |
return buf
|
505 |
+
except Exception as e:
|
506 |
+
st.error(f"Preview generation error: {str(e)}")
|
507 |
return None
|
508 |
|
509 |
# Main application function
|
|
|
535 |
st.session_state.game_scenario = ""
|
536 |
st.session_state.game_code = ""
|
537 |
st.session_state.game_explanation = ""
|
538 |
+
st.session_state.game_preview = None
|
539 |
st.session_state.active_tab = "story"
|
540 |
st.markdown('</div>', unsafe_allow_html=True)
|
541 |
|
|
|
579 |
)
|
580 |
|
581 |
with st.spinner("🖼️ Generating game preview..."):
|
582 |
+
st.session_state.game_preview = generate_game_preview()
|
|
|
|
|
583 |
|
584 |
st.session_state.active_tab = "game"
|
585 |
st.session_state.loading = False
|
|
|
625 |
if st.session_state.game_preview:
|
626 |
st.image(st.session_state.game_preview, use_container_width=True)
|
627 |
else:
|
628 |
+
st.info("Game preview visualization")
|
629 |
st.image("https://i.imgur.com/7zQY1eE.gif", use_container_width=True)
|
630 |
|
631 |
# Game explanation
|
|
|
716 |
<div class="game-card">
|
717 |
<ul>
|
718 |
<li>Move your character (red square) with arrow keys</li>
|
719 |
+
<li>Collect the gold squares to increase your score</li>
|
720 |
<li>Avoid the brown obstacles</li>
|
721 |
<li>See how programming concepts make the game work!</li>
|
722 |
</ul>
|