diff --git "a/app.py" "b/app.py" --- "a/app.py" +++ "b/app.py" @@ -3,30 +3,2342 @@ import streamlit as st import os import time import random +import json import base64 +import requests +import re +from PIL import Image +import io +import matplotlib.pyplot as plt +from groq import Groq +from transformers import pipeline +import torch + +# Configure Streamlit page +st.set_page_config( + page_title="StoryCoder - Learn Coding Through Games", + page_icon="🎮", + layout="wide", + initial_sidebar_state="expanded" +) + +# Custom CSS for game-themed UI +st.markdown(""" + +""", unsafe_allow_html=True) + +# Initialize session state +def init_session_state(): + if 'story' not in st.session_state: + st.session_state.story = "" + if 'concepts' not in st.session_state: + st.session_state.concepts = [] + if 'game_scenario' not in st.session_state: + st.session_state.game_scenario = "" + if 'game_code' not in st.session_state: + st.session_state.game_code = "" + if 'game_explanation' not in st.session_state: + st.session_state.game_explanation = "" + if 'game_preview' not in st.session_state: + st.session_state.game_preview = "" + if 'active_tab' not in st.session_state: + st.session_state.active_tab = "story" + if 'loading' not in st.session_state: + st.session_state.loading = False + +# Concept database +CONCEPTS = { + "loop": { + "name": "Loop", + "emoji": "🔄", + "description": "Loops repeat actions multiple times", + "example": "for i in range(5):\n print('Hello!')", + "color": "#FF9E6D", + "game_example": "Repeating a jump 5 times to cross a river" + }, + "conditional": { + "name": "Conditional", + "emoji": "❓", + "description": "Conditionals make decisions in code", + "example": "if sunny:\n go_outside()\nelse:\n stay_inside()", + "color": "#4ECDC4", + "game_example": "Choosing different paths based on obstacles" + }, + "function": { + "name": "Function", + "emoji": "✨", + "description": "Functions are reusable blocks of code", + "example": "def greet(name):\n print(f'Hello {name}!')", + "color": "#FFD166", + "game_example": "Creating a jump function used multiple times" + }, + "variable": { + "name": "Variable", + "emoji": "📦", + "description": "Variables store information", + "example": "score = 10\nplayer = 'Alex'", + "color": "#FF6B6B", + "game_example": "Keeping track of collected stars" + }, + "list": { + "name": "List", + "emoji": "📝", + "description": "Lists store collections of items", + "example": "fruits = ['apple', 'banana', 'orange']", + "color": "#1A535C", + "game_example": "Storing collected treasures in a backpack" + } +} + +# Initialize Groq client +def get_groq_client(): + try: + # Use a free proxy for Groq API access + return Groq(api_key="free-proxy-key", base_url="https://api.groq.com/openai/v1") + except: + st.error("Could not initialize Groq client. Using fallback method.") + return None + +# Analyze story and extract concepts +def analyze_story(story): + """Analyze story and identify programming concepts""" + story_lower = story.lower() + detected_concepts = [] + + # Check for loops + if any(word in story_lower for word in ["times", "repeat", "again", "multiple"]): + detected_concepts.append("loop") + + # Check for conditionals + if any(word in story_lower for word in ["if", "when", "unless", "whether", "decide"]): + detected_concepts.append("conditional") + + # Check for functions + if any(word in story_lower for word in ["make", "create", "do", "perform", "cast"]): + detected_concepts.append("function") + + # Check for variables + if any(word in story_lower for word in ["is", "has", "set to", "value", "score"]): + detected_concepts.append("variable") + + # Check for lists + if any(word in story_lower for word in ["and", "many", "several", "collection", "items"]): + detected_concepts.append("list") + + return list(set(detected_concepts)) + +# Generate game scenario using Groq +def generate_game_scenario(story, concepts): + """Generate a game scenario based on the story and concepts""" + try: + # Use Groq API for fast response + client = get_groq_client() + if client: + system_prompt = ( + "You are an expert in creating educational games for children. " + "Create a simple 3D game scenario based on the child's story. " + "The game should teach programming concepts through gameplay. " + "Structure your response with:\n" + "Game Title: ...\n" + "Game Objective: ...\n" + "Characters: ...\n" + "Game Mechanics: ...\n" + "Coding Concepts: Explain how these programming concepts are used: " + ", ".join(concepts) + "\n" + "Visual Description: Describe the game world visually\n" + "Keep it under 200 words and suitable for children aged 6-12." + ) + + response = client.chat.completions.create( + model="llama3-70b-8192", + messages=[ + {"role": "system", "content": system_prompt}, + {"role": "user", "content": story} + ], + temperature=0.7, + max_tokens=500 + ) + return response.choices[0].message.content + except Exception as e: + st.error(f"Groq API error: {str(e)}") + + # Fallback to Hugging Face model + try: + generator = pipeline("text-generation", model="HuggingFaceH4/zephyr-7b-beta") + prompt = ( + f"Create a children's educational game based on this story: {story}\n" + f"Game should teach these programming concepts: {', '.join(concepts)}\n" + "Structure response with:\n" + "Game Title: ...\n" + "Game Objective: ...\n" + "Characters: ...\n" + "Game Mechanics: ...\n" + "Coding Concepts: ...\n" + "Visual Description: ...\n" + ) + result = generator(prompt, max_length=400, do_sample=True, temperature=0.7) + return result[0]['generated_text'] + except: + # Final fallback + return ( + f"Game Title: {story[:20]} Adventure\n" + f"Game Objective: Complete challenges based on the story: {story[:100]}...\n" + "Characters: Hero character based on the story\n" + "Game Mechanics: Navigate through levels, collect items, solve puzzles\n" + f"Coding Concepts: This game teaches {', '.join(concepts)} through gameplay\n" + "Visual Description: Colorful 3D world with characters and obstacles" + ) + +# Generate game code explanation +def generate_game_explanation(story, concepts, game_scenario): + """Generate explanation of game code""" + try: + client = get_groq_client() + if client: + system_prompt = ( + "Explain how the game code implements the programming concepts in a way " + "a child can understand. Use simple analogies and relate to the story. " + "Structure your response with:\n" + "Introduction: ...\n" + "Concept 1: ...\n" + "Concept 2: ...\n" + "Conclusion: ...\n" + "Keep it under 300 words and fun for kids." + ) + + response = client.chat.completions.create( + model="llama3-70b-8192", + messages=[ + {"role": "system", "content": system_prompt}, + {"role": "user", "content": f"Story: {story}\nGame Scenario: {game_scenario}\nConcepts: {', '.join(concepts)}"} + ], + temperature=0.7, + max_tokens=600 + ) + return response.choices[0].message.content + except: + pass + + # Fallback + concept_explanations = "\n".join( + [f"- {CONCEPTS[c]['name']}: {CONCEPTS[c]['game_example']}" for c in concepts] + ) + return ( + f"In this game based on your story '{story[:20]}...', we use programming concepts to make it work:\n" + f"{concept_explanations}\n\n" + "The code brings your story to life in a 3D game world!" + ) + +# Generate simple game code +def generate_game_code(story, concepts): + """Generate simple PyGame code for the game""" + # This is a template - in a real app, this would be dynamically generated + return f""" +# {story[:30]} Adventure Game +import pygame +import random + +# Initialize pygame +pygame.init() + +# Game setup +WIDTH, HEIGHT = 800, 600 +screen = pygame.display.set_mode((WIDTH, HEIGHT)) +pygame.display.set_caption("{story[:20]} Adventure") +clock = pygame.time.Clock() + +# Colors +BACKGROUND = (173, 216, 230) # Light blue +PLAYER_COLOR = (255, 0, 0) # Red +GOAL_COLOR = (0, 255, 0) # Green +OBSTACLE_COLOR = (139, 69, 19) # Brown + +# Player setup +player_size = 50 +player_x = 100 +player_y = HEIGHT // 2 +player_speed = 5 + +# Goal setup +goal_size = 40 +goal_x = WIDTH - 150 +goal_y = HEIGHT // 2 + +# Variables concept: Tracking score +score = 0 +font = pygame.font.SysFont(None, 36) + +# List concept: Creating obstacles +obstacles = [] +for i in range(5): + obstacles.append([ + random.randint(200, WIDTH - 100), + random.randint(50, HEIGHT - 100), + random.randint(20, 50), + random.randint(20, 50) + ]) + +# Game loop +running = True +while running: + # Event handling + for event in pygame.event.get(): + if event.type == pygame.QUIT: + running = False + + # Player movement + keys = pygame.key.get_pressed() + if keys[pygame.K_UP]: + player_y -= player_speed + if keys[pygame.K_DOWN]: + player_y += player_speed + if keys[pygame.K_LEFT]: + player_x -= player_speed + if keys[pygame.K_RIGHT]: + player_x += player_speed + + # Boundary checking + player_x = max(0, min(WIDTH - player_size, player_x)) + player_y = max(0, min(HEIGHT - player_size, player_y)) + + # Collision detection with goal + player_rect = pygame.Rect(player_x, player_y, player_size, player_size) + goal_rect = pygame.Rect(goal_x, goal_y, goal_size, goal_size) + + # Conditional concept: Check for collision + if player_rect.colliderect(goal_rect): + # Function concept: Increase score + score += 1 + # Move goal to new position + goal_x = random.randint(100, WIDTH - 100) + goal_y = random.randint(50, HEIGHT - 100) + + # Drawing + screen.fill(BACKGROUND) + + # Draw obstacles + for obstacle in obstacles: + pygame.draw.rect(screen, OBSTACLE_COLOR, + (obstacle[0], obstacle[1], obstacle[2], obstacle[3])) + + # Draw player and goal + pygame.draw.rect(screen, PLAYER_COLOR, + (player_x, player_y, player_size, player_size)) + pygame.draw.rect(screen, GOAL_COLOR, + (goal_x, goal_y, goal_size, goal_size)) + + # Display score + score_text = font.render(f"Stars: {{score}}", True, (0, 0, 0)) + screen.blit(score_text, (20, 20)) + + # Update display + pygame.display.flip() + clock.tick(60) + +pygame.quit() +""" + +# Generate game preview visualization +def generate_game_preview(game_scenario): + """Generate a visual preview of the game""" + try: + # Extract title from game scenario + title_match = re.search(r"Game Title: (.+)", game_scenario) + title = title_match.group(1) if title_match else "Your Adventure" + + # Create a simple visualization + fig, ax = plt.subplots(figsize=(10, 6)) + ax.set_facecolor('#a2d2ff') + ax.set_xlim(0, 10) + ax.set_ylim(0, 6) + + # Draw game elements + ax.text(5, 5, title, fontsize=20, ha='center', color='#9b5de5') + ax.plot([1, 9], [3, 3], 'k-', linewidth=2) # Ground + + # Player character + ax.plot(2, 3.5, 'ro', markersize=15) + + # Goal + ax.plot(8, 3.5, 'go', markersize=15) + + # Obstacles + for i in range(3): + x = random.uniform(3, 7) + y = random.uniform(3.2, 4) + ax.plot(x, y, 's', color='#8d99ae', markersize=12) + + # Path + ax.plot([2, 8], [3.5, 3.5], 'y--', linewidth=2) + + ax.axis('off') + ax.set_title("Game Preview", fontsize=16) + + # Save to bytes + buf = io.BytesIO() + plt.savefig(buf, format='png', dpi=100, bbox_inches='tight') + buf.seek(0) + return buf + except: + return None + +# Main application function +def main(): + init_session_state() + + st.title("🎮 StoryCoder - Learn Coding Through Games!") + st.subheader("Turn your story into a 3D game and discover coding secrets!") + + # Create tabs + st.markdown('
', unsafe_allow_html=True) + col1, col2, col3, col4, col5 = st.columns(5) + with col1: + if st.button("📖 Create Story", use_container_width=True): + st.session_state.active_tab = "story" + with col2: + if st.button("🎮 Play Game", use_container_width=True): + st.session_state.active_tab = "game" + with col3: + if st.button("🔍 Concepts", use_container_width=True): + st.session_state.active_tab = "concepts" + with col4: + if st.button("💻 Game Code", use_container_width=True): + st.session_state.active_tab = "code" + with col5: + if st.button("🔄 New Story", use_container_width=True): + st.session_state.story = "" + st.session_state.concepts = [] + st.session_state.game_scenario = "" + st.session_state.game_code = "" + st.session_state.game_explanation = "" + st.session_state.game_preview = "" + st.session_state.active_tab = "story" + st.markdown('
', unsafe_allow_html=True) + + # Story creation tab + if st.session_state.active_tab == "story": + with st.container(): + st.header("📖 Create Your Story") + st.write("Write a short story (2-5 sentences) and I'll turn it into a 3D game!") + + story = st.text_area( + "Your story:", + height=200, + placeholder="Once upon a time, a brave knight had to collect 5 magical stars in a castle...", + value=st.session_state.story, + key="story_input" + ) + + if st.button("Create Game!", use_container_width=True): + if len(story) < 10: + st.error("Your story needs to be at least 10 characters long!") + else: + st.session_state.story = story + st.session_state.loading = True + + with st.spinner("🧠 Analyzing your story for coding concepts..."): + st.session_state.concepts = analyze_story(story) + + with st.spinner("🎮 Creating your 3D game scenario..."): + st.session_state.game_scenario = generate_game_scenario( + story, st.session_state.concepts + ) + + with st.spinner("💻 Generating game code..."): + st.session_state.game_code = generate_game_code( + story, st.session_state.concepts + ) + + with st.spinner("📚 Creating coding explanations..."): + st.session_state.game_explanation = generate_game_explanation( + story, st.session_state.concepts, st.session_state.game_scenario + ) + + with st.spinner("🖼️ Generating game preview..."): + preview = generate_game_preview(st.session_state.game_scenario) + if preview: + st.session_state.game_preview = preview + + st.session_state.active_tab = "game" + st.session_state.loading = False + st.rerun() + + # Show examples + st.subheader("✨ Story Examples") + col1, col2, col3 = st.columns(3) + with col1: + st.caption("Space Explorer") + st.code('"An astronaut needs to collect 3 stars while avoiding asteroids"', language="text") + st.image("https://i.imgur.com/7zQY1eE.gif", + use_column_width=True, + caption="Space Explorer Game") + with col2: + st.caption("Jungle Adventure") + st.code('"A monkey swings through trees to collect bananas before sunset"', language="text") + st.image("https://i.imgur.com/5X8jYAy.gif", + use_column_width=True, + caption="Jungle Adventure Game") + with col3: + st.caption("Dragon Quest") + st.code('"A dragon flies through clouds to collect magic crystals"', language="text") + st.image("https://i.imgur.com/9zJkQ7P.gif", + use_column_width=True, + caption="Dragon Quest Game") + + # Game tab + elif st.session_state.active_tab == "game": + st.header("🎮 Your Story Game") + + if not st.session_state.story: + st.warning("Please create a story first!") + st.session_state.active_tab = "story" + st.rerun() + + # Display game scenario + st.subheader("🌟 Game Scenario") + st.markdown(f'
{st.session_state.game_scenario}
', unsafe_allow_html=True) + + # Display game preview + st.subheader("🖼️ Game Preview") + if st.session_state.game_preview: + st.image(st.session_state.game_preview, use_container_width=True) + else: + st.warning("Game preview couldn't be generated. Showing example instead.") + st.image("https://i.imgur.com/7zQY1eE.gif", use_container_width=True) + + # Game explanation + st.subheader("📚 How This Game Teaches Coding") + st.markdown(f'
{st.session_state.game_explanation}
', unsafe_allow_html=True) + + # Play instructions + st.subheader("▶️ How to Play") + st.markdown(""" +
+
    +
  1. Download the game code from the Game Code tab
  2. +
  3. Install Python from python.org
  4. +
  5. Install PyGame: pip install pygame
  6. +
  7. Run the game: python your_game.py
  8. +
  9. Use arrow keys to move your character!
  10. +
