CatRider / CatRider4.app.py
awacke1's picture
Rename app.py to CatRider4.app.py
66beef2 verified
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
# ๐Ÿฑ Cat Rider and Gear Data
CAT_RIDERS = [
{"name": "Whiskers", "type": "Speed", "emoji": "๐Ÿพ", "strength": 3, "skill": 7},
{"name": "Fluffy", "type": "Bravery", "emoji": "๐Ÿฆ", "strength": 5, "skill": 5},
{"name": "Midnight", "type": "Stealth", "emoji": "๐ŸŒ‘", "strength": 4, "skill": 6},
{"name": "Bella", "type": "Charm", "emoji": "๐Ÿ˜บ", "strength": 2, "skill": 8}
]
RIDING_GEAR = [
{"name": "Feathered Boots", "type": "Agility", "strength": 2},
{"name": "Golden Armor", "type": "Defense", "strength": 4},
{"name": "Magic Whisker Wand", "type": "Magic", "strength": 3},
{"name": "Sleek Shadow Cape", "type": "Stealth", "strength": 1}
]
# ๐ŸŒ Game World Data - SITUATIONS and ACTIONS expanded with humorous elements
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 before the walls crumble! ๐Ÿš๏ธ",
"emoji": "๐Ÿšช",
"type": "escape"
},
{
"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. Don't let the spooky ghosts get you! ๐Ÿ‘ป",
"emoji": "๐Ÿ›๏ธ",
"type": "exploration"
},
{
"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. Be prepared to face noble feline adversaries! ๐Ÿฑ",
"emoji": "๐Ÿ‘‘",
"type": "competition"
},
{
"id": "cheese_heist",
"name": "The Great Cheese Heist",
"description": "Your cat rider must sneak into the royal pantry to steal the legendary Cheese of Destiny. But beware โ€“ the palace mice are guarding it! ๐Ÿง€",
"emoji": "๐Ÿง€",
"type": "heist"
},
{
"id": "sky_race",
"name": "The Sky Race",
"description": "Compete in the annual Sky Race where your cat rider flies across the skies on a magical broomstick! Watch out for lightning storms and mischievous crows! ๐ŸŒฉ๏ธ",
"emoji": "โ˜๏ธ",
"type": "competition"
},
{
"id": "purr_summit",
"name": "The Purr Summit",
"description": "Join a secret gathering of the most intellectual cats in the world. Engage in a battle of wits and wisdom to become the Grand Purr! ๐Ÿง ",
"emoji": "๐Ÿ“œ",
"type": "debate"
},
{
"id": "cat_nap",
"name": "The Eternal Catnap",
"description": "You've entered a sacred temple where cats nap for centuries. Can you navigate the dream world and escape before you too are lulled into eternal slumber? ๐Ÿ›๏ธ",
"emoji": "๐Ÿ’ค",
"type": "exploration"
},
{
"id": "feline_moon_mission",
"name": "The Feline Moon Mission",
"description": "Blast off into space! Your mission is to plant the flag of Catopia on the moon. But first, you must pilot your rocket through an asteroid field. ๐Ÿš€",
"emoji": "๐ŸŒ•",
"type": "exploration"
},
{
"id": "pirate_cove",
"name": "The Pirate Cove",
"description": "Sail the high seas with your trusty crew of cats and uncover the secrets of the Pirate Cove. But beware of the treacherous Sea Dogs! ๐Ÿดโ€โ˜ ๏ธ",
"emoji": "๐Ÿดโ€โ˜ ๏ธ",
"type": "exploration"
},
{
"id": "cat_casino",
"name": "The Cat Casino",
"description": "Test your luck in the glamorous Cat Casino! Bet your whiskers on the tables and try not to lose it all. Meow is the time! ๐ŸŽฒ",
"emoji": "๐ŸŽฐ",
"type": "competition"
}
]
ACTIONS = [
{
"id": "stealth",
"name": "Use Stealth",
"description": "Sneak past obstacles or enemies without being detected. You're like a ninja in the shadows! ๐Ÿพ",
"emoji": "๐Ÿคซ",
"type": "skill"
},
{
"id": "agility",
"name": "Showcase Agility",
"description": "Perform impressive acrobatic maneuvers to overcome challenges. Cats always land on their feet, right? ๐Ÿƒ",
"emoji": "๐Ÿƒ",
"type": "physical"
},
{
"id": "charm",
"name": "Charm Others",
"description": "Use your cat's natural charisma to win over allies or distract foes. Who could resist those cute eyes? ๐Ÿ˜ป",
"emoji": "๐Ÿ˜ป",
"type": "social"
},
{
"id": "resourcefulness",
"name": "Be Resourceful",
"description": "Utilize the environment or items in creative ways to solve problems. Think on your paws! ๐Ÿง ",
"emoji": "๐Ÿง ",
"type": "mental"
},
{
"id": "bravery",
"name": "Show Bravery",
"description": "Face dangers head-on with your feline courage. Not all heroes wear capes โ€“ some wear fur! ๐Ÿฆธโ€โ™€๏ธ",
"emoji": "๐Ÿฆธโ€โ™€๏ธ",
"type": "physical"
},
{
"id": "negotiation",
"name": "Negotiate",
"description": "Use diplomacy and clever negotiation to get out of a tight spot. Every cat has their price! ๐Ÿ’ผ",
"emoji": "๐Ÿ’ผ",
"type": "social"
},
{
"id": "precision",
"name": "Precision Attack",
"description": "Execute a perfectly timed attack to disable traps or defeat enemies. Purrfection in motion! ๐ŸŽฏ",
"emoji": "๐ŸŽฏ",
"type": "skill"
},
{
"id": "distraction",
"name": "Create a Distraction",
"description": "Use cunning tricks and diversions to draw attention away from your real goal. Look over there! ๐Ÿช„",
"emoji": "๐Ÿช„",
"type": "mental"
},
{
"id": "speed",
"name": "Sprint Away",
"description": "Run faster than you've ever run before to escape danger. Just like a cat fleeing a vacuum cleaner! ๐Ÿƒโ€โ™€๏ธ",
"emoji": "๐Ÿƒโ€โ™€๏ธ",
"type": "physical"
},
{
"id": "insight",
"name": "Use Insight",
"description": "Tap into ancient feline wisdom to solve puzzles and mysteries. A cat always knows! ๐Ÿ”ฎ",
"emoji": "๐Ÿ”ฎ",
"type": "mental"
}
]
# Expanded conclusions for outcomes - 10 items each for success and failure
SUCCESS_CONCLUSIONS = [
"Your swift paws led you to victory! ๐ŸŽ‰",
"You pounced at the perfect moment! ๐Ÿ†",
"The stars aligned for your cat rider! ๐ŸŒŸ",
"You navigated the challenge like a true feline champion! ๐Ÿฑ",
"Victory is sweet, just like a bowl of fresh milk! ๐Ÿฅ›",
"Your opponents are left in awe of your skills! ๐Ÿ˜บ",
"Youโ€™ve earned the title of Cat Commander! ๐Ÿ…",
"All the other cats are jealous of your agility! ๐Ÿƒโ€โ™‚๏ธ",
"Your strategy was flawless, and the victory is yours! ๐ŸŽ–๏ธ",
"Your cat rider is now a legend in the feline world! ๐Ÿ‘‘"
]
FAILURE_CONCLUSIONS = [
"You tried your best, but it just wasnโ€™t enough. ๐Ÿ˜ฟ",
"Maybe next time, kitty. Keep your tail up! ๐Ÿพ",
"That didnโ€™t go as planned. Time for a catnap to recover! ๐Ÿ’ค",
"Even the best cats have their off days. ๐Ÿ˜”",
"The challenge was too great this time. Better luck next time! ๐Ÿ€",
"You might need more than nine lives to get through this. ๐Ÿˆ",
"The enemy was too clever for your plan. ๐Ÿง ",
"You tripped over your own paws! ๐Ÿพ",
"The cat gods were not in your favor today. ๐Ÿ™€",
"Itโ€™s okay, every cat has a learning curve. ๐Ÿ“š"
]
# ๐Ÿง  Game Mechanics
def generate_situation():
return random.choice(SITUATIONS)
def generate_actions():
return random.sample(ACTIONS, min(3, len(ACTIONS)))
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
def generate_encounter_conclusion(situation, action, outcome):
if outcome:
return random.choice(SUCCESS_CONCLUSIONS)
else:
return random.choice(FAILURE_CONCLUSIONS)
# ๐ŸŒณ Journey Visualization with Heterogeneous Graph Structure
def create_heterogeneous_graph(history_df):
nodes = []
edges = []
# Define node shapes based on situation and action types
situation_shapes = {
"escape": "diamond",
"exploration": "triangle",
"competition": "star"
}
action_shapes = {
"skill": "square",
"physical": "circle",
"social": "hexagon",
"mental": "octagon"
}
for index, row in history_df.iterrows():
situation_id = f"situation-{index}"
action_id = f"action-{index}"
conclusion_id = f"conclusion-{index}"
# Create situation node
situation_content = f"{row['situation_emoji']} {row['situation_name']}\n๐Ÿ•’ {row['timestamp']}"
situation_node = StreamlitFlowNode(situation_id, (0, 0), {'content': situation_content}, 'output', 'bottom', 'top', shape=situation_shapes.get(row['situation_type'], 'ellipse'))
nodes.append(situation_node)
# Create action node
action_content = f"{row['action_emoji']} {row['action_name']}\nOutcome: {'โœ… Success' if row['outcome'] else 'โŒ Failure'}"
action_node = StreamlitFlowNode(action_id, (0, 0), {'content': action_content}, 'output', 'bottom', 'top', shape=action_shapes.get(row['action_type'], 'ellipse'))
nodes.append(action_node)
# Create conclusion node
conclusion_content = f"๐Ÿ“œ {row['conclusion']}\n๐Ÿ’ช Gear: {row['gear_strength']:.2f} | ๐Ÿ‹๏ธ Skill: {row['rider_skill']:.2f}"
conclusion_node = StreamlitFlowNode(conclusion_id, (0, 0), {'content': conclusion_content}, 'output', 'bottom', 'top', shape='parallelogram')
nodes.append(conclusion_node)
# Create edges
edges.append(StreamlitFlowEdge(f"{situation_id}-{action_id}", situation_id, action_id, animated=True, dashed=False))
edges.append(StreamlitFlowEdge(f"{action_id}-{conclusion_id}", action_id, conclusion_id, animated=True, dashed=False))
# Create edge to previous conclusion if not the first node
if index > 0:
prev_conclusion_id = f"conclusion-{index-1}"
edges.append(StreamlitFlowEdge(f"{prev_conclusion_id}-{situation_id}", prev_conclusion_id, situation_id, animated=True, dashed=True))
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 * 3)
markdown += f"{indent}๐ŸŒŸ **{row['situation_name']}** ({row['situation_type']})\n"
markdown += f"{indent} โ†ช {row['action_emoji']} {row['action_name']} ({row['action_type']}): "
markdown += "โœ… Success\n" if row['outcome'] else "โŒ Failure\n"
markdown += f"{indent} ๐Ÿ“œ {row['conclusion']}\n"
markdown += f"{indent} ๐Ÿ’ช Gear: {row['gear_strength']:.2f} | ๐Ÿ‹๏ธ Skill: {row['rider_skill']:.2f}\n\n"
return markdown
# ๐Ÿ”„ Game State Management
def update_game_state(game_state, situation, action, outcome, timestamp):
conclusion = generate_encounter_conclusion(situation, action, outcome)
game_state = update_character_stats(game_state, outcome)
new_record = pd.DataFrame({
'user_id': [game_state['user_id']],
'timestamp': [timestamp],
'situation_id': [situation['id']],
'situation_name': [situation['name']],
'situation_emoji': [situation['emoji']],
'situation_type': [situation['type']],
'action_id': [action['id']],
'action_name': [action['name']],
'action_emoji': [action['emoji']],
'action_type': [action['type']],
'outcome': [outcome],
'conclusion': [conclusion],
'gear_strength': [game_state['gear_strength']],
'rider_skill': [game_state['rider_skill']],
'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
# ๐Ÿ”„ Update character stats based on the outcome
def update_character_stats(game_state, outcome):
if outcome:
game_state['gear_strength'] = min(10, game_state['gear_strength'] + random.uniform(0.1, 0.5))
game_state['rider_skill'] = min(10, game_state['rider_skill'] + random.uniform(0.1, 0.5))
return game_state
# ๐ŸŽฎ Main Game Application
def main():
st.title("๐Ÿฑ Cat Rider ๐Ÿ‡")
# ๐Ÿ“œ Game Rules
st.markdown("""
### ๐Ÿ“œ Game Rules
| Step | Description |
|------|-------------|
| 1๏ธโƒฃ | Choose your Cat Rider |
| 2๏ธโƒฃ | Select your Riding Gear |
| 3๏ธโƒฃ | Set off on an Adventure |
| 4๏ธโƒฃ | Encounter Challenges and Make Decisions |
| 5๏ธโƒฃ | Complete the Quest and Grow Stronger |
""")
# ๐Ÿ 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': 0,
'rider_skill': 0,
'cat_rider': None,
'riding_gear': None,
'history_df': pd.DataFrame(columns=['user_id', 'timestamp', 'situation_id', 'situation_name', 'situation_emoji', 'situation_type', 'action_id', 'action_name', 'action_emoji', 'action_type', 'outcome', 'conclusion', 'gear_strength', 'rider_skill', 'score'])
}
# ๐Ÿฑ Cat Rider Selection
if st.session_state.game_state['cat_rider'] is None:
st.markdown("## Choose Your Cat Rider:")
cols = st.columns(len(CAT_RIDERS))
for i, rider in enumerate(CAT_RIDERS):
if cols[i].button(f"{rider['emoji']} {rider['name']} ({rider['type']})"):
st.session_state.game_state['cat_rider'] = rider
st.session_state.game_state['rider_skill'] = rider['skill']
# ๐Ÿ‡ Riding Gear Selection
if st.session_state.game_state['riding_gear'] is None and st.session_state.game_state['cat_rider'] is not None:
st.markdown("## Select Your Riding Gear:")
cols = st.columns(len(RIDING_GEAR))
for i, gear in enumerate(RIDING_GEAR):
if cols[i].button(f"{gear['name']} ({gear['type']})"):
st.session_state.game_state['riding_gear'] = gear
st.session_state.game_state['gear_strength'] = gear['strength']
# ๐ŸŽญ Game Loop
if st.session_state.game_state['cat_rider'] is not None and st.session_state.game_state['riding_gear'] is not None:
situation = generate_situation()
actions = generate_actions()
st.markdown(f"## {situation['emoji']} Current Situation: {situation['name']} ({situation['type']})")
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']} ({action['type']})"):
outcome, success_chance = evaluate_action(action, st.session_state.game_state['gear_strength'], st.session_state.game_state['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']}** ({action['type']})")
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 conclusion
conclusion = st.session_state.game_state['history_df'].iloc[-1]['conclusion']
st.markdown(f"**Encounter Conclusion:** {conclusion}")
# Display updated stats
st.markdown(f"**Updated Stats:**")
st.markdown(f"๐Ÿ’ช Gear Strength: {st.session_state.game_state['gear_strength']:.2f}")
st.markdown(f"๐Ÿ‹๏ธ Rider Skill: {st.session_state.game_state['rider_skill']:.2f}")
# ๐Ÿ“ 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 Heterogeneous Journey Graph
if not st.session_state.game_state['history_df'].empty:
st.markdown("## ๐ŸŒณ Your Journey (Heterogeneous Graph)")
nodes, edges = create_heterogeneous_graph(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": [st.session_state.game_state['gear_strength'], st.session_state.game_state['rider_skill']]}
df = pd.DataFrame(data)
fig = px.bar(df, x='Stat', y='Value', title="Cat Rider Stats ๐Ÿ“Š")
st.plotly_chart(fig)
if __name__ == "__main__":
main()