Spaces:
Sleeping
Sleeping
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>
|