+
+ """, unsafe_allow_html=True) + + if st.button("Learn Coding Concepts", use_container_width=True): + st.session_state.active_tab = "concepts" + st.rerun() + + # Concepts tab + elif st.session_state.active_tab == "concepts": + st.header("🔍 Coding Concepts in Your Game") + st.subheader("Your game teaches these programming concepts:") + + if not st.session_state.concepts: + st.warning("No concepts detected in your story! Try adding words like '3 times', 'if', or 'collect'.") + else: + for concept in st.session_state.concepts: + if concept in CONCEPTS: + details = CONCEPTS[concept] + st.markdown(f""" +
+
+ {details['emoji']} +

{details['name']}

+
+

{details['description']}

+

In your game: {details['game_example']}

+
{details['example']}
+
+ """, unsafe_allow_html=True) + + if st.button("See the Game Code", use_container_width=True): + st.session_state.active_tab = "code" + st.rerun() + + # Code tab + elif st.session_state.active_tab == "code": + st.header("💻 Game Code") + st.write("Here's the Python code for your game. Download it and run on your computer!") + + if st.session_state.game_code: + # Display code with syntax highlighting + st.subheader("Your Game Code") + st.code(st.session_state.game_code, language="python") + + # Download button + st.download_button( + label="📥 Download Game Code", + data=st.session_state.game_code, + file_name="story_game.py", + mime="text/python", + use_container_width=True + ) + + # Game running instructions + st.subheader("🖥️ How to Run Your Game") + st.markdown(""" +
+
    +
  1. Install Python from python.org
  2. +
  3. Install PyGame: Open command prompt and type pip install pygame
  4. +
  5. Save the game code to a file named my_game.py
  6. +
  7. Run the game: python my_game.py
  8. +
  9. Use arrow keys to play!
  10. +
+
+ """, unsafe_allow_html=True) + + # What to expect + st.subheader("🎮 What to Expect When Playing") + st.markdown(""" +
+ +
+ """, unsafe_allow_html=True) + else: + st.warning("No game code generated yet!") + + if st.button("Create Another Story!", use_container_width=True): + st.session_state.active_tab = "story" + st.rerun() + +if __name__ == "__main__": + main()# app.py - Game-Based Learning Version +import streamlit as st +import os +import time +import random +import json +import base64 +import requests +import re +from PIL import Image +import io +import matplotlib.pyplot as plt +from groq import Groq +from transformers import pipeline +import torch + +# Configure Streamlit page +st.set_page_config( + page_title="StoryCoder - Learn Coding Through Games", + page_icon="🎮", + layout="wide", + initial_sidebar_state="expanded" +) + +# Custom CSS for game-themed UI +st.markdown(""" + +""", unsafe_allow_html=True) + +# Initialize session state +def init_session_state(): + if 'story' not in st.session_state: + st.session_state.story = "" + if 'concepts' not in st.session_state: + st.session_state.concepts = [] + if 'game_scenario' not in st.session_state: + st.session_state.game_scenario = "" + if 'game_code' not in st.session_state: + st.session_state.game_code = "" + if 'game_explanation' not in st.session_state: + st.session_state.game_explanation = "" + if 'game_preview' not in st.session_state: + st.session_state.game_preview = "" + if 'active_tab' not in st.session_state: + st.session_state.active_tab = "story" + if 'loading' not in st.session_state: + st.session_state.loading = False + +# Concept database +CONCEPTS = { + "loop": { + "name": "Loop", + "emoji": "🔄", + "description": "Loops repeat actions multiple times", + "example": "for i in range(5):\n print('Hello!')", + "color": "#FF9E6D", + "game_example": "Repeating a jump 5 times to cross a river" + }, + "conditional": { + "name": "Conditional", + "emoji": "❓", + "description": "Conditionals make decisions in code", + "example": "if sunny:\n go_outside()\nelse:\n stay_inside()", + "color": "#4ECDC4", + "game_example": "Choosing different paths based on obstacles" + }, + "function": { + "name": "Function", + "emoji": "✨", + "description": "Functions are reusable blocks of code", + "example": "def greet(name):\n print(f'Hello {name}!')", + "color": "#FFD166", + "game_example": "Creating a jump function used multiple times" + }, + "variable": { + "name": "Variable", + "emoji": "📦", + "description": "Variables store information", + "example": "score = 10\nplayer = 'Alex'", + "color": "#FF6B6B", + "game_example": "Keeping track of collected stars" + }, + "list": { + "name": "List", + "emoji": "📝", + "description": "Lists store collections of items", + "example": "fruits = ['apple', 'banana', 'orange']", + "color": "#1A535C", + "game_example": "Storing collected treasures in a backpack" + } +} + +# Initialize Groq client +def get_groq_client(): + try: + # Use a free proxy for Groq API access + return Groq(api_key="free-proxy-key", base_url="https://api.groq.com/openai/v1") + except: + st.error("Could not initialize Groq client. Using fallback method.") + return None + +# Analyze story and extract concepts +def analyze_story(story): + """Analyze story and identify programming concepts""" + story_lower = story.lower() + detected_concepts = [] + + # Check for loops + if any(word in story_lower for word in ["times", "repeat", "again", "multiple"]): + detected_concepts.append("loop") + + # Check for conditionals + if any(word in story_lower for word in ["if", "when", "unless", "whether", "decide"]): + detected_concepts.append("conditional") + + # Check for functions + if any(word in story_lower for word in ["make", "create", "do", "perform", "cast"]): + detected_concepts.append("function") + + # Check for variables + if any(word in story_lower for word in ["is", "has", "set to", "value", "score"]): + detected_concepts.append("variable") + + # Check for lists + if any(word in story_lower for word in ["and", "many", "several", "collection", "items"]): + detected_concepts.append("list") + + return list(set(detected_concepts)) + +# Generate game scenario using Groq +def generate_game_scenario(story, concepts): + """Generate a game scenario based on the story and concepts""" + try: + # Use Groq API for fast response + client = get_groq_client() + if client: + system_prompt = ( + "You are an expert in creating educational games for children. " + "Create a simple 3D game scenario based on the child's story. " + "The game should teach programming concepts through gameplay. " + "Structure your response with:\n" + "Game Title: ...\n" + "Game Objective: ...\n" + "Characters: ...\n" + "Game Mechanics: ...\n" + "Coding Concepts: Explain how these programming concepts are used: " + ", ".join(concepts) + "\n" + "Visual Description: Describe the game world visually\n" + "Keep it under 200 words and suitable for children aged 6-12." + ) + + response = client.chat.completions.create( + model="llama3-70b-8192", + messages=[ + {"role": "system", "content": system_prompt}, + {"role": "user", "content": story} + ], + temperature=0.7, + max_tokens=500 + ) + return response.choices[0].message.content + except Exception as e: + st.error(f"Groq API error: {str(e)}") + + # Fallback to Hugging Face model + try: + generator = pipeline("text-generation", model="HuggingFaceH4/zephyr-7b-beta") + prompt = ( + f"Create a children's educational game based on this story: {story}\n" + f"Game should teach these programming concepts: {', '.join(concepts)}\n" + "Structure response with:\n" + "Game Title: ...\n" + "Game Objective: ...\n" + "Characters: ...\n" + "Game Mechanics: ...\n" + "Coding Concepts: ...\n" + "Visual Description: ...\n" + ) + result = generator(prompt, max_length=400, do_sample=True, temperature=0.7) + return result[0]['generated_text'] + except: + # Final fallback + return ( + f"Game Title: {story[:20]} Adventure\n" + f"Game Objective: Complete challenges based on the story: {story[:100]}...\n" + "Characters: Hero character based on the story\n" + "Game Mechanics: Navigate through levels, collect items, solve puzzles\n" + f"Coding Concepts: This game teaches {', '.join(concepts)} through gameplay\n" + "Visual Description: Colorful 3D world with characters and obstacles" + ) + +# Generate game code explanation +def generate_game_explanation(story, concepts, game_scenario): + """Generate explanation of game code""" + try: + client = get_groq_client() + if client: + system_prompt = ( + "Explain how the game code implements the programming concepts in a way " + "a child can understand. Use simple analogies and relate to the story. " + "Structure your response with:\n" + "Introduction: ...\n" + "Concept 1: ...\n" + "Concept 2: ...\n" + "Conclusion: ...\n" + "Keep it under 300 words and fun for kids." + ) + + response = client.chat.completions.create( + model="llama3-70b-8192", + messages=[ + {"role": "system", "content": system_prompt}, + {"role": "user", "content": f"Story: {story}\nGame Scenario: {game_scenario}\nConcepts: {', '.join(concepts)}"} + ], + temperature=0.7, + max_tokens=600 + ) + return response.choices[0].message.content + except: + pass + + # Fallback + concept_explanations = "\n".join( + [f"- {CONCEPTS[c]['name']}: {CONCEPTS[c]['game_example']}" for c in concepts] + ) + return ( + f"In this game based on your story '{story[:20]}...', we use programming concepts to make it work:\n" + f"{concept_explanations}\n\n" + "The code brings your story to life in a 3D game world!" + ) + +# Generate simple game code +def generate_game_code(story, concepts): + """Generate simple PyGame code for the game""" + # This is a template - in a real app, this would be dynamically generated + return f""" +# {story[:30]} Adventure Game +import pygame +import random + +# Initialize pygame +pygame.init() + +# Game setup +WIDTH, HEIGHT = 800, 600 +screen = pygame.display.set_mode((WIDTH, HEIGHT)) +pygame.display.set_caption("{story[:20]} Adventure") +clock = pygame.time.Clock() + +# Colors +BACKGROUND = (173, 216, 230) # Light blue +PLAYER_COLOR = (255, 0, 0) # Red +GOAL_COLOR = (0, 255, 0) # Green +OBSTACLE_COLOR = (139, 69, 19) # Brown + +# Player setup +player_size = 50 +player_x = 100 +player_y = HEIGHT // 2 +player_speed = 5 + +# Goal setup +goal_size = 40 +goal_x = WIDTH - 150 +goal_y = HEIGHT // 2 + +# Variables concept: Tracking score +score = 0 +font = pygame.font.SysFont(None, 36) + +# List concept: Creating obstacles +obstacles = [] +for i in range(5): + obstacles.append([ + random.randint(200, WIDTH - 100), + random.randint(50, HEIGHT - 100), + random.randint(20, 50), + random.randint(20, 50) + ]) + +# Game loop +running = True +while running: + # Event handling + for event in pygame.event.get(): + if event.type == pygame.QUIT: + running = False + + # Player movement + keys = pygame.key.get_pressed() + if keys[pygame.K_UP]: + player_y -= player_speed + if keys[pygame.K_DOWN]: + player_y += player_speed + if keys[pygame.K_LEFT]: + player_x -= player_speed + if keys[pygame.K_RIGHT]: + player_x += player_speed + + # Boundary checking + player_x = max(0, min(WIDTH - player_size, player_x)) + player_y = max(0, min(HEIGHT - player_size, player_y)) + + # Collision detection with goal + player_rect = pygame.Rect(player_x, player_y, player_size, player_size) + goal_rect = pygame.Rect(goal_x, goal_y, goal_size, goal_size) + + # Conditional concept: Check for collision + if player_rect.colliderect(goal_rect): + # Function concept: Increase score + score += 1 + # Move goal to new position + goal_x = random.randint(100, WIDTH - 100) + goal_y = random.randint(50, HEIGHT - 100) + + # Drawing + screen.fill(BACKGROUND) + + # Draw obstacles + for obstacle in obstacles: + pygame.draw.rect(screen, OBSTACLE_COLOR, + (obstacle[0], obstacle[1], obstacle[2], obstacle[3])) + + # Draw player and goal + pygame.draw.rect(screen, PLAYER_COLOR, + (player_x, player_y, player_size, player_size)) + pygame.draw.rect(screen, GOAL_COLOR, + (goal_x, goal_y, goal_size, goal_size)) + + # Display score + score_text = font.render(f"Stars: {{score}}", True, (0, 0, 0)) + screen.blit(score_text, (20, 20)) + + # Update display + pygame.display.flip() + clock.tick(60) + +pygame.quit() +""" + +# Generate game preview visualization +def generate_game_preview(game_scenario): + """Generate a visual preview of the game""" + try: + # Extract title from game scenario + title_match = re.search(r"Game Title: (.+)", game_scenario) + title = title_match.group(1) if title_match else "Your Adventure" + + # Create a simple visualization + fig, ax = plt.subplots(figsize=(10, 6)) + ax.set_facecolor('#a2d2ff') + ax.set_xlim(0, 10) + ax.set_ylim(0, 6) + + # Draw game elements + ax.text(5, 5, title, fontsize=20, ha='center', color='#9b5de5') + ax.plot([1, 9], [3, 3], 'k-', linewidth=2) # Ground + + # Player character + ax.plot(2, 3.5, 'ro', markersize=15) + + # Goal + ax.plot(8, 3.5, 'go', markersize=15) + + # Obstacles + for i in range(3): + x = random.uniform(3, 7) + y = random.uniform(3.2, 4) + ax.plot(x, y, 's', color='#8d99ae', markersize=12) + + # Path + ax.plot([2, 8], [3.5, 3.5], 'y--', linewidth=2) + + ax.axis('off') + ax.set_title("Game Preview", fontsize=16) + + # Save to bytes + buf = io.BytesIO() + plt.savefig(buf, format='png', dpi=100, bbox_inches='tight') + buf.seek(0) + return buf + except: + return None + +# Main application function +def main(): + init_session_state() + + st.title("🎮 StoryCoder - Learn Coding Through Games!") + st.subheader("Turn your story into a 3D game and discover coding secrets!") + + # Create tabs + st.markdown('
', unsafe_allow_html=True) + col1, col2, col3, col4, col5 = st.columns(5) + with col1: + if st.button("📖 Create Story", use_container_width=True): + st.session_state.active_tab = "story" + with col2: + if st.button("🎮 Play Game", use_container_width=True): + st.session_state.active_tab = "game" + with col3: + if st.button("🔍 Concepts", use_container_width=True): + st.session_state.active_tab = "concepts" + with col4: + if st.button("💻 Game Code", use_container_width=True): + st.session_state.active_tab = "code" + with col5: + if st.button("🔄 New Story", use_container_width=True): + st.session_state.story = "" + st.session_state.concepts = [] + st.session_state.game_scenario = "" + st.session_state.game_code = "" + st.session_state.game_explanation = "" + st.session_state.game_preview = "" + st.session_state.active_tab = "story" + st.markdown('
', unsafe_allow_html=True) + + # Story creation tab + if st.session_state.active_tab == "story": + with st.container(): + st.header("📖 Create Your Story") + st.write("Write a short story (2-5 sentences) and I'll turn it into a 3D game!") + + story = st.text_area( + "Your story:", + height=200, + placeholder="Once upon a time, a brave knight had to collect 5 magical stars in a castle...", + value=st.session_state.story, + key="story_input" + ) + + if st.button("Create Game!", use_container_width=True): + if len(story) < 10: + st.error("Your story needs to be at least 10 characters long!") + else: + st.session_state.story = story + st.session_state.loading = True + + with st.spinner("🧠 Analyzing your story for coding concepts..."): + st.session_state.concepts = analyze_story(story) + + with st.spinner("🎮 Creating your 3D game scenario..."): + st.session_state.game_scenario = generate_game_scenario( + story, st.session_state.concepts + ) + + with st.spinner("💻 Generating game code..."): + st.session_state.game_code = generate_game_code( + story, st.session_state.concepts + ) + + with st.spinner("📚 Creating coding explanations..."): + st.session_state.game_explanation = generate_game_explanation( + story, st.session_state.concepts, st.session_state.game_scenario + ) + + with st.spinner("🖼️ Generating game preview..."): + preview = generate_game_preview(st.session_state.game_scenario) + if preview: + st.session_state.game_preview = preview + + st.session_state.active_tab = "game" + st.session_state.loading = False + st.rerun() + + # Show examples + st.subheader("✨ Story Examples") + col1, col2, col3 = st.columns(3) + with col1: + st.caption("Space Explorer") + st.code('"An astronaut needs to collect 3 stars while avoiding asteroids"', language="text") + st.image("https://i.imgur.com/7zQY1eE.gif", + use_column_width=True, + caption="Space Explorer Game") + with col2: + st.caption("Jungle Adventure") + st.code('"A monkey swings through trees to collect bananas before sunset"', language="text") + st.image("https://i.imgur.com/5X8jYAy.gif", + use_column_width=True, + caption="Jungle Adventure Game") + with col3: + st.caption("Dragon Quest") + st.code('"A dragon flies through clouds to collect magic crystals"', language="text") + st.image("https://i.imgur.com/9zJkQ7P.gif", + use_column_width=True, + caption="Dragon Quest Game") + + # Game tab + elif st.session_state.active_tab == "game": + st.header("🎮 Your Story Game") + + if not st.session_state.story: + st.warning("Please create a story first!") + st.session_state.active_tab = "story" + st.rerun() + + # Display game scenario + st.subheader("🌟 Game Scenario") + st.markdown(f'
{st.session_state.game_scenario}
', unsafe_allow_html=True) + + # Display game preview + st.subheader("🖼️ Game Preview") + if st.session_state.game_preview: + st.image(st.session_state.game_preview, use_container_width=True) + else: + st.warning("Game preview couldn't be generated. Showing example instead.") + st.image("https://i.imgur.com/7zQY1eE.gif", use_container_width=True) + + # Game explanation + st.subheader("📚 How This Game Teaches Coding") + st.markdown(f'
{st.session_state.game_explanation}
', unsafe_allow_html=True) + + # Play instructions + st.subheader("▶️ How to Play") + st.markdown(""" +
+
    +
  1. Download the game code from the Game Code tab
  2. +
  3. Install Python from python.org
  4. +
  5. Install PyGame: pip install pygame
  6. +
  7. Run the game: python your_game.py
  8. +
  9. Use arrow keys to move your character!
  10. +
