Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -4,6 +4,7 @@ import plotly.express as px
|
|
4 |
import random
|
5 |
import uuid
|
6 |
import os
|
|
|
7 |
from datetime import datetime
|
8 |
from streamlit_flow import streamlit_flow
|
9 |
from streamlit_flow.elements import StreamlitFlowNode, StreamlitFlowEdge
|
@@ -94,10 +95,47 @@ def save_history_to_file(history_df, user_id):
|
|
94 |
f.write(markdown)
|
95 |
return filename
|
96 |
|
97 |
-
# Function to load saved histories
|
98 |
-
def load_saved_histories():
|
99 |
-
history_files = [f for f in os.listdir('.') if f.startswith('history_') and f.endswith('.md')]
|
100 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
101 |
|
102 |
# π§ Game Mechanics
|
103 |
def generate_situation():
|
@@ -158,7 +196,7 @@ def process_journey_history(history_df):
|
|
158 |
|
159 |
for situation_name, group in grouped:
|
160 |
situation_emoji = group.iloc[0]['situation_emoji']
|
161 |
-
situation_id = group.iloc[0]
|
162 |
situation_node_id = f"situation_{situation_id}"
|
163 |
|
164 |
markdown += f"### {situation_emoji} **{situation_name}**\n"
|
@@ -181,14 +219,14 @@ def process_journey_history(history_df):
|
|
181 |
action_name = row['action_name']
|
182 |
outcome = row['outcome']
|
183 |
outcome_str = 'β
Success' if outcome else 'β Failure'
|
184 |
-
stars = 'β' * int(row
|
185 |
-
conclusion = row
|
186 |
|
187 |
markdown += f"Attempt {attempt}: {action_emoji} **{action_name}**: {outcome_str} {stars}\n"
|
188 |
markdown += f"{conclusion}\n"
|
189 |
|
190 |
# Create attempt node
|
191 |
-
attempt_node_id = f"attempt_{situation_id}_{attempt}_{
|
192 |
if outcome:
|
193 |
attempt_content = f"Attempt {attempt}: {action_emoji} {action_name} - {outcome_str}\n{stars}"
|
194 |
else:
|
@@ -259,6 +297,9 @@ def update_game_state(game_state, situation, action, outcome, timestamp):
|
|
259 |
else:
|
260 |
game_state['history'][action['id']] = 1 if outcome else -1
|
261 |
|
|
|
|
|
|
|
262 |
return game_state
|
263 |
|
264 |
# π
Display Scoreboard with Star Emojis and Buckyball Outline
|
@@ -303,7 +344,7 @@ def main():
|
|
303 |
# π Initialize game state
|
304 |
if 'game_state' not in st.session_state:
|
305 |
st.session_state.game_state = {
|
306 |
-
'user_id':
|
307 |
'score': 0,
|
308 |
'history': {},
|
309 |
'gear_strength': 0,
|
@@ -317,38 +358,38 @@ def main():
|
|
317 |
'succeeded': False
|
318 |
}
|
319 |
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
if
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
st.sidebar.success(f"Loaded {selected_history}")
|
329 |
-
|
330 |
-
# π± Cat Rider Selection
|
331 |
-
if st.session_state.game_state['cat_rider'] is None:
|
332 |
-
st.markdown("## Choose Your Cat Rider:")
|
333 |
cols = st.columns(len(CAT_RIDERS))
|
334 |
for i, rider in enumerate(CAT_RIDERS):
|
335 |
if cols[i].button(f"{rider['emoji']} {rider['name']} ({rider['type']})", key=f"rider_{i}"):
|
336 |
-
|
337 |
-
|
338 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
339 |
|
340 |
# π Riding Gear Selection
|
341 |
-
if
|
342 |
st.markdown("## Select Your Riding Gear:")
|
343 |
cols = st.columns(len(RIDING_GEAR))
|
344 |
for i, gear in enumerate(RIDING_GEAR):
|
345 |
if cols[i].button(f"{gear['name']} ({gear['type']})", key=f"gear_{i}"):
|
346 |
-
|
347 |
-
|
348 |
|
349 |
# π Game Loop
|
350 |
-
game_state = st.session_state.game_state
|
351 |
-
|
352 |
if game_state['cat_rider'] is not None and game_state['riding_gear'] is not None:
|
353 |
# Check if current_situation is None or if the player succeeded in the previous situation
|
354 |
if game_state['current_situation'] is None or game_state['succeeded']:
|
@@ -445,23 +486,12 @@ def main():
|
|
445 |
fig = px.bar(df, x='Stat', y='Value', title="Cat Rider Stats π")
|
446 |
st.plotly_chart(fig)
|
447 |
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
# Provide download buttons for saved histories
|
456 |
-
st.sidebar.markdown("### π₯ Download Histories")
|
457 |
-
for history_file in history_files:
|
458 |
-
with open(history_file, 'r', encoding='utf-8') as f:
|
459 |
-
st.sidebar.download_button(
|
460 |
-
label=f"Download {history_file}",
|
461 |
-
data=f.read(),
|
462 |
-
file_name=history_file,
|
463 |
-
mime='text/markdown'
|
464 |
-
)
|
465 |
|
466 |
if __name__ == "__main__":
|
467 |
main()
|
|
|
4 |
import random
|
5 |
import uuid
|
6 |
import os
|
7 |
+
import re
|
8 |
from datetime import datetime
|
9 |
from streamlit_flow import streamlit_flow
|
10 |
from streamlit_flow.elements import StreamlitFlowNode, StreamlitFlowEdge
|
|
|
95 |
f.write(markdown)
|
96 |
return filename
|
97 |
|
98 |
+
# Function to load saved histories and reconstruct game state
|
99 |
+
def load_saved_histories(user_id):
|
100 |
+
history_files = [f for f in os.listdir('.') if f.startswith(f'history_{user_id}_') and f.endswith('.md')]
|
101 |
+
history_files.sort() # Ensure files are sorted by timestamp
|
102 |
+
combined_history = ''
|
103 |
+
for history_file in history_files:
|
104 |
+
with open(history_file, 'r', encoding='utf-8') as f:
|
105 |
+
combined_history += f.read() + '\n'
|
106 |
+
return combined_history
|
107 |
+
|
108 |
+
# Function to parse markdown history and reconstruct history DataFrame
|
109 |
+
def parse_history_markdown(markdown_text):
|
110 |
+
lines = markdown_text.split('\n')
|
111 |
+
data = []
|
112 |
+
current_situation = None
|
113 |
+
for line in lines:
|
114 |
+
situation_match = re.match(r"### (\S+) \*\*(.+)\*\*", line)
|
115 |
+
if situation_match:
|
116 |
+
situation_emoji = situation_match.group(1)
|
117 |
+
situation_name = situation_match.group(2)
|
118 |
+
continue
|
119 |
+
attempt_match = re.match(r"Attempt (\d+): (\S+) \*\*(.+)\*\*: (β
Success|β Failure) (\S*)", line)
|
120 |
+
if attempt_match:
|
121 |
+
attempt = int(attempt_match.group(1))
|
122 |
+
action_emoji = attempt_match.group(2)
|
123 |
+
action_name = attempt_match.group(3)
|
124 |
+
outcome_str = attempt_match.group(4)
|
125 |
+
stars = attempt_match.group(5)
|
126 |
+
outcome = True if outcome_str == 'β
Success' else False
|
127 |
+
score = len(stars)
|
128 |
+
data.append({
|
129 |
+
'situation_name': situation_name,
|
130 |
+
'situation_emoji': situation_emoji,
|
131 |
+
'attempt': attempt,
|
132 |
+
'action_name': action_name,
|
133 |
+
'action_emoji': action_emoji,
|
134 |
+
'outcome': outcome,
|
135 |
+
'score': score
|
136 |
+
})
|
137 |
+
history_df = pd.DataFrame(data)
|
138 |
+
return history_df
|
139 |
|
140 |
# π§ Game Mechanics
|
141 |
def generate_situation():
|
|
|
196 |
|
197 |
for situation_name, group in grouped:
|
198 |
situation_emoji = group.iloc[0]['situation_emoji']
|
199 |
+
situation_id = group.iloc[0].get('situation_id', uuid.uuid4())
|
200 |
situation_node_id = f"situation_{situation_id}"
|
201 |
|
202 |
markdown += f"### {situation_emoji} **{situation_name}**\n"
|
|
|
219 |
action_name = row['action_name']
|
220 |
outcome = row['outcome']
|
221 |
outcome_str = 'β
Success' if outcome else 'β Failure'
|
222 |
+
stars = 'β' * int(row.get('score', 0)) if outcome else ''
|
223 |
+
conclusion = row.get('conclusion', '')
|
224 |
|
225 |
markdown += f"Attempt {attempt}: {action_emoji} **{action_name}**: {outcome_str} {stars}\n"
|
226 |
markdown += f"{conclusion}\n"
|
227 |
|
228 |
# Create attempt node
|
229 |
+
attempt_node_id = f"attempt_{situation_id}_{attempt}_{uuid.uuid4()}"
|
230 |
if outcome:
|
231 |
attempt_content = f"Attempt {attempt}: {action_emoji} {action_name} - {outcome_str}\n{stars}"
|
232 |
else:
|
|
|
297 |
else:
|
298 |
game_state['history'][action['id']] = 1 if outcome else -1
|
299 |
|
300 |
+
# Automatically save history after each action
|
301 |
+
save_history_to_file(game_state['history_df'], game_state['user_id'])
|
302 |
+
|
303 |
return game_state
|
304 |
|
305 |
# π
Display Scoreboard with Star Emojis and Buckyball Outline
|
|
|
344 |
# π Initialize game state
|
345 |
if 'game_state' not in st.session_state:
|
346 |
st.session_state.game_state = {
|
347 |
+
'user_id': None,
|
348 |
'score': 0,
|
349 |
'history': {},
|
350 |
'gear_strength': 0,
|
|
|
358 |
'succeeded': False
|
359 |
}
|
360 |
|
361 |
+
game_state = st.session_state.game_state
|
362 |
+
|
363 |
+
# π± Cat Rider Selection or Loading Previous State
|
364 |
+
if game_state['cat_rider'] is None:
|
365 |
+
st.markdown("## Choose Your Cat Rider or Load Previous Journey:")
|
366 |
+
# Check for existing histories
|
367 |
+
existing_riders = [f.split('_')[1] for f in os.listdir('.') if f.startswith('history_')]
|
368 |
+
existing_riders = list(set(existing_riders))
|
|
|
|
|
|
|
|
|
|
|
369 |
cols = st.columns(len(CAT_RIDERS))
|
370 |
for i, rider in enumerate(CAT_RIDERS):
|
371 |
if cols[i].button(f"{rider['emoji']} {rider['name']} ({rider['type']})", key=f"rider_{i}"):
|
372 |
+
game_state['cat_rider'] = rider
|
373 |
+
game_state['rider_skill'] = rider['skill']
|
374 |
+
game_state['user_id'] = rider['name'] # Use rider name as user ID
|
375 |
+
|
376 |
+
# Load existing history if available
|
377 |
+
existing_history = load_saved_histories(game_state['user_id'])
|
378 |
+
if existing_history:
|
379 |
+
history_df = parse_history_markdown(existing_history)
|
380 |
+
game_state['history_df'] = history_df
|
381 |
+
game_state['score'] = history_df['score'].max() if not history_df.empty else 0
|
382 |
|
383 |
# π Riding Gear Selection
|
384 |
+
if game_state['riding_gear'] is None and game_state['cat_rider'] is not None:
|
385 |
st.markdown("## Select Your Riding Gear:")
|
386 |
cols = st.columns(len(RIDING_GEAR))
|
387 |
for i, gear in enumerate(RIDING_GEAR):
|
388 |
if cols[i].button(f"{gear['name']} ({gear['type']})", key=f"gear_{i}"):
|
389 |
+
game_state['riding_gear'] = gear
|
390 |
+
game_state['gear_strength'] = gear['strength']
|
391 |
|
392 |
# π Game Loop
|
|
|
|
|
393 |
if game_state['cat_rider'] is not None and game_state['riding_gear'] is not None:
|
394 |
# Check if current_situation is None or if the player succeeded in the previous situation
|
395 |
if game_state['current_situation'] is None or game_state['succeeded']:
|
|
|
486 |
fig = px.bar(df, x='Stat', y='Value', title="Cat Rider Stats π")
|
487 |
st.plotly_chart(fig)
|
488 |
|
489 |
+
# Automatically load saved history if available
|
490 |
+
if game_state['user_id'] and not game_state['history_df'].empty:
|
491 |
+
existing_history = load_saved_histories(game_state['user_id'])
|
492 |
+
if existing_history:
|
493 |
+
st.markdown("## π Loaded Journey History")
|
494 |
+
st.markdown(existing_history)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
495 |
|
496 |
if __name__ == "__main__":
|
497 |
main()
|