import gradio as gr
import pandas as pd
import numpy as np
import random
import time
# --- Game Greetings (Static HTML) ---
ARABIC_HEADER = """
بمناسبة حلول العيد
يتقدم فريق علماء البيانات المغاربة بأحر التهاني وأطيب التبريكات لجميع أعضاء مجتمعنا.
عيد مبارك سعيد وكل عام وأنتم بخير. 😉
"""
# --- Game Data & Stages (The Text Adventure) ---
STAGES_DATA = {
0: { # Round 1: Setup
"title": "Round 1: Pipeline Initialization (Morning)",
"terminal_text": "System booted. Connection to mosque established. Training Phase (Ramadan) complete. Please select your 'Social Aura Model' for the Eid Deployment.",
"choices": [
("Model A: Humble Scientist (Focus: Listening, 🔋Social Save)", {"social_delta": +10, "stomach_delta": 0, "eidiya_delta": +50}),
("Model B: Successful Flexer (Focus: Talking, 💰Eidiya Boost)", {"social_delta": -20, "stomach_delta": 0, "eidiya_delta": +200}),
("Model C: Overfitted Dev (Focus: Silence, ⚠️High Crash Risk)", {"social_delta": -40, "stomach_delta": 0, "eidiya_delta": 0}),
]
},
1: { # Round 2: Breakfast
"title": "Round 2: Input Stream Processing (Breakfast)",
"terminal_text": "Unexpected high-volume dataset detected: Multiple plates of Msemmen, Beghrir, and Kaab el Ghazal. Aunt Fatima demands data parsing.",
"choices": [
("sample(n=1, strategy='polite')", {"social_delta": -10, "stomach_delta": +15, "eidiya_delta": 0}),
("batch_processing(intensity='max')", {"social_delta": +10, "stomach_delta": +60, "eidiya_delta": +50}),
("Execute: skip_breakfast()", {"social_delta": -30, "stomach_delta": 0, "eidiya_delta": -50}),
]
},
2: { # Round 3: Visiting
"title": "Round 3: Distributed Network Cross-Validation",
"terminal_text": "Time to visit nodes in the family tree. Select routing algorithm.",
"choices": [
("Depth-First Search (Visit every single uncle/aunt in the village)", {"social_delta": -50, "stomach_delta": +10, "eidiya_delta": +150}),
("Breadth-First Search (Quick city loop, visit high-Eidiya nodes only)", {"social_delta": -10, "stomach_delta": +40, "eidiya_delta": +300}),
("Skip Cross-Validation (Stay home, check server logs)", {"social_delta": -60, "stomach_delta": 0, "eidiya_delta": 0}),
]
},
3: { # Round 4: Aunt Question
"title": "Round 4: Unexpected Black Box Query",
"terminal_text": "Critical Event: Uncle Hassan's wife Node.AuntFatima initiated `query: marriage_status()`. This function has no defined documentation in your current model.",
"choices": [
("A: 'Model is still in pre-alpha deployment'", {"social_delta": -10, "stomach_delta": 0, "eidiya_delta": -50}),
("B: 'Overfitting on work dataset'", {"social_delta": -20, "stomach_delta": 0, "eidiya_delta": 0}),
("C: Execute dodge_query() sub-routine", {"social_delta": +10, "stomach_delta": +20, "eidiya_delta": 0}), # Dodge means eating more sweets at her table
]
},
4: { # Final Score
"title": "Final Deployment Evaluation (Evening)",
"terminal_text": "Deployment phase complete. System reaching termination sequence. Parsing final logs...",
"choices": [] # Game ends here
}
}
MAX_STOMACH = 100
MAX_SOCIAL = 100
# --- Game Game Logic ---
def process_choice(choice_index, current_state):
"""
Main Game Controller. Advances stage and updates resources.
"""
if current_state is None:
current_state = {"stage": 0, "social": MAX_SOCIAL, "stomach": 0, "eidiya": 0, "game_over": False}
# Don't process if the game is already over
if current_state.get("game_over"):
return update_game_ui(current_state)
stage_idx = current_state["stage"]
stage_data = STAGES_DATA.get(stage_idx)
# Process the choice consequences (except for Stage 0 init button)
if choice_index is not None and stage_idx < 4:
selected_choice = stage_data["choices"][choice_index]
consequences = selected_choice[1]
current_state["social"] = max(0, min(MAX_SOCIAL, current_state["social"] + consequences["social_delta"]))
current_state["stomach"] = max(0, min(MAX_STOMACH + 20, current_state["stomach"] + consequences["stomach_delta"]))
current_state["eidiya"] = max(0, current_state["eidiya"] + consequences["eidiya_delta"])
# Check for failure conditions (Critical Errors)
if current_state["social"] <= 0:
current_state["game_over"] = True
current_state["final_msg"] = "CRITICAL ERROR: Social Battery hit 0%. System shut down due to exhaustion. (Relative Disapproval)."
elif current_state["stomach"] >= MAX_STOMACH:
current_state["game_over"] = True
current_state["final_msg"] = "FATAL ERROR: Stomach Capacity exceeded (Integer Overflow). Couscous detected in CPU. Please rest."
# Advance the stage (if not game over)
if not current_state.get("game_over"):
current_state["stage"] += 1
return update_game_ui(current_state)
def reset_game():
"""Returns the initial game state."""
return {"stage": 0, "social": MAX_SOCIAL, "stomach": 0, "eidiya": 0, "game_over": False}
def update_game_ui(state):
"""
Renders the UI based on the current State.
Crucial for updating button visibility and labels.
"""
stage_idx = state["stage"]
stage_data = STAGES_DATA.get(stage_idx)
# 1. Update Resource Indicators
social_text = f"🔋 Social Battery: {state['social']}%"
stomach_text = f"🛑 Stomach Capacity: {state['stomach']}%"
eidiya_text = f"💰 Eidiya Balance: {state['eidiya']} MAD"
# 2. Update Console (Terminal) and Round Title
round_title = stage_data["title"]
if state.get("game_over"):
terminal_out = f"## ⚠️ SYSTEM CRASH ⚠️\n\n{state['final_msg']}\n\nRestart game to try again."
round_title = "SYSTEM OVERLOAD"
return [
# State Update
gr.State(state),
# UI Updates
round_title, terminal_out,
# Reset visibility of buttons
gr.update(visible=True, value="Restart Deployment Cycle (New Game)"),
gr.update(visible=False), gr.update(visible=False), gr.update(visible=False),
# Update resources
gr.update(value=social_text, variant="secondary" if state['social'] > 20 else "stop"),
gr.update(value=stomach_text, variant="secondary" if state['stomach'] < 80 else "stop"),
eidiya_text
]
elif stage_idx == 4: # Final Score
final_score = (state['eidiya'] + state['social']) - state['stomach']
terminal_out = f"""
## Final Output: 📈 End of Day Evaluation
System status: **DEPLOYED SUCCESSFULLY** (Barely).
### Final Statistics:
* Social Battery Remaining: **{state['social']}%** (Stable)
* Stomach Load: **{state['stomach']}%** (Safe Level)
* Total Eidiya Collected: **{state['eidiya']} MAD** (Infinite Blessings)
* **Deployment Score: {final_score:,}**
تقبل الله منا ومنكم صالح الأعمال.
*Eid Mubarak to the Moroccan Data Scientists community! Scalable happiness, infinite blessings ♾️*
"""
return [
gr.State(state),
round_title, terminal_out,
gr.update(visible=True, value="Deploy New Instance (New Game)"), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False),
social_text, stomach_text, eidiya_text
]
else: # Ongoing game
terminal_out = f"[{time.strftime('%H:%M:%S')}] {stage_data['terminal_text']}"
choices = stage_data["choices"]
# Determine button updates (hide if less than 3 choices)
btn1_update = gr.update(value=choices[0][0], visible=True)
btn2_update = gr.update(value=choices[1][0], visible=True)
btn3_update = gr.update