+
+ """, unsafe_allow_html=True) + + if st.button("Learn Coding Concepts", use_container_width=True): + st.session_state.active_tab = "concepts" + st.rerun() + + # Concepts tab + elif st.session_state.active_tab == "concepts": + st.header("🔍 Coding Concepts in Your Game") + st.subheader("Your game teaches these programming concepts:") + + if not st.session_state.concepts: + st.warning("No concepts detected in your story! Try adding words like '3 times', 'if', or 'collect'.") + else: + for concept in st.session_state.concepts: + if concept in CONCEPTS: + details = CONCEPTS[concept] + st.markdown(f""" +
+
+ {details['emoji']} +

{details['name']}

+
+

{details['description']}

+

In your game: {details['game_example']}

+
{details['example']}
+
+ """, unsafe_allow_html=True) + + if st.button("See the Game Code", use_container_width=True): + st.session_state.active_tab = "code" + st.rerun() + + # Code tab + elif st.session_state.active_tab == "code": + st.header("💻 Game Code") + st.write("Here's the Python code for your game. Download it and run on your computer!") + + if st.session_state.game_code: + # Display code with syntax highlighting + st.subheader("Your Game Code") + st.code(st.session_state.game_code, language="python") + + # Download button + st.download_button( + label="📥 Download Game Code", + data=st.session_state.game_code, + file_name="story_game.py", + mime="text/python", + use_container_width=True + ) + + # Game running instructions + st.subheader("🖥️ How to Run Your Game") + st.markdown(""" +
+
    +
  1. Install Python from python.org
  2. +
  3. Install PyGame: Open command prompt and type pip install pygame
  4. +
  5. Save the game code to a file named my_game.py
  6. +
  7. Run the game: python my_game.py
  8. +
  9. Use arrow keys to play!
  10. +
