Spaces:
Sleeping
Sleeping
import streamlit as st | |
import pandas as pd | |
import plotly.express as px | |
import random | |
import uuid | |
from datetime import datetime | |
from streamlit_flow import streamlit_flow | |
from streamlit_flow.elements import StreamlitFlowNode, StreamlitFlowEdge | |
from streamlit_flow.layouts import TreeLayout | |
# ๐ Game World Data | |
SITUATIONS = [ | |
{ | |
"id": "feline_escape", | |
"name": "The Great Feline Escape", | |
"description": "Your cat rider is trapped in an old mansion, which is about to be demolished. Using agility, wit, and bravery, orchestrate the perfect escape.", | |
"emoji": "๐ช" | |
}, | |
{ | |
"id": "lost_temple", | |
"name": "The Treasure of the Lost Temple", | |
"description": "On a quest to retrieve an ancient artifact, your cat rider must navigate through a labyrinth filled with traps and guardian spirits.", | |
"emoji": "๐๏ธ" | |
}, | |
{ | |
"id": "royal_tournament", | |
"name": "The Royal Tournament", | |
"description": "Compete in a grand tournament where the finest cat riders showcase their skills and bravery to earn the title of the Royal Rider.", | |
"emoji": "๐" | |
} | |
] | |
ACTIONS = [ | |
{ | |
"id": "stealth", | |
"name": "Use Stealth", | |
"description": "Sneak past obstacles or enemies without being detected.", | |
"emoji": "๐คซ" | |
}, | |
{ | |
"id": "agility", | |
"name": "Showcase Agility", | |
"description": "Perform impressive acrobatic maneuvers to overcome challenges.", | |
"emoji": "๐" | |
}, | |
{ | |
"id": "charm", | |
"name": "Charm Others", | |
"description": "Use your cat's natural charisma to win over allies or distract foes.", | |
"emoji": "๐ป" | |
}, | |
{ | |
"id": "resourcefulness", | |
"name": "Be Resourceful", | |
"description": "Utilize the environment or items in creative ways to solve problems.", | |
"emoji": "๐ง " | |
} | |
] | |
# ๐ฒ Game Mechanics | |
def generate_situation(): | |
return random.choice(SITUATIONS) | |
def generate_actions(): | |
return random.sample(ACTIONS, 3) | |
def evaluate_action(action, gear_strength, rider_skill, history): | |
base_success_chance = (gear_strength + rider_skill) / 2 | |
if action['id'] in history: | |
success_chance = base_success_chance + (history[action['id']] * 2) | |
else: | |
success_chance = base_success_chance | |
outcome = random.randint(1, 100) <= success_chance | |
return outcome, success_chance | |
# ๐ณ Journey Visualization | |
def create_graph_from_history(history_df): | |
nodes = [] | |
edges = [] | |
for index, row in history_df.iterrows(): | |
node_id = f"{index}-{row['situation_id']}-{row['action_id']}" | |
content = f"{row['situation_emoji']} {row['situation_name']}\n{row['action_emoji']} {row['action_name']}\nOutcome: {'โ Success' if row['outcome'] else 'โ Failure'}\n๐ {row['timestamp']}" | |
new_node = StreamlitFlowNode(node_id, (0, 0), {'content': content}, 'output', 'bottom', 'top') | |
nodes.append(new_node) | |
if index > 0: | |
prev_node_id = f"{index-1}-{history_df.iloc[index-1]['situation_id']}-{history_df.iloc[index-1]['action_id']}" | |
new_edge = StreamlitFlowEdge(f"{prev_node_id}-{node_id}", prev_node_id, node_id, animated=True, dashed=True) | |
edges.append(new_edge) | |
return nodes, edges | |
# ๐ Markdown Preview | |
def create_markdown_preview(history_df): | |
markdown = "## ๐ณ Journey Preview\n\n" | |
for index, row in history_df.iterrows(): | |
indent = " " * index | |
markdown += f"{indent}- {row['situation_emoji']} **{row['situation_name']}**\n" | |
markdown += f"{indent} - {row['action_emoji']} {row['action_name']}: " | |
markdown += "โ Success\n" if row['outcome'] else "โ Failure\n" | |
return markdown | |
# ๐ Game State Management | |
def update_game_state(game_state, situation, action, outcome, timestamp): | |
new_record = pd.DataFrame({ | |
'user_id': [game_state['user_id']], | |
'timestamp': [timestamp], | |
'situation_id': [situation['id']], | |
'situation_name': [situation['name']], | |
'situation_emoji': [situation['emoji']], | |
'action_id': [action['id']], | |
'action_name': [action['name']], | |
'action_emoji': [action['emoji']], | |
'outcome': [outcome], | |
'score': [game_state['score']] | |
}) | |
game_state['history_df'] = pd.concat([game_state['history_df'], new_record], ignore_index=True) | |
if action['id'] in game_state['history']: | |
game_state['history'][action['id']] += 1 if outcome else -1 | |
else: | |
game_state['history'][action['id']] = 1 if outcome else -1 | |
return game_state | |
# ๐ฎ Main Game Application | |
def main(): | |
st.title("๐ฑ Cat Rider ๐") | |
st.markdown(""" | |
## Welcome to Cat Rider! | |
In this immersive adventure, you will explore the thrilling world of feline riders. This game sets the stage for dramatic situations and guided storytelling with engaging interactive elements. | |
""") | |
# ๐ Game Rules | |
st.markdown(""" | |
### ๐ Game Rules | |
| ๐ค๏ธ Step | ๐ Description | | |
|---------|----------------| | |
| 1๏ธโฃ | Choose your Cat Rider | | |
| 2๏ธโฃ | Select the Riding Gear | | |
| 3๏ธโฃ | Set off on an Adventure | | |
| 4๏ธโฃ | Encounter Challenges and Make Decisions | | |
| 5๏ธโฃ | Complete the Quest | | |
""") | |
# ๐ Initialize game state | |
if 'game_state' not in st.session_state: | |
st.session_state.game_state = { | |
'user_id': str(uuid.uuid4()), | |
'score': 0, | |
'history': {}, | |
'gear_strength': 5, | |
'rider_skill': 5, | |
'history_df': pd.DataFrame(columns=['user_id', 'timestamp', 'situation_id', 'situation_name', 'situation_emoji', 'action_id', 'action_name', 'action_emoji', 'outcome', 'score']) | |
} | |
# ๐ Game Stats | |
st.sidebar.markdown("## ๐ Game Stats") | |
st.sidebar.markdown(f"**Score:** {st.session_state.game_state['score']}") | |
# ๐ฆธ Character Stats | |
gear_strength = st.sidebar.slider('Gear Strength ๐ก๏ธ', 1, 10, st.session_state.game_state['gear_strength']) | |
rider_skill = st.sidebar.slider('Rider Skill ๐', 1, 10, st.session_state.game_state['rider_skill']) | |
# ๐ญ Game Loop | |
situation = generate_situation() | |
actions = generate_actions() | |
st.markdown(f"## {situation['emoji']} Current Situation: {situation['name']}") | |
st.markdown(situation['description']) | |
st.markdown("### ๐ญ Choose your action:") | |
cols = st.columns(3) | |
for i, action in enumerate(actions): | |
if cols[i].button(f"{action['emoji']} {action['name']}"): | |
outcome, success_chance = evaluate_action(action, gear_strength, rider_skill, st.session_state.game_state['history']) | |
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") | |
st.markdown(f"You decided to: **{action['name']}**") | |
st.markdown(action['description']) | |
st.markdown(f"**Outcome:** {'โ Success!' if outcome else 'โ Failure.'}") | |
st.markdown(f"**Success Chance:** {success_chance:.2f}%") | |
if outcome: | |
st.session_state.game_state['score'] += 1 | |
# ๐ Update game state | |
st.session_state.game_state = update_game_state( | |
st.session_state.game_state, | |
situation, | |
action, | |
outcome, | |
timestamp | |
) | |
# ๐ Display Markdown Preview | |
if not st.session_state.game_state['history_df'].empty: | |
st.markdown(create_markdown_preview(st.session_state.game_state['history_df'])) | |
# ๐ณ Display Journey Graph | |
if not st.session_state.game_state['history_df'].empty: | |
st.markdown("## ๐ณ Your Journey") | |
nodes, edges = create_graph_from_history(st.session_state.game_state['history_df']) | |
try: | |
streamlit_flow('cat_rider_flow', | |
nodes, | |
edges, | |
layout=TreeLayout(direction='down'), | |
fit_view=True, | |
height=600) | |
except Exception as e: | |
st.error(f"An error occurred while rendering the journey graph: {str(e)}") | |
st.markdown("Please try refreshing the page if the graph doesn't appear.") | |
# ๐ Character Stats Visualization | |
data = {"Stat": ["Gear Strength ๐ก๏ธ", "Rider Skill ๐"], | |
"Value": [gear_strength, rider_skill]} | |
df = pd.DataFrame(data) | |
fig = px.bar(df, x='Stat', y='Value', title="Cat Rider Stats ๐") | |
st.plotly_chart(fig) | |
# Example of Data Table | |
st.markdown("### ๐ ๏ธ Available Gear") | |
gear_data = { | |
'Gear': ['Helmet', 'Armor', 'Boots', 'Gloves'], | |
'Protection Level': [8, 7, 5, 4] | |
} | |
gear_df = pd.DataFrame(gear_data) | |
st.dataframe(gear_df) | |
if __name__ == "__main__": | |
main() |