page3 / app.py
pranit144's picture
Upload 15 files
09d8270 verified
from flask import Flask, render_template, session, redirect, url_for, request
import time
from pathlib import Path
import random
app = Flask(__name__)
# Set a secret key for session management. CHANGE THIS IN PRODUCTION!
app.secret_key = 'your_super_secret_key_for_flask_session_security'
# --- Game Data ---
# Updated video paths to be relative to the 'static/videos' directory
videos = [
"static/videos/Animated_Drought_Relief_Video_Creation.mp4",
"static/videos/Animated_Rainwater_Harvesting_Video.mp4",
"static/videos/Animated_Water_Filtration_Process_Video.mp4",
"static/videos/Water_Filtration_Animation_Ready.mp4",
"static/videos/Animated_Rainwater_Usage_Video.mp4",
"static/videos/Water_Hero_Video_Generation_Complete.mp4"
]
video_descriptions = [
"🌍 Water Crisis Alert",
"🏠 Collection Master",
"💧 Purification Expert",
"🗃️ Storage Specialist",
"♻️ Usage Strategist",
"🌱 Environmental Champion"
]
# Enhanced task cards with detailed scenarios and consequences
task_scenarios = [
# Video 0 - Water Crisis (has question)
{
"question": "🌍 After watching the video, what is the FIRST step to address water scarcity at your home?",
"choices": [
{
"action": "🌧️ Start collecting rainwater immediately",
"description": "Begin harvesting nature's free water supply",
"consequence": "✅ SMART START! You're taking the first step toward water independence! +100 XP",
"xp_reward": 100,
"icon": "🏆"
},
{
"action": "🚿 Take longer showers to enjoy water while it lasts",
"description": "Use more water before it runs out",
"consequence": "❌ WRONG APPROACH! This worsens the problem. Conservation is key! -20 Health",
"xp_reward": 0,
"icon": "💸"
},
{
"action": "⏳ Wait for government to solve the problem",
"description": "Rely on authorities to fix water issues",
"consequence": "❌ MISSED OPPORTUNITY! Individual action is crucial. Start now! -20 Health",
"xp_reward": 0,
"icon": "⏰"
}
]
},
# Video 1 - Collection
{
"question": "🌧️ It's raining heavily! Your house has a metal roof. What's your FIRST action as a Water Conservation Hero?",
"choices": [
{
"action": "🏠 Install gutters and downspouts on your roof",
"description": "Channel rainwater efficiently into collection system",
"consequence": "✅ SMART MOVE! You capture 80% of the rainfall from your roof area. +100 XP",
"xp_reward": 100,
"icon": "🏆"
},
{
"action": "🛣️ Let the water flow down the streets",
"description": "Allow natural drainage to carry water away",
"consequence": "❌ MISSED OPPORTUNITY! Thousands of liters wasted into storm drains. -20 Health",
"xp_reward": 0,
"icon": "💸"
},
{
"action": "🛍️ Place plastic bags under the roof edge",
"description": "Use bags to catch dripping water",
"consequence": "❌ INEFFICIENT! Bags tear easily and collect very little water. Try a proper system! -20 Health",
"xp_reward": 0,
"icon": "🗑️"
}
]
},
# Video 2 - Filtration
{
"question": "💧 Your collection tank is filling up with rainwater, but you notice leaves and debris floating in it. What's your next critical step?",
"choices": [
{
"action": "🔍 Install a first-flush diverter and filtration system",
"description": "Remove initial dirty water and filter the rest",
"consequence": "✅ EXCELLENT CHOICE! Clean, safe water ready for storage. Your filtration efficiency: 95%! +100 XP",
"xp_reward": 100,
"icon": "🧪"
},
{
"action": "⚠️ Use the dirty water directly without treatment",
"description": "Proceed with unfiltered rainwater",
"consequence": "❌ HEALTH HAZARD! Contaminated water can cause serious illness. Always filter first! -20 Health",
"xp_reward": 0,
"icon": "☠️"
},
{
"action": "🧪 Add household bleach to kill germs",
"description": "Chemical treatment of collected water",
"consequence": "❌ WRONG CHEMICAL! Bleach is not safe for water treatment. Use proper filtration! -20 Health",
"xp_reward": 0,
"icon": "⚗️"
}
]
},
# Video 3 - Storage
{
"question": "🏺 You have 500 liters of clean, filtered rainwater. The monsoon season is ending soon. Where should you store this precious resource?",
"choices": [
{
"action": "🏺 Install an underground concrete tank with cover",
"description": "Professional storage solution with temperature control",
"consequence": "✅ MASTER STRATEGY! Water stays cool, clean, and safe for months. Storage efficiency: 100%! +100 XP",
"xp_reward": 100,
"icon": "🏛️"
},
{
"action": "🪣 Store in open buckets around your yard",
"description": "Multiple container approach for easy access",
"consequence": "❌ BREEDING GROUND! Open water attracts mosquitoes and gets contaminated. -20 Health",
"xp_reward": 0,
"icon": "🦟"
},
{
"action": "🌍 Dig a pit and let water sit directly in ground",
"description": "Natural ground storage method",
"consequence": "❌ CONTAMINATION RISK! Soil bacteria and insects will pollute your water. -20 Health",
"xp_reward": 0,
"icon": "🕳️"
}
]
},
# Video 4 - Usage
{
"question": "♻️ Dry season has arrived! You have 200 liters of stored rainwater left. Your neighbor is asking for help with their garden. How do you maximize the impact?",
"choices": [
{
"action": "🌿 Use for drip irrigation and toilet flushing",
"description": "Strategic usage for maximum water conservation",
"consequence": "✅ WATER WISDOM! You save 300L of municipal water and help the environment! +100 XP",
"xp_reward": 100,
"icon": "🌱"
},
{
"action": "⏰ Save all water for potential emergencies later",
"description": "Conservative approach for future needs",
"consequence": "❌ MISSED IMPACT! Water can spoil if stored too long. Use it wisely now! -20 Health",
"xp_reward": 0,
"icon": "⏰"
},
{
"action": "🚽 Mix with sewage water for disposal",
"description": "Combine with waste water system",
"consequence": "❌ TERRIBLE WASTE! Never contaminate clean water with sewage! -20 Health",
"xp_reward": 0,
"icon": "🤮"
}
]
},
# Video 5 - Environmental Impact (has question)
{
"question": "🌱 Now that you've mastered rainwater harvesting, how will you inspire your community to join the movement?",
"choices": [
{
"action": "👥 Organize community workshops and share your knowledge",
"description": "Teach others about water conservation benefits",
"consequence": "✅ COMMUNITY HERO! You inspire 50 families to start rainwater harvesting! +100 XP",
"xp_reward": 100,
"icon": "🌟"
},
{
"action": "🤐 Keep the knowledge to yourself for competitive advantage",
"description": "Maintain exclusive access to water conservation techniques",
"consequence": "❌ SELFISH APPROACH! Environmental problems need collective solutions! -20 Health",
"xp_reward": 0,
"icon": "🚫"
},
{
"action": "📱 Only post about it on social media occasionally",
"description": "Share water conservation tips online when convenient",
"consequence": "❌ MINIMAL IMPACT! Real change needs active community engagement! -20 Health",
"xp_reward": 0,
"icon": "📱"
}
]
}
]
# Achievement definitions
achievements_list = [
{"name": "🌟 First Steps", "desc": "Started your water journey", "condition": "start"},
{"name": "💧 Drop Collector", "desc": "Learned about collection", "condition": "video_1"},
{"name": "🔬 Purification Pro", "desc": "Mastered filtration", "condition": "video_2"},
{"name": "🏺 Storage Sage", "desc": "Understood storage methods", "condition": "video_3"},
{"name": "♻️ Usage Expert", "desc": "Optimized water usage", "condition": "video_4"},
{"name": "🎯 Perfect Score", "desc": "100% accuracy achieved", "condition": "perfect"},
{"name": "🔥 On Fire", "desc": "3 correct answers in a row", "condition": "streak_3"},
{"name": "🌍 Water Hero", "desc": "Completed the full quest", "condition": "complete"}
]
# --- Helper Functions (adapted for Flask session) ---
def calculate_level() -> int:
return min(10, 1 + session.get('xp_points', 0) // 100)
def add_xp(amount: int):
old_level = session.get('player_level', 1)
session['xp_points'] = session.get('xp_points', 0) + amount
session['player_level'] = calculate_level()
if session['player_level'] > old_level:
session['message'] = f"🎉 LEVEL UP! You reached Level {session['player_level']}!"
def unlock_achievement(condition: str):
for achievement in achievements_list:
if achievement["condition"] == condition and achievement not in session.get('achievements', []):
session['achievements'] = session.get('achievements', []) + [achievement]
session['message'] = f"🏆 Achievement Unlocked: {achievement['name']} - {achievement['desc']}"
add_xp(50)
def initialize_game_state():
session.setdefault("video_index", 0)
session.setdefault("feedback", "")
session.setdefault("quiz_correct_count", 0)
session.setdefault("quiz_attempts", 0)
session.setdefault("player_level", 1)
session.setdefault("xp_points", 0)
session.setdefault("achievements", [])
session.setdefault("streak", 0)
session.setdefault("health", 100)
session.setdefault("video_watched", False)
session.setdefault("question_answered", False)
session.setdefault("message", "") # For temporary messages like level-up
def next_video_logic():
if session['video_index'] < len(videos) - 1:
session['video_index'] += 1
session['feedback'] = ""
session['video_watched'] = False
session['question_answered'] = False
session['message'] = ""
if session['video_index'] > 0:
unlock_achievement(f"video_{session['video_index']}")
return redirect(url_for('main_app'))
else:
unlock_achievement("complete")
return redirect(url_for('summary_page'))
def mark_video_watched_logic():
session['video_watched'] = True
session['message'] = ""
def replay_video_logic():
session['feedback'] = ""
session['video_watched'] = False
session['question_answered'] = False
session['message'] = "🔄 Video ready for replay! Click play to watch again."
def reset_quest_logic():
session.clear() # Clears all session data
initialize_game_state() # Reinitialize with default values
def select_card_logic(choice_index: int):
current_scenario = task_scenarios[session['video_index']]
choice = current_scenario["choices"][choice_index]
session['quiz_attempts'] = session.get('quiz_attempts', 0) + 1
session['question_answered'] = True
session['feedback'] = choice["consequence"]
session['message'] = "" # Clear any previous messages
if choice["xp_reward"] > 0:
session['quiz_correct_count'] = session.get('quiz_correct_count', 0) + 1
session['streak'] = session.get('streak', 0) + 1
add_xp(choice["xp_reward"])
if session['streak'] >= 3:
unlock_achievement("streak_3")
else:
session['streak'] = 0
session['health'] = max(0, session.get('health', 100) - 20)
# --- Flask Routes ---
@app.route('/')
def welcome_page():
if 'player_level' not in session: # Only initialize if not already in session (e.g., first visit or after full reset)
initialize_game_state()
return render_template('welcome.html')
@app.route('/begin_quest', methods=['POST'])
def begin_quest():
unlock_achievement("start")
return redirect(url_for('main_app'))
@app.route('/main', methods=['GET', 'POST'])
def main_app():
if 'player_level' not in session: # If somehow landed here without initializing
return redirect(url_for('welcome_page'))
# Handle form submissions
if request.method == 'POST':
if 'mark_watched' in request.form:
mark_video_watched_logic()
elif 'select_choice' in request.form:
choice_index = int(request.form['select_choice'])
select_card_logic(choice_index)
elif 'next_level' in request.form or 'continue_quest' in request.form:
return next_video_logic() # This function handles redirection
elif 'replay_video' in request.form:
replay_video_logic()
return redirect(url_for('main_app')) # Redirect to show replay message
elif 'main_menu' in request.form:
return redirect(url_for('welcome_page'))
return redirect(url_for('main_app')) # Redirect after POST to prevent resubmission
current_video_index = session.get('video_index', 0)
current_video_path = videos[current_video_index]
# Determine if it's a local video (starts with 'videos/') or a URL
is_local_video = current_video_path.startswith('videos/')
if is_local_video:
video_src = url_for('static', filename=current_video_path)
else:
video_src = current_video_path # It's a full URL
# Check if local file exists if it's a local video
local_file_exists = True
if is_local_video:
full_path = Path(app.static_folder) / current_video_path
if not full_path.exists():
local_file_exists = False
context = {
'current_video_index': current_video_index,
'total_videos': len(videos),
'video_src': video_src,
'is_local_video': is_local_video,
'local_file_exists': local_file_exists,
'video_description': video_descriptions[current_video_index],
'current_scenario': task_scenarios[current_video_index],
'player_level': session.get('player_level', 1),
'xp_points': session.get('xp_points', 0),
'health': session.get('health', 100),
'streak': session.get('streak', 0),
'quiz_correct_count': session.get('quiz_correct_count', 0),
'quiz_attempts': session.get('quiz_attempts', 0),
'video_watched': session.get('video_watched', False),
'question_answered': session.get('question_answered', False),
'feedback': session.get('feedback', ''),
'achievements': session.get('achievements', []),
'message': session.pop('message', '') # Pop message so it only shows once
}
return render_template('main.html', **context)
@app.route('/summary')
def summary_page():
if 'player_level' not in session:
return redirect(url_for('welcome_page'))
total_quizzes = len([s for s in task_scenarios if s.get("choices")])
score = session.get('quiz_correct_count', 0)
if score == total_quizzes and total_quizzes > 0:
unlock_achievement("perfect")
context = {
'player_level': session.get('player_level', 1),
'xp_points': session.get('xp_points', 0),
'quiz_score': score,
'total_quizzes': total_quizzes,
'accuracy': (score / max(1, total_quizzes)) * 100,
'streak': session.get('streak', 0),
'achievements': session.get('achievements', []),
'current_date': time.strftime("%B %d, %Y"),
'message': session.pop('message', '')
}
return render_template('summary.html', **context)
@app.route('/restart_quest', methods=['POST'])
def restart_quest():
reset_quest_logic()
return redirect(url_for('welcome_page'))
@app.route('/view_stats', methods=['POST'])
def view_stats():
session['message'] = "Detailed stats coming soon!"
return redirect(url_for('summary_page'))
@app.route('/share_impact', methods=['POST'])
def share_impact():
session['message'] = "🌟 Your impact is shared!"
return redirect(url_for('summary_page'))
if __name__ == '__main__':
app.run(debug=True) # Set debug=False in production