+
+ """, unsafe_allow_html=True) + + # What to expect + st.subheader("🎮 What to Expect When Playing") + st.markdown(""" +
+ +
+ """, unsafe_allow_html=True) + else: + st.warning("No game code generated yet!") + + if st.button("Create Another Story!", use_container_width=True): + st.session_state.active_tab = "story" + st.rerun() + +if __name__ == "__main__": + main()# app.py - Game-Based Learning Version +import streamlit as st +import os +import time +import random +import json +import base64 +import requests +import re +from PIL import Image +import io +import matplotlib.pyplot as plt +from groq import Groq +from transformers import pipeline +import torch + +# Configure Streamlit page +st.set_page_config( + page_title="StoryCoder - Learn Coding Through Games", + page_icon="🎮", + layout="wide", + initial_sidebar_state="expanded" +) + +# Custom CSS for game-themed UI +st.markdown(""" + +""", unsafe_allow_html=True) + +# Initialize session state +def init_session_state(): + if 'story' not in st.session_state: + st.session_state.story = "" + if 'concepts' not in st.session_state: + st.session_state.concepts = [] + if 'game_scenario' not in st.session_state: + st.session_state.game_scenario = "" + if 'game_code' not in st.session_state: + st.session_state.game_code = "" + if 'game_explanation' not in st.session_state: + st.session_state.game_explanation = "" + if 'game_preview' not in st.session_state: + st.session_state.game_preview = "" + if 'active_tab' not in st.session_state: + st.session_state.active_tab = "story" + if 'loading' not in st.session_state: + st.session_state.loading = False + +# Concept database +CONCEPTS = { + "loop": { + "name": "Loop", + "emoji": "🔄", + "description": "Loops repeat actions multiple times", + "example": "for i in range(5):\n print('Hello!')", + "color": "#FF9E6D", + "game_example": "Repeating a jump 5 times to cross a river" + }, + "conditional": { + "name": "Conditional", + "emoji": "❓", + "description": "Conditionals make decisions in code", + "example": "if sunny:\n go_outside()\nelse:\n stay_inside()", + "color": "#4ECDC4", + "game_example": "Choosing different paths based on obstacles" + }, + "function": { + "name": "Function", + "emoji": "✨", + "description": "Functions are reusable blocks of code", + "example": "def greet(name):\n print(f'Hello {name}!')", + "color": "#FFD166", + "game_example": "Creating a jump function used multiple times" + }, + "variable": { + "name": "Variable", + "emoji": "📦", + "description": "Variables store information", + "example": "score = 10\nplayer = 'Alex'", + "color": "#FF6B6B", + "game_example": "Keeping track of collected stars" + }, + "list": { + "name": "List", + "emoji": "📝", + "description": "Lists store collections of items", + "example": "fruits = ['apple', 'banana', 'orange']", + "color": "#1A535C", + "game_example": "Storing collected treasures in a backpack" + } +} + +# Initialize Groq client +def get_groq_client(): + try: + # Use a free proxy for Groq API access + return Groq(api_key="free-proxy-key", base_url="https://api.groq.com/openai/v1") + except: + st.error("Could not initialize Groq client. Using fallback method.") + return None + +# Analyze story and extract concepts +def analyze_story(story): + """Analyze story and identify programming concepts""" + story_lower = story.lower() + detected_concepts = [] + + # Check for loops + if any(word in story_lower for word in ["times", "repeat", "again", "multiple"]): + detected_concepts.append("loop") + + # Check for conditionals + if any(word in story_lower for word in ["if", "when", "unless", "whether", "decide"]): + detected_concepts.append("conditional") + + # Check for functions + if any(word in story_lower for word in ["make", "create", "do", "perform", "cast"]): + detected_concepts.append("function") + + # Check for variables + if any(word in story_lower for word in ["is", "has", "set to", "value", "score"]): + detected_concepts.append("variable") + + # Check for lists + if any(word in story_lower for word in ["and", "many", "several", "collection", "items"]): + detected_concepts.append("list") + + return list(set(detected_concepts)) + +# Generate game scenario using Groq +def generate_game_scenario(story, concepts): + """Generate a game scenario based on the story and concepts""" + try: + # Use Groq API for fast response + client = get_groq_client() + if client: + system_prompt = ( + "You are an expert in creating educational games for children. " + "Create a simple 3D game scenario based on the child's story. " + "The game should teach programming concepts through gameplay. " + "Structure your response with:\n" + "Game Title: ...\n" + "Game Objective: ...\n" + "Characters: ...\n" + "Game Mechanics: ...\n" + "Coding Concepts: Explain how these programming concepts are used: " + ", ".join(concepts) + "\n" + "Visual Description: Describe the game world visually\n" + "Keep it under 200 words and suitable for children aged 6-12." + ) + + response = client.chat.completions.create( + model="llama3-70b-8192", + messages=[ + {"role": "system", "content": system_prompt}, + {"role": "user", "content": story} + ], + temperature=0.7, + max_tokens=500 + ) + return response.choices[0].message.content + except Exception as e: + st.error(f"Groq API error: {str(e)}") + + # Fallback to Hugging Face model + try: + generator = pipeline("text-generation", model="HuggingFaceH4/zephyr-7b-beta") + prompt = ( + f"Create a children's educational game based on this story: {story}\n" + f"Game should teach these programming concepts: {', '.join(concepts)}\n" + "Structure response with:\n" + "Game Title: ...\n" + "Game Objective: ...\n" + "Characters: ...\n" + "Game Mechanics: ...\n" + "Coding Concepts: ...\n" + "Visual Description: ...\n" + ) + result = generator(prompt, max_length=400, do_sample=True, temperature=0.7) + return result[0]['generated_text'] + except: + # Final fallback + return ( + f"Game Title: {story[:20]} Adventure\n" + f"Game Objective: Complete challenges based on the story: {story[:100]}...\n" + "Characters: Hero character based on the story\n" + "Game Mechanics: Navigate through levels, collect items, solve puzzles\n" + f"Coding Concepts: This game teaches {', '.join(concepts)} through gameplay\n" + "Visual Description: Colorful 3D world with characters and obstacles" + ) + +# Generate game code explanation +def generate_game_explanation(story, concepts, game_scenario): + """Generate explanation of game code""" + try: + client = get_groq_client() + if client: + system_prompt = ( + "Explain how the game code implements the programming concepts in a way " + "a child can understand. Use simple analogies and relate to the story. " + "Structure your response with:\n" + "Introduction: ...\n" + "Concept 1: ...\n" + "Concept 2: ...\n" + "Conclusion: ...\n" + "Keep it under 300 words and fun for kids." + ) + + response = client.chat.completions.create( + model="llama3-70b-8192", + messages=[ + {"role": "system", "content": system_prompt}, + {"role": "user", "content": f"Story: {story}\nGame Scenario: {game_scenario}\nConcepts: {', '.join(concepts)}"} + ], + temperature=0.7, + max_tokens=600 + ) + return response.choices[0].message.content + except: + pass + + # Fallback + concept_explanations = "\n".join( + [f"- {CONCEPTS[c]['name']}: {CONCEPTS[c]['game_example']}" for c in concepts] + ) + return ( + f"In this game based on your story '{story[:20]}...', we use programming concepts to make it work:\n" + f"{concept_explanations}\n\n" + "The code brings your story to life in a 3D game world!" + ) + +# Generate simple game code +def generate_game_code(story, concepts): + """Generate simple PyGame code for the game""" + # This is a template - in a real app, this would be dynamically generated + return f""" +# {story[:30]} Adventure Game +import pygame +import random + +# Initialize pygame +pygame.init() + +# Game setup +WIDTH, HEIGHT = 800, 600 +screen = pygame.display.set_mode((WIDTH, HEIGHT)) +pygame.display.set_caption("{story[:20]} Adventure") +clock = pygame.time.Clock() + +# Colors +BACKGROUND = (173, 216, 230) # Light blue +PLAYER_COLOR = (255, 0, 0) # Red +GOAL_COLOR = (0, 255, 0) # Green +OBSTACLE_COLOR = (139, 69, 19) # Brown + +# Player setup +player_size = 50 +player_x = 100 +player_y = HEIGHT // 2 +player_speed = 5 + +# Goal setup +goal_size = 40 +goal_x = WIDTH - 150 +goal_y = HEIGHT // 2 + +# Variables concept: Tracking score +score = 0 +font = pygame.font.SysFont(None, 36) + +# List concept: Creating obstacles +obstacles = [] +for i in range(5): + obstacles.append([ + random.randint(200, WIDTH - 100), + random.randint(50, HEIGHT - 100), + random.randint(20, 50), + random.randint(20, 50) + ]) + +# Game loop +running = True +while running: + # Event handling + for event in pygame.event.get(): + if event.type == pygame.QUIT: + running = False + + # Player movement + keys = pygame.key.get_pressed() + if keys[pygame.K_UP]: + player_y -= player_speed + if keys[pygame.K_DOWN]: + player_y += player_speed + if keys[pygame.K_LEFT]: + player_x -= player_speed + if keys[pygame.K_RIGHT]: + player_x += player_speed + + # Boundary checking + player_x = max(0, min(WIDTH - player_size, player_x)) + player_y = max(0, min(HEIGHT - player_size, player_y)) + + # Collision detection with goal + player_rect = pygame.Rect(player_x, player_y, player_size, player_size) + goal_rect = pygame.Rect(goal_x, goal_y, goal_size, goal_size) + + # Conditional concept: Check for collision + if player_rect.colliderect(goal_rect): + # Function concept: Increase score + score += 1 + # Move goal to new position + goal_x = random.randint(100, WIDTH - 100) + goal_y = random.randint(50, HEIGHT - 100) + + # Drawing + screen.fill(BACKGROUND) + + # Draw obstacles + for obstacle in obstacles: + pygame.draw.rect(screen, OBSTACLE_COLOR, + (obstacle[0], obstacle[1], obstacle[2], obstacle[3])) + + # Draw player and goal + pygame.draw.rect(screen, PLAYER_COLOR, + (player_x, player_y, player_size, player_size)) + pygame.draw.rect(screen, GOAL_COLOR, + (goal_x, goal_y, goal_size, goal_size)) + + # Display score + score_text = font.render(f"Stars: {{score}}", True, (0, 0, 0)) + screen.blit(score_text, (20, 20)) + + # Update display + pygame.display.flip() + clock.tick(60) + +pygame.quit() +""" + +# Generate game preview visualization +def generate_game_preview(game_scenario): + """Generate a visual preview of the game""" + try: + # Extract title from game scenario + title_match = re.search(r"Game Title: (.+)", game_scenario) + title = title_match.group(1) if title_match else "Your Adventure" + + # Create a simple visualization + fig, ax = plt.subplots(figsize=(10, 6)) + ax.set_facecolor('#a2d2ff') + ax.set_xlim(0, 10) + ax.set_ylim(0, 6) + + # Draw game elements + ax.text(5, 5, title, fontsize=20, ha='center', color='#9b5de5') + ax.plot([1, 9], [3, 3], 'k-', linewidth=2) # Ground + + # Player character + ax.plot(2, 3.5, 'ro', markersize=15) + + # Goal + ax.plot(8, 3.5, 'go', markersize=15) + + # Obstacles + for i in range(3): + x = random.uniform(3, 7) + y = random.uniform(3.2, 4) + ax.plot(x, y, 's', color='#8d99ae', markersize=12) + + # Path + ax.plot([2, 8], [3.5, 3.5], 'y--', linewidth=2) + + ax.axis('off') + ax.set_title("Game Preview", fontsize=16) + + # Save to bytes + buf = io.BytesIO() + plt.savefig(buf, format='png', dpi=100, bbox_inches='tight') + buf.seek(0) + return buf + except: + return None + +# Main application function +def main(): + init_session_state() + + st.title("🎮 StoryCoder - Learn Coding Through Games!") + st.subheader("Turn your story into a 3D game and discover coding secrets!") + + # Create tabs + st.markdown('
', unsafe_allow_html=True) + col1, col2, col3, col4, col5 = st.columns(5) + with col1: + if st.button("📖 Create Story", use_container_width=True): + st.session_state.active_tab = "story" + with col2: + if st.button("🎮 Play Game", use_container_width=True): + st.session_state.active_tab = "game" + with col3: + if st.button("🔍 Concepts", use_container_width=True): + st.session_state.active_tab = "concepts" + with col4: + if st.button("💻 Game Code", use_container_width=True): + st.session_state.active_tab = "code" + with col5: + if st.button("🔄 New Story", use_container_width=True): + st.session_state.story = "" + st.session_state.concepts = [] + st.session_state.game_scenario = "" + st.session_state.game_code = "" + st.session_state.game_explanation = "" + st.session_state.game_preview = "" + st.session_state.active_tab = "story" + st.markdown('
', unsafe_allow_html=True) + + # Story creation tab + if st.session_state.active_tab == "story": + with st.container(): + st.header("📖 Create Your Story") + st.write("Write a short story (2-5 sentences) and I'll turn it into a 3D game!") + + story = st.text_area( + "Your story:", + height=200, + placeholder="Once upon a time, a brave knight had to collect 5 magical stars in a castle...", + value=st.session_state.story, + key="story_input" + ) + + if st.button("Create Game!", use_container_width=True): + if len(story) < 10: + st.error("Your story needs to be at least 10 characters long!") + else: + st.session_state.story = story + st.session_state.loading = True + + with st.spinner("🧠 Analyzing your story for coding concepts..."): + st.session_state.concepts = analyze_story(story) + + with st.spinner("🎮 Creating your 3D game scenario..."): + st.session_state.game_scenario = generate_game_scenario( + story, st.session_state.concepts + ) + + with st.spinner("💻 Generating game code..."): + st.session_state.game_code = generate_game_code( + story, st.session_state.concepts + ) + + with st.spinner("📚 Creating coding explanations..."): + st.session_state.game_explanation = generate_game_explanation( + story, st.session_state.concepts, st.session_state.game_scenario + ) + + with st.spinner("🖼️ Generating game preview..."): + preview = generate_game_preview(st.session_state.game_scenario) + if preview: + st.session_state.game_preview = preview + + st.session_state.active_tab = "game" + st.session_state.loading = False + st.rerun() + + # Show examples + st.subheader("✨ Story Examples") + col1, col2, col3 = st.columns(3) + with col1: + st.caption("Space Explorer") + st.code('"An astronaut needs to collect 3 stars while avoiding asteroids"', language="text") + st.image("https://i.imgur.com/7zQY1eE.gif", + use_column_width=True, + caption="Space Explorer Game") + with col2: + st.caption("Jungle Adventure") + st.code('"A monkey swings through trees to collect bananas before sunset"', language="text") + st.image("https://i.imgur.com/5X8jYAy.gif", + use_column_width=True, + caption="Jungle Adventure Game") + with col3: + st.caption("Dragon Quest") + st.code('"A dragon flies through clouds to collect magic crystals"', language="text") + st.image("https://i.imgur.com/9zJkQ7P.gif", + use_column_width=True, + caption="Dragon Quest Game") + + # Game tab + elif st.session_state.active_tab == "game": + st.header("🎮 Your Story Game") + + if not st.session_state.story: + st.warning("Please create a story first!") + st.session_state.active_tab = "story" + st.rerun() + + # Display game scenario + st.subheader("🌟 Game Scenario") + st.markdown(f'
{st.session_state.game_scenario}
', unsafe_allow_html=True) + + # Display game preview + st.subheader("🖼️ Game Preview") + if st.session_state.game_preview: + st.image(st.session_state.game_preview, use_container_width=True) + else: + st.warning("Game preview couldn't be generated. Showing example instead.") + st.image("https://i.imgur.com/7zQY1eE.gif", use_container_width=True) + + # Game explanation + st.subheader("📚 How This Game Teaches Coding") + st.markdown(f'
{st.session_state.game_explanation}
', unsafe_allow_html=True) + + # Play instructions + st.subheader("▶️ How to Play") + st.markdown(""" +
+
    +
  1. Download the game code from the Game Code tab
  2. +
  3. Install Python from python.org
  4. +
  5. Install PyGame: pip install pygame
  6. +
  7. Run the game: python your_game.py
  8. +
  9. Use arrow keys to move your character!
  10. +
+
+ """, unsafe_allow_html=True) + + if st.button("Learn Coding Concepts", use_container_width=True): + st.session_state.active_tab = "concepts" + st.rerun() + + # Concepts tab + elif st.session_state.active_tab == "concepts": + st.header("🔍 Coding Concepts in Your Game") + st.subheader("Your game teaches these programming concepts:") + + if not st.session_state.concepts: + st.warning("No concepts detected in your story! Try adding words like '3 times', 'if', or 'collect'.") + else: + for concept in st.session_state.concepts: + if concept in CONCEPTS: + details = CONCEPTS[concept] + st.markdown(f""" +
+
+ {details['emoji']} +

{details['name']}

+
+

{details['description']}

+

In your game: {details['game_example']}

+
{details['example']}
+
+ """, unsafe_allow_html=True) + + if st.button("See the Game Code", use_container_width=True): + st.session_state.active_tab = "code" + st.rerun() + + # Code tab + elif st.session_state.active_tab == "code": + st.header("💻 Game Code") + st.write("Here's the Python code for your game. Download it and run on your computer!") + + if st.session_state.game_code: + # Display code with syntax highlighting + st.subheader("Your Game Code") + st.code(st.session_state.game_code, language="python") + + # Download button + st.download_button( + label="📥 Download Game Code", + data=st.session_state.game_code, + file_name="story_game.py", + mime="text/python", + use_container_width=True + ) + + # Game running instructions + st.subheader("🖥️ How to Run Your Game") + st.markdown(""" +
+
    +
  1. Install Python from python.org
  2. +
  3. Install PyGame: Open command prompt and type pip install pygame
  4. +
  5. Save the game code to a file named my_game.py
  6. +
  7. Run the game: python my_game.py
  8. +
  9. Use arrow keys to play!
  10. +
