File size: 5,308 Bytes
f407e31
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c9b54cd
f407e31
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
import streamlit as st
import pandas as pd
import plotly.express as px
import random
import json
from streamlit_flow import streamlit_flow
from streamlit_flow.elements import StreamlitFlowNode, StreamlitFlowEdge
from streamlit_flow.layouts import TreeLayout

def generate_situation():
    situations = [
        "The Village in Peril",
        "The Cursed Artifact",
        "The Sacred Pact",
        "The Shapeshifter's Challenge",
        "The Fox Fire Trial"
    ]
    return random.choice(situations)

def generate_actions():
    actions = [
        ("Use Fox Fire", "πŸ”₯"),
        ("Shapeshift", "🦊"),
        ("Possess an Object", "πŸ‘»"),
        ("Call Upon Ancient Spirits", "🌟"),
        ("Use Mystical Artifact", "πŸ—‘οΈ")
    ]
    return random.sample(actions, 3)

def evaluate_action(action, power_level, mystical_energy, history):
    base_success_chance = (power_level + mystical_energy) / 2
    
    # Adjust success chance based on history
    if action in history:
        success_chance = base_success_chance + (history[action] * 2)
    else:
        success_chance = base_success_chance
    
    outcome = random.randint(1, 100) <= success_chance
    return outcome, success_chance

def update_graph(nodes, edges, situation, action, outcome):
    new_node_id = f"{len(nodes)}-{situation}-{action}"
    new_node = StreamlitFlowNode(new_node_id, (0, 0), {'content': f"{situation}\n{action}\nOutcome: {'Success' if outcome else 'Failure'}"}, 'output', 'bottom', 'top')
    nodes.append(new_node)
    
    if len(nodes) > 1:
        new_edge = StreamlitFlowEdge(f"{nodes[-2].id}-{new_node.id}", nodes[-2].id, new_node.id, animated=True)
        edges.append(new_edge)
    
    return nodes, edges

def save_game_state(state):
    return json.dumps(state)

def load_game_state(state_json):
    return json.loads(state_json)

def app():
    st.markdown("# Kitsune - The Mystical Shape-Shifter Game 🦊")
    
    if 'game_state' not in st.session_state:
        st.session_state.game_state = {
            'nodes': [],
            'edges': [],
            'score': 0,
            'history': {},
            'power_level': 50,
            'mystical_energy': 75
        }
    
    # Game Stats
    st.sidebar.markdown("## Game Stats")
    st.sidebar.markdown(f"Score: {st.session_state.game_state['score']}")
    
    # Character Stats
    power_level = st.sidebar.slider('Power Level ⚑', 0, 100, st.session_state.game_state['power_level'])
    mystical_energy = st.sidebar.slider('Mystical Energy ✨', 0, 100, st.session_state.game_state['mystical_energy'])
    
    # Game Loop
    situation = generate_situation()
    actions = generate_actions()
    
    st.markdown(f"## Current Situation: {situation}")
    st.markdown("Choose your action:")
    
    cols = st.columns(3)
    for i, (action, emoji) in enumerate(actions):
        if cols[i].button(f"{emoji} {action}"):
            outcome, success_chance = evaluate_action(action, power_level, mystical_energy, st.session_state.game_state['history'])
            
            st.markdown(f"You decided to: {action}")
            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 history
            if action in st.session_state.game_state['history']:
                st.session_state.game_state['history'][action] += 1 if outcome else -1
            else:
                st.session_state.game_state['history'][action] = 1 if outcome else -1
            
            st.session_state.game_state['nodes'], st.session_state.game_state['edges'] = update_graph(
                st.session_state.game_state['nodes'], 
                st.session_state.game_state['edges'], 
                situation, 
                action, 
                outcome
            )
    
    # Display Graph
    if st.session_state.game_state['nodes']:
        streamlit_flow('kitsune_game_flow', 
                       st.session_state.game_state['nodes'], 
                       st.session_state.game_state['edges'], 
                       layout=TreeLayout(direction='TB'),
                       fit_view=True, 
                       height=600)
    
    # Character Stats Visualization
    data = {"Stat": ["Power Level", "Mystical Energy"],
            "Value": [power_level, mystical_energy]}
    df = pd.DataFrame(data)
    fig = px.bar(df, x='Stat', y='Value', title="Kitsune Stats πŸ“Š")
    st.plotly_chart(fig)
    
    # Save and Load Game State
    st.markdown("## Save/Load Game")
    if st.button("Save Game"):
        game_state_json = save_game_state(st.session_state.game_state)
        st.download_button(
            label="Download Game State",
            data=game_state_json,
            file_name="kitsune_game_state.json",
            mime="application/json"
        )
    
    uploaded_file = st.file_uploader("Load Game State", type="json")
    if uploaded_file is not None:
        game_state_json = uploaded_file.getvalue().decode("utf-8")
        st.session_state.game_state = load_game_state(game_state_json)
        st.success("Game state loaded successfully!")

if __name__ == "__main__":
    app()