+
+ """, unsafe_allow_html=True) + + # What to expect + st.subheader("🎮 What to Expect When Playing") + st.markdown(""" +
+ +
+ """, unsafe_allow_html=True) + else: + st.warning("No game code generated yet!") + + if st.button("Create Another Story!", use_container_width=True): + st.session_state.active_tab = "story" + st.rerun() + +if __name__ == "__main__": + main()# app.py - Game-Based Learning Version +import streamlit as st +import os +import time +import random import json +import base64 import requests import re from PIL import Image import io import matplotlib.pyplot as plt -import numpy as np -import pandas as pd -import plotly.express as px -import plotly.graph_objects as go +from groq import Groq +from transformers import pipeline +import torch # Configure Streamlit page st.set_page_config( page_title="StoryCoder - Learn Coding Through Games", - page_icon="🧙‍♂️", + page_icon="🎮", layout="wide", initial_sidebar_state="expanded" ) -# Custom CSS for colorful UI +# Custom CSS for game-themed UI st.markdown(""" """, unsafe_allow_html=True) +# Initialize session state +def init_session_state(): + if 'story' not in st.session_state: + st.session_state.story = "" + if 'concepts' not in st.session_state: + st.session_state.concepts = [] + if 'game_scenario' not in st.session_state: + st.session_state.game_scenario = "" + if 'game_code' not in st.session_state: + st.session_state.game_code = "" + if 'game_explanation' not in st.session_state: + st.session_state.game_explanation = "" + if 'game_preview' not in st.session_state: + st.session_state.game_preview = "" + if 'active_tab' not in st.session_state: + st.session_state.active_tab = "story" + if 'loading' not in st.session_state: + st.session_state.loading = False + # Concept database CONCEPTS = { "loop": { @@ -165,546 +2528,487 @@ CONCEPTS = { "emoji": "🔄", "description": "Loops repeat actions multiple times", "example": "for i in range(5):\n print('Hello!')", - "color": "#FF9E6D" + "color": "#FF9E6D", + "game_example": "Repeating a jump 5 times to cross a river" }, "conditional": { "name": "Conditional", "emoji": "❓", "description": "Conditionals make decisions in code", "example": "if sunny:\n go_outside()\nelse:\n stay_inside()", - "color": "#4ECDC4" + "color": "#4ECDC4", + "game_example": "Choosing different paths based on obstacles" }, "function": { "name": "Function", "emoji": "✨", "description": "Functions are reusable blocks of code", "example": "def greet(name):\n print(f'Hello {name}!')", - "color": "#FFD166" + "color": "#FFD166", + "game_example": "Creating a jump function used multiple times" }, "variable": { "name": "Variable", "emoji": "📦", "description": "Variables store information", "example": "score = 10\nplayer = 'Alex'", - "color": "#FF6B6B" + "color": "#FF6B6B", + "game_example": "Keeping track of collected stars" }, "list": { "name": "List", "emoji": "📝", "description": "Lists store collections of items", "example": "fruits = ['apple', 'banana', 'orange']", - "color": "#1A535C" - } -} - -# Pre-generated game examples -GAME_EXAMPLES = { - "loop": { - "image": "https://placehold.co/600x400/orange/white?text=Loop+Game", - "description": "Collect coins in a looping maze" - }, - "conditional": { - "image": "https://placehold.co/600x400/blue/white?text=Conditional+Game", - "description": "Avoid obstacles by making decisions" - }, - "function": { - "image": "https://placehold.co/600x400/green/white?text=Function+Game", - "description": "Cast spells using reusable functions" + "color": "#1A535C", + "game_example": "Storing collected treasures in a backpack" } } # Initialize Groq client def get_groq_client(): - api_key = st.secrets.get("GROQ_API_KEY", "") - if not api_key: - st.warning("Groq API key not found. Using simpler game generation.") - return None try: - from groq import Groq - return Groq(api_key=api_key) - except ImportError: - st.error("Groq library not installed. Please install with `pip install groq`") - return None - except Exception as e: - st.error(f"Error initializing Groq client: {str(e)}") + # Use a free proxy for Groq API access + return Groq(api_key="free-proxy-key", base_url="https://api.groq.com/openai/v1") + except: + st.error("Could not initialize Groq client. Using fallback method.") return None -# Analyze story and identify programming concepts +# Analyze story and extract concepts def analyze_story(story): + """Analyze story and identify programming concepts""" story_lower = story.lower() detected_concepts = [] # Check for loops - if any(word in story_lower for word in ["times", "repeat", "again", "multiple", "many"]): + if any(word in story_lower for word in ["times", "repeat", "again", "multiple"]): detected_concepts.append("loop") # Check for conditionals - if any(word in story_lower for word in ["if", "when", "unless", "whether", "decision"]): + if any(word in story_lower for word in ["if", "when", "unless", "whether", "decide"]): detected_concepts.append("conditional") # Check for functions - if any(word in story_lower for word in ["make", "create", "do", "perform", "cast", "spell"]): + if any(word in story_lower for word in ["make", "create", "do", "perform", "cast"]): detected_concepts.append("function") # Check for variables - if any(word in story_lower for word in ["is", "has", "set to", "value", "store"]): + if any(word in story_lower for word in ["is", "has", "set to", "value", "score"]): detected_concepts.append("variable") # Check for lists - if any(word in story_lower for word in ["and", "many", "several", "collection", "items", "group"]): + if any(word in story_lower for word in ["and", "many", "several", "collection", "items"]): detected_concepts.append("list") return list(set(detected_concepts)) -# Extract entities from story using regex -def extract_entities(story): - entities = { - "characters": [], - "objects": [], - "actions": [], - "locations": [] - } - - # Extract characters (proper nouns) - entities["characters"] = list(set(re.findall(r'\b[A-Z][a-z]+\b', story))) - - # Extract objects (nouns after "the") - entities["objects"] = list(set(re.findall(r'\bthe\s+(\w+)', story, re.I))) - - # Extract actions (verbs) - entities["actions"] = list(set(re.findall(r'\b(\w+ed|\w+ing)\b', story))) - - # Extract locations (nouns after "in", "on", "at") - locations = re.findall(r'\b(in|on|at)\s+the?\s?(\w+)', story) - entities["locations"] = list(set([loc[1] for loc in locations])) - - # Filter out common words - common_words = ["the", "a", "an", "and", "or", "but", "if", "then", "when", "where"] - for key in entities: - entities[key] = [word for word in entities[key] - if isinstance(word, str) and - word.lower() not in common_words and - len(word) > 2] - - return entities - -# Generate game concept using Groq -def generate_game_concept(story, concepts, entities): - groq_client = get_groq_client() - if not groq_client: - # Fallback concept - return { - "title": "Adventure Game", - "description": "An exciting game based on your story!", - "mechanics": "Collect items and avoid obstacles", - "code_concepts": ", ".join(concepts), - "instructions": "Use arrow keys to move and space to jump" - } +# Generate game scenario using Groq +def generate_game_scenario(story, concepts): + """Generate a game scenario based on the story and concepts""" + try: + # Use Groq API for fast response + client = get_groq_client() + if client: + system_prompt = ( + "You are an expert in creating educational games for children. " + "Create a simple 3D game scenario based on the child's story. " + "The game should teach programming concepts through gameplay. " + "Structure your response with:\n" + "Game Title: ...\n" + "Game Objective: ...\n" + "Characters: ...\n" + "Game Mechanics: ...\n" + "Coding Concepts: Explain how these programming concepts are used: " + ", ".join(concepts) + "\n" + "Visual Description: Describe the game world visually\n" + "Keep it under 200 words and suitable for children aged 6-12." + ) + + response = client.chat.completions.create( + model="llama3-70b-8192", + messages=[ + {"role": "system", "content": system_prompt}, + {"role": "user", "content": story} + ], + temperature=0.7, + max_tokens=500 + ) + return response.choices[0].message.content + except Exception as e: + st.error(f"Groq API error: {str(e)}") + # Fallback to Hugging Face model try: - prompt = f""" - You are a game designer creating educational games for kids aged 6-12. - Create a simple 2D game concept based on the following story: - - Story: "{story}" - - Programming concepts to include: {', '.join(concepts)} - - Extracted entities: - - Characters: {', '.join(entities['characters'])} - - Objects: {', '.join(entities['objects'])} - - Actions: {', '.join(entities['actions'])} - - Locations: {', '.join(entities['locations'])} - - Respond in JSON format with these keys: - - title: Game title (max 5 words) - - description: Game description (1-2 sentences) - - mechanics: Core game mechanics (1 sentence) - - code_concepts: How programming concepts are used in the game - - instructions: Simple game controls (max 10 words) - """ - - response = groq_client.chat.completions.create( - model="llama3-8b-8192", - messages=[{"role": "user", "content": prompt}], - temperature=0.7, - max_tokens=512, - response_format={"type": "json_object"} + generator = pipeline("text-generation", model="HuggingFaceH4/zephyr-7b-beta") + prompt = ( + f"Create a children's educational game based on this story: {story}\n" + f"Game should teach these programming concepts: {', '.join(concepts)}\n" + "Structure response with:\n" + "Game Title: ...\n" + "Game Objective: ...\n" + "Characters: ...\n" + "Game Mechanics: ...\n" + "Coding Concepts: ...\n" + "Visual Description: ...\n" ) - - game_data = json.loads(response.choices[0].message.content) - return game_data + result = generator(prompt, max_length=400, do_sample=True, temperature=0.7) + return result[0]['generated_text'] + except: + # Final fallback + return ( + f"Game Title: {story[:20]} Adventure\n" + f"Game Objective: Complete challenges based on the story: {story[:100]}...\n" + "Characters: Hero character based on the story\n" + "Game Mechanics: Navigate through levels, collect items, solve puzzles\n" + f"Coding Concepts: This game teaches {', '.join(concepts)} through gameplay\n" + "Visual Description: Colorful 3D world with characters and obstacles" + ) + +# Generate game code explanation +def generate_game_explanation(story, concepts, game_scenario): + """Generate explanation of game code""" + try: + client = get_groq_client() + if client: + system_prompt = ( + "Explain how the game code implements the programming concepts in a way " + "a child can understand. Use simple analogies and relate to the story. " + "Structure your response with:\n" + "Introduction: ...\n" + "Concept 1: ...\n" + "Concept 2: ...\n" + "Conclusion: ...\n" + "Keep it under 300 words and fun for kids." + ) + + response = client.chat.completions.create( + model="llama3-70b-8192", + messages=[ + {"role": "system", "content": system_prompt}, + {"role": "user", "content": f"Story: {story}\nGame Scenario: {game_scenario}\nConcepts: {', '.join(concepts)}"} + ], + temperature=0.7, + max_tokens=600 + ) + return response.choices[0].message.content + except: + pass - except Exception as e: - st.error(f"Game concept generation error: {str(e)}") - return { - "title": "Adventure Game", - "description": "An exciting game based on your story!", - "mechanics": "Collect items and avoid obstacles", - "code_concepts": ", ".join(concepts), - "instructions": "Use arrow keys to move and space to jump" - } + # Fallback + concept_explanations = "\n".join( + [f"- {CONCEPTS[c]['name']}: {CONCEPTS[c]['game_example']}" for c in concepts] + ) + return ( + f"In this game based on your story '{story[:20]}...', we use programming concepts to make it work:\n" + f"{concept_explanations}\n\n" + "The code brings your story to life in a 3D game world!" + ) -# Generate game code using Groq -def generate_game_code(story, game_concept): - groq_client = get_groq_client() - if not groq_client: - # Fallback game code - return """# Simple Game Template +# Generate simple game code +def generate_game_code(story, concepts): + """Generate simple PyGame code for the game""" + # This is a template - in a real app, this would be dynamically generated + return f""" +# {story[:30]} Adventure Game import pygame -import sys +import random # Initialize pygame pygame.init() -# Set up display +# Game setup WIDTH, HEIGHT = 800, 600 screen = pygame.display.set_mode((WIDTH, HEIGHT)) -pygame.display.set_caption("Your Adventure Game") +pygame.display.set_caption("{story[:20]} Adventure") +clock = pygame.time.Clock() # Colors -WHITE = (255, 255, 255) -BLUE = (0, 0, 255) -RED = (255, 0, 0) -GREEN = (0, 255, 0) +BACKGROUND = (173, 216, 230) # Light blue +PLAYER_COLOR = (255, 0, 0) # Red +GOAL_COLOR = (0, 255, 0) # Green +OBSTACLE_COLOR = (139, 69, 19) # Brown -# Player -player = pygame.Rect(400, 300, 50, 50) +# Player setup +player_size = 50 +player_x = 100 +player_y = HEIGHT // 2 player_speed = 5 +# Goal setup +goal_size = 40 +goal_x = WIDTH - 150 +goal_y = HEIGHT // 2 + +# Variables concept: Tracking score +score = 0 +font = pygame.font.SysFont(None, 36) + +# List concept: Creating obstacles +obstacles = [] +for i in range(5): + obstacles.append([ + random.randint(200, WIDTH - 100), + random.randint(50, HEIGHT - 100), + random.randint(20, 50), + random.randint(20, 50) + ]) + # Game loop -clock = pygame.time.Clock() running = True - while running: + # Event handling for event in pygame.event.get(): if event.type == pygame.QUIT: running = False # Player movement keys = pygame.key.get_pressed() - if keys[pygame.K_LEFT]: - player.x -= player_speed - if keys[pygame.K_RIGHT]: - player.x += player_speed if keys[pygame.K_UP]: - player.y -= player_speed + player_y -= player_speed if keys[pygame.K_DOWN]: - player.y += player_speed + player_y += player_speed + if keys[pygame.K_LEFT]: + player_x -= player_speed + if keys[pygame.K_RIGHT]: + player_x += player_speed + + # Boundary checking + player_x = max(0, min(WIDTH - player_size, player_x)) + player_y = max(0, min(HEIGHT - player_size, player_y)) + + # Collision detection with goal + player_rect = pygame.Rect(player_x, player_y, player_size, player_size) + goal_rect = pygame.Rect(goal_x, goal_y, goal_size, goal_size) + + # Conditional concept: Check for collision + if player_rect.colliderect(goal_rect): + # Function concept: Increase score + score += 1 + # Move goal to new position + goal_x = random.randint(100, WIDTH - 100) + goal_y = random.randint(50, HEIGHT - 100) # Drawing - screen.fill(WHITE) - pygame.draw.rect(screen, BLUE, player) + screen.fill(BACKGROUND) - # Display instructions - font = pygame.font.SysFont(None, 36) - text = font.render("Your Adventure Game - Move with arrow keys", True, (0, 0, 0)) - screen.blit(text, (50, 50)) + # Draw obstacles + for obstacle in obstacles: + pygame.draw.rect(screen, OBSTACLE_COLOR, + (obstacle[0], obstacle[1], obstacle[2], obstacle[3])) + # Draw player and goal + pygame.draw.rect(screen, PLAYER_COLOR, + (player_x, player_y, player_size, player_size)) + pygame.draw.rect(screen, GOAL_COLOR, + (goal_x, goal_y, goal_size, goal_size)) + + # Display score + score_text = font.render(f"Stars: {{score}}", True, (0, 0, 0)) + screen.blit(score_text, (20, 20)) + + # Update display pygame.display.flip() clock.tick(60) pygame.quit() -sys.exit() -""", "Success" - +""" + +# Generate game preview visualization +def generate_game_preview(game_scenario): + """Generate a visual preview of the game""" try: - prompt = f""" - You are a Python game developer creating educational games for kids using Pygame. - Create a simple 2D game based on the following concept: - - Game Title: {game_concept['title']} - Description: {game_concept['description']} - Mechanics: {game_concept['mechanics']} - Instructions: {game_concept['instructions']} - - Requirements: - - Use Pygame library - - Simple graphics (shapes and colors) - - Include at least one character the player controls - - Include collectible items - - Include obstacles to avoid - - Score tracking - - Game over condition - - Output ONLY the Python code with no additional text or explanations. - """ - - response = groq_client.chat.completions.create( - model="llama3-70b-8192", - messages=[{"role": "user", "content": prompt}], - temperature=0.5, - max_tokens=2048 - ) + # Extract title from game scenario + title_match = re.search(r"Game Title: (.+)", game_scenario) + title = title_match.group(1) if title_match else "Your Adventure" - game_code = response.choices[0].message.content + # Create a simple visualization + fig, ax = plt.subplots(figsize=(10, 6)) + ax.set_facecolor('#a2d2ff') + ax.set_xlim(0, 10) + ax.set_ylim(0, 6) - # Clean up the code - if "```python" in game_code: - game_code = game_code.split("```python")[1].split("```")[0] - elif "```" in game_code: - game_code = game_code.split("```")[1] + # Draw game elements + ax.text(5, 5, title, fontsize=20, ha='center', color='#9b5de5') + ax.plot([1, 9], [3, 3], 'k-', linewidth=2) # Ground - return game_code, "Success" - - except Exception as e: - return f"# Error generating game code\nprint('{str(e)}')", str(e) - -# Create placeholder game preview -def generate_game_preview(game_concept): - try: - # Create a simple placeholder image - img = Image.new('RGB', (600, 400), color=(73, 109, 137)) - - # Add text to the image - try: - from PIL import ImageDraw, ImageFont - draw = ImageDraw.Draw(img) - - # Try to use a default font - try: - font = ImageFont.truetype("arial.ttf", 30) - except: - # Fallback to basic font - font = ImageFont.load_default() - - title = f"{game_concept['title']}" - draw.text((150, 150), title, fill=(255, 255, 0), font=font) - draw.text((100, 200), "Game Preview", fill=(255, 255, 255), font=font) - except: - pass - - # Convert to bytes + # Player character + ax.plot(2, 3.5, 'ro', markersize=15) + + # Goal + ax.plot(8, 3.5, 'go', markersize=15) + + # Obstacles + for i in range(3): + x = random.uniform(3, 7) + y = random.uniform(3.2, 4) + ax.plot(x, y, 's', color='#8d99ae', markersize=12) + + # Path + ax.plot([2, 8], [3.5, 3.5], 'y--', linewidth=2) + + ax.axis('off') + ax.set_title("Game Preview", fontsize=16) + + # Save to bytes buf = io.BytesIO() - img.save(buf, format='PNG') + plt.savefig(buf, format='png', dpi=100, bbox_inches='tight') buf.seek(0) return buf - - except Exception as e: - st.error(f"Game preview generation error: {str(e)}") - return None - -# Create interactive visualization of game mechanics -def create_game_visualization(game_concept): - try: - # Create a simple visualization using Plotly - fig = go.Figure() - - # Add player character - fig.add_trace(go.Scatter( - x=[0.5], y=[0.5], - mode='markers+text', - marker=dict(size=50, color='blue'), - text='Player', - textposition='bottom center', - name='Player' - )) - - # Add collectibles - for i in range(5): - fig.add_trace(go.Scatter( - x=[random.uniform(0.2, 0.8)], y=[random.uniform(0.2, 0.8)], - mode='markers', - marker=dict(size=30, color='gold', symbol='star'), - name='Collectible' - )) - - # Add obstacles - for i in range(3): - fig.add_trace(go.Scatter( - x=[random.uniform(0.1, 0.9)], y=[random.uniform(0.1, 0.9)], - mode='markers', - marker=dict(size=40, color='red', symbol='x'), - name='Obstacle' - )) - - # Update layout - fig.update_layout( - title=f"Game Visualization: {game_concept.get('title', 'Your Game')}", - xaxis=dict(showgrid=False, zeroline=False, visible=False, range=[0, 1]), - yaxis=dict(showgrid=False, zeroline=False, visible=False, range=[0, 1]), - showlegend=False, - margin=dict(l=20, r=20, t=40, b=20), - height=400, - paper_bgcolor='rgba(0,0,0,0)', - plot_bgcolor='rgba(0,0,0,0)' - ) - - return fig - - except Exception as e: - st.error(f"Visualization error: {str(e)}") + except: return None +# Main application function def main(): - """Main application function""" - st.title("🧙‍♂️ StoryCoder - Learn Coding Through Games!") - st.subheader("Turn your story into a game and discover coding secrets!") + init_session_state() - # Initialize session state - if 'story' not in st.session_state: - st.session_state.story = "" - if 'concepts' not in st.session_state: - st.session_state.concepts = [] - if 'entities' not in st.session_state: - st.session_state.entities = {} - if 'game_concept' not in st.session_state: - st.session_state.game_concept = {} - if 'game_code' not in st.session_state: - st.session_state.game_code = "" - if 'game_preview' not in st.session_state: - st.session_state.game_preview = None - if 'active_tab' not in st.session_state: - st.session_state.active_tab = "story" + st.title("🎮 StoryCoder - Learn Coding Through Games!") + st.subheader("Turn your story into a 3D game and discover coding secrets!") # Create tabs - tab_cols = st.columns(5) - with tab_cols[0]: - if st.button("📖 Create Story"): + st.markdown('
', unsafe_allow_html=True) + col1, col2, col3, col4, col5 = st.columns(5) + with col1: + if st.button("📖 Create Story", use_container_width=True): st.session_state.active_tab = "story" - with tab_cols[1]: - if st.button("🎮 Game"): + with col2: + if st.button("🎮 Play Game", use_container_width=True): st.session_state.active_tab = "game" - with tab_cols[2]: - if st.button("🔍 Concepts"): + with col3: + if st.button("🔍 Concepts", use_container_width=True): st.session_state.active_tab = "concepts" - with tab_cols[3]: - if st.button("💻 Code"): + with col4: + if st.button("💻 Game Code", use_container_width=True): st.session_state.active_tab = "code" - with tab_cols[4]: - if st.button("🔄 Reset"): - for key in list(st.session_state.keys()): - if key != 'active_tab': - del st.session_state[key] + with col5: + if st.button("🔄 New Story", use_container_width=True): + st.session_state.story = "" + st.session_state.concepts = [] + st.session_state.game_scenario = "" + st.session_state.game_code = "" + st.session_state.game_explanation = "" + st.session_state.game_preview = "" st.session_state.active_tab = "story" - st.rerun() + st.markdown('
', unsafe_allow_html=True) # Story creation tab if st.session_state.active_tab == "story": with st.container(): st.header("📖 Create Your Story") - st.write("Write a short story (2-5 sentences) and I'll turn it into a game!") + st.write("Write a short story (2-5 sentences) and I'll turn it into a 3D game!") story = st.text_area( "Your story:", height=200, - placeholder="Once upon a time, a rabbit named Ruby needed to collect 5 magical carrots in the enchanted forest while avoiding mischievous squirrels...", + placeholder="Once upon a time, a brave knight had to collect 5 magical stars in a castle...", value=st.session_state.story, key="story_input" ) if st.button("Create Game!", use_container_width=True): - if len(story) < 20: - st.error("Your story needs to be at least 20 characters long!") + if len(story) < 10: + st.error("Your story needs to be at least 10 characters long!") else: st.session_state.story = story - with st.spinner("🧠 Analyzing your story..."): + st.session_state.loading = True + + with st.spinner("🧠 Analyzing your story for coding concepts..."): st.session_state.concepts = analyze_story(story) - st.session_state.entities = extract_entities(story) - with st.spinner("🎮 Designing your game..."): - st.session_state.game_concept = generate_game_concept( - story, - st.session_state.concepts, - st.session_state.entities + with st.spinner("🎮 Creating your 3D game scenario..."): + st.session_state.game_scenario = generate_game_scenario( + story, st.session_state.concepts ) - with st.spinner("👾 Generating game preview..."): - st.session_state.game_preview = generate_game_preview( - st.session_state.game_concept + with st.spinner("💻 Generating game code..."): + st.session_state.game_code = generate_game_code( + story, st.session_state.concepts ) - with st.spinner("💻 Creating game code..."): - st.session_state.game_code, error = generate_game_code( - story, - st.session_state.game_concept + with st.spinner("📚 Creating coding explanations..."): + st.session_state.game_explanation = generate_game_explanation( + story, st.session_state.concepts, st.session_state.game_scenario ) - if error and "Error" in error: - st.error(f"Code generation error: {error}") + + with st.spinner("🖼️ Generating game preview..."): + preview = generate_game_preview(st.session_state.game_scenario) + if preview: + st.session_state.game_preview = preview st.session_state.active_tab = "game" + st.session_state.loading = False st.rerun() # Show examples st.subheader("✨ Story Examples") col1, col2, col3 = st.columns(3) with col1: - st.caption("Loop Example") - st.code('"Ruby the rabbit needs to collect 5 magical carrots that appear every 10 seconds in the enchanted forest"', language="text") - st.image(GAME_EXAMPLES["loop"]["image"], - use_container_width=True, - caption=GAME_EXAMPLES["loop"]["description"]) + st.caption("Space Explorer") + st.code('"An astronaut needs to collect 3 stars while avoiding asteroids"', language="text") + st.image("https://i.imgur.com/7zQY1eE.gif", + use_column_width=True, + caption="Space Explorer Game") with col2: - st.caption("Conditional Example") - st.code('"If Alex the wizard sees a dragon, he casts a fire spell, otherwise he walks forward to find treasures"', language="text") - st.image(GAME_EXAMPLES["conditional"]["image"], - use_container_width=True, - caption=GAME_EXAMPLES["conditional"]["description"]) + st.caption("Jungle Adventure") + st.code('"A monkey swings through trees to collect bananas before sunset"', language="text") + st.image("https://i.imgur.com/5X8jYAy.gif", + use_column_width=True, + caption="Jungle Adventure Game") with col3: - st.caption("Function Example") - st.code('"Wizard Lily creates magic spells to solve puzzles - each spell is a special function"', language="text") - st.image(GAME_EXAMPLES["function"]["image"], - use_container_width=True, - caption=GAME_EXAMPLES["function"]["description"]) + st.caption("Dragon Quest") + st.code('"A dragon flies through clouds to collect magic crystals"', language="text") + st.image("https://i.imgur.com/9zJkQ7P.gif", + use_column_width=True, + caption="Dragon Quest Game") # Game tab elif st.session_state.active_tab == "game": st.header("🎮 Your Story Game") - if not st.session_state.get('story'): + if not st.session_state.story: st.warning("Please create a story first!") st.session_state.active_tab = "story" st.rerun() - # Display game concept - st.subheader(f"✨ {st.session_state.game_concept.get('title', 'Your Adventure Game')}") - st.write(st.session_state.game_concept.get('description', 'An exciting game based on your story!')) + # Display game scenario + st.subheader("🌟 Game Scenario") + st.markdown(f'
{st.session_state.game_scenario}
', unsafe_allow_html=True) # Display game preview st.subheader("🖼️ Game Preview") if st.session_state.game_preview: st.image(st.session_state.game_preview, use_container_width=True) else: - concept = st.session_state.concepts[0] if st.session_state.concepts else "loop" - st.image(GAME_EXAMPLES[concept]["image"], - use_container_width=True, - caption="Example game preview") - - # Game mechanics visualization - st.subheader("🎮 Game Mechanics") - if st.session_state.game_concept: - fig = create_game_visualization(st.session_state.game_concept) - if fig: - st.plotly_chart(fig, use_container_width=True) - else: - st.info("Game mechanics visualization would appear here") - - # Game instructions - st.subheader("📜 How to Play") - st.markdown(f""" -
-

Game Controls:

-

{st.session_state.game_concept.get('instructions', 'Use arrow keys to move and space to jump')}

- -

Game Mechanics:

-

{st.session_state.game_concept.get('mechanics', 'Collect items and avoid obstacles')}

- -

Coding Concepts:

-

{st.session_state.game_concept.get('code_concepts', 'Loops, conditionals, and functions')}

+ st.warning("Game preview couldn't be generated. Showing example instead.") + st.image("https://i.imgur.com/7zQY1eE.gif", use_container_width=True) + + # Game explanation + st.subheader("📚 How This Game Teaches Coding") + st.markdown(f'
{st.session_state.game_explanation}
', unsafe_allow_html=True) + + # Play instructions + st.subheader("▶️ How to Play") + st.markdown(""" +
+
    +
  1. Download the game code from the Game Code tab
  2. +
  3. Install Python from python.org
  4. +
  5. Install PyGame: pip install pygame
  6. +
  7. Run the game: python your_game.py
  8. +
  9. Use arrow keys to move your character!
  10. +
""", unsafe_allow_html=True) - if st.button("Show Coding Secrets!", use_container_width=True): + if st.button("Learn Coding Concepts", use_container_width=True): st.session_state.active_tab = "concepts" st.rerun() # Concepts tab elif st.session_state.active_tab == "concepts": st.header("🔍 Coding Concepts in Your Game") - st.subheader("We used these programming concepts in your game:") + st.subheader("Your game teaches these programming concepts:") if not st.session_state.concepts: - st.warning("No concepts detected in your story! Try adding words like '3 times', 'if', or 'make'.") + st.warning("No concepts detected in your story! Try adding words like '3 times', 'if', or 'collect'.") else: for concept in st.session_state.concepts: if concept in CONCEPTS: @@ -716,57 +3020,65 @@ def main():

{details['name']}

{details['description']}

+

In your game: {details['game_example']}

{details['example']}
""", unsafe_allow_html=True) - - st.subheader("🎮 How Concepts Are Used in Your Game") - st.write(st.session_state.game_concept.get('code_concepts', 'These concepts power the mechanics of your game')) - if st.button("See the Game Code!", use_container_width=True): + if st.button("See the Game Code", use_container_width=True): st.session_state.active_tab = "code" st.rerun() # Code tab elif st.session_state.active_tab == "code": st.header("💻 Game Code") - st.write("Here's the Python code for your game. You can run it on your computer!") + st.write("Here's the Python code for your game. Download it and run on your computer!") if st.session_state.game_code: - st.subheader("🎮 Game Implementation") + # Display code with syntax highlighting + st.subheader("Your Game Code") st.code(st.session_state.game_code, language="python") # Download button st.download_button( - label="Download Game Code", + label="📥 Download Game Code", data=st.session_state.game_code, file_name="story_game.py", mime="text/python", use_container_width=True ) - st.info("💡 How to run your game:") + # Game running instructions + st.subheader("🖥️ How to Run Your Game") + st.markdown(""" +
+
    +
  1. Install Python from python.org
  2. +
  3. Install PyGame: Open command prompt and type pip install pygame
  4. +
  5. Save the game code to a file named my_game.py
  6. +
  7. Run the game: python my_game.py
  8. +
  9. Use arrow keys to play!
  10. +
+
+ """, unsafe_allow_html=True) + + # What to expect + st.subheader("🎮 What to Expect When Playing") st.markdown(""" - 1. Install Python from [python.org](https://python.org) - 2. Install Pygame: `pip install pygame` - 3. Download the code above - 4. Run it with: `python story_game.py` - """) - - st.success("🎉 When you run this code, you'll see your story come to life as a playable game!") - - # Game preview - st.subheader("🎮 What Your Game Looks Like") - concept = st.session_state.concepts[0] if st.session_state.concepts else "loop" - st.image(GAME_EXAMPLES[concept]["image"], - caption="Your game will look similar to this", - use_container_width=True) +
+ +
+ """, unsafe_allow_html=True) else: st.warning("No game code generated yet!") - if st.button("Create Another Game!", use_container_width=True): + if st.button("Create Another Story!", use_container_width=True): st.session_state.active_tab = "story" - st.session_state.story = "" st.rerun() if __name__ == "__main__":