awacke1 commited on
Commit
6cd5904
·
verified ·
1 Parent(s): e04b366

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +74 -147
app.py CHANGED
@@ -12,11 +12,11 @@ import numpy as np
12
 
13
  GRID_WIDTH = 16
14
  GRID_HEIGHT = 9
15
- REFRESH_RATE = 5
16
  INTERACTION_RADIUS = 2
17
  POINTS_PER_INTERACTION = 1
18
 
19
- @st.cache_resource(show_spinner="Loading game resources...")
20
  def get_game_images():
21
  return {
22
  'tile': Image.new('RGB', (50, 50), color='green'),
@@ -33,7 +33,7 @@ def get_name_components():
33
  'is', 'ax', 'on', 'ir', 'ex', 'az', 'er', 'eth', 'ys', 'ix']
34
  }
35
 
36
- @st.cache_data(ttl=5)
37
  def load_all_players(timestamp):
38
  players = {}
39
  if os.path.exists('players'):
@@ -48,163 +48,87 @@ def load_all_players(timestamp):
48
  continue
49
  return {'players': players, 'last_update': time.time()}
50
 
51
- def clear_caches():
52
- st.cache_resource.clear()
53
- st.cache_data.clear()
54
-
55
- def generate_fantasy_name():
56
- name_parts = get_name_components()
57
- return random.choice(name_parts['prefixes']) + random.choice(name_parts['suffixes'])
58
-
59
- def load_game_state():
60
- if 'player_name' in st.query_params:
61
- st.session_state.player_name = st.query_params.player_name
62
- st.session_state.position = {
63
- 'x': int(st.query_params.get('x', random.randint(0, GRID_WIDTH - 1))),
64
- 'y': int(st.query_params.get('y', random.randint(0, GRID_HEIGHT - 1)))
65
- }
66
- st.session_state.character_stats = {
67
- 'STR': int(st.query_params.get('STR', 10)),
68
- 'DEX': int(st.query_params.get('DEX', 10)),
69
- 'CON': int(st.query_params.get('CON', 10)),
70
- 'INT': int(st.query_params.get('INT', 10)),
71
- 'WIS': int(st.query_params.get('WIS', 10)),
72
- 'CHA': int(st.query_params.get('CHA', 10)),
73
- 'HP': int(st.query_params.get('HP', 20)),
74
- 'MAX_HP': int(st.query_params.get('MAX_HP', 40)),
75
- 'score': int(st.query_params.get('score', 0)),
76
- 'created_at': float(st.query_params.get('created_at', time.time()))
77
- }
78
-
79
- def save_game_state():
80
- if st.session_state.player_name and st.session_state.character_stats:
81
- params = {
82
- 'player_name': st.session_state.player_name,
83
- 'x': str(st.session_state.position['x']),
84
- 'y': str(st.session_state.position['y']),
85
- **{k: str(v) for k, v in st.session_state.character_stats.items()}
86
- }
87
- st.query_params.from_dict(params)
88
-
89
- if 'initialized' not in st.session_state:
90
- st.session_state.initialized = False
91
- st.session_state.game_state = {
92
- 'players': {},
93
- 'chat_messages': [],
94
- 'last_sync': time.time()
95
- }
96
- st.session_state.player_name = None
97
- st.session_state.character_stats = None
98
- st.session_state.position = {
99
- 'x': random.randint(0, GRID_WIDTH - 1),
100
- 'y': random.randint(0, GRID_HEIGHT - 1)
101
- }
102
- st.session_state.last_move = time.time()
103
- st.session_state.nearby_players = []
104
- load_game_state()
105
-
106
- def save_player_state():
107
- if st.session_state.player_name:
108
- player_data = {
109
- 'name': st.session_state.player_name,
110
- 'position': st.session_state.position,
111
- 'stats': st.session_state.character_stats,
112
- 'last_update': time.time()
113
- }
114
- os.makedirs('players', exist_ok=True)
115
- with open(f"players/{st.session_state.player_name}.json", 'w') as f:
116
- json.dump(player_data, f)
117
- save_game_state()
118
-
119
- def calculate_distance(pos1, pos2):
120
- dx = min(abs(pos1['x'] - pos2['x']), GRID_WIDTH - abs(pos1['x'] - pos2['x']))
121
- dy = min(abs(pos1['y'] - pos2['y']), GRID_HEIGHT - abs(pos1['y'] - pos2['y']))
122
- return dx + dy
123
-
124
- def update_position(direction):
125
- if direction == "up":
126
- st.session_state.position['y'] = (st.session_state.position['y'] - 1) % GRID_HEIGHT
127
- elif direction == "down":
128
- st.session_state.position['y'] = (st.session_state.position['y'] + 1) % GRID_HEIGHT
129
- elif direction == "left":
130
- st.session_state.position['x'] = (st.session_state.position['x'] - 1) % GRID_WIDTH
131
- elif direction == "right":
132
- st.session_state.position['x'] = (st.session_state.position['x'] + 1) % GRID_WIDTH
133
- st.session_state.last_move = time.time()
134
- save_player_state()
135
-
136
- def update_nearby_players():
137
- current_time = time.time()
138
- all_players = load_all_players(current_time)['players']
139
- nearby = []
140
- score_gain = 0
141
- for player_name, player_data in all_players.items():
142
- if player_name != st.session_state.player_name:
143
- distance = calculate_distance(st.session_state.position, player_data['position'])
144
- if distance <= INTERACTION_RADIUS:
145
- nearby.append({
146
- 'name': player_name,
147
- 'distance': distance,
148
- 'score': player_data['stats']['score']
149
- })
150
- score_gain += POINTS_PER_INTERACTION
151
- if score_gain > 0:
152
- st.session_state.character_stats['score'] += score_gain
153
- save_player_state()
154
- st.session_state.nearby_players = nearby
155
-
156
- def create_game_board():
157
- current_time = time.time()
158
- all_players = load_all_players(current_time)['players']
159
- images = get_game_images()
160
- for y in range(GRID_HEIGHT):
161
- cols = st.columns(GRID_WIDTH)
162
- for x in range(GRID_WIDTH):
163
- player_here = None
164
- for player_name, player_data in all_players.items():
165
- if (player_data['position']['x'] == x and player_data['position']['y'] == y):
166
- player_here = player_name
167
- if x == st.session_state.position['x'] and y == st.session_state.position['y']:
168
- cols[x].image(images['player'], use_column_width=True)
169
- cols[x].markdown(f"**You** ({st.session_state.character_stats['score']} pts)")
170
- elif player_here:
171
- cols[x].image(images['other_player'], use_column_width=True)
172
- cols[x].markdown(f"**{player_here}** ({all_players[player_here]['stats']['score']} pts)")
173
- else:
174
- cols[x].image(images['tile'], use_column_width=True)
175
-
176
- def create_auto_refresh_timer():
177
- refresh_js = """
178
  <script>
179
- function setupRefresh() {
180
- const milliseconds = 5000;
181
- function refreshPage() {
182
- window.parent.document.querySelector('.stApp').classList.add('refreshing');
183
- setTimeout(() => window.location.reload(), 100);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
184
  }
185
- let refresh = setInterval(refreshPage, milliseconds);
 
 
 
 
 
 
186
  document.addEventListener('visibilitychange', function() {
187
- if (document.hidden) {
188
- clearInterval(refresh);
189
- } else {
190
- refresh = setInterval(refreshPage, milliseconds);
191
  }
192
  });
 
 
 
193
  }
 
194
  if (document.readyState === 'complete') {
195
- setupRefresh();
196
  } else {
197
- window.addEventListener('load', setupRefresh);
198
  }
199
  </script>
200
  """
201
- st.components.v1.html(refresh_js, height=0)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
202
 
203
  def main():
204
- create_auto_refresh_timer()
205
  update_nearby_players()
 
206
  st.sidebar.title("Player Info")
207
 
 
 
 
208
  if st.session_state.player_name is None:
209
  default_name = generate_fantasy_name()
210
  player_name = st.sidebar.text_input("Enter your name or use generated name:", value=default_name)
@@ -226,9 +150,12 @@ def main():
226
  save_player_state()
227
  st.rerun()
228
  else:
229
- st.sidebar.markdown("### Nearby Players")
230
- for player in st.session_state.nearby_players:
231
- st.sidebar.markdown(f"**{player['name']}** - {player['distance']} tiles away - {player['score']} pts")
 
 
 
232
 
233
  st.sidebar.markdown("### Movement Controls")
234
  move_cols = st.sidebar.columns(3)
 
12
 
13
  GRID_WIDTH = 16
14
  GRID_HEIGHT = 9
15
+ REFRESH_RATE = 10
16
  INTERACTION_RADIUS = 2
17
  POINTS_PER_INTERACTION = 1
18
 
19
+ @st.cache_resource
20
  def get_game_images():
21
  return {
22
  'tile': Image.new('RGB', (50, 50), color='green'),
 
33
  'is', 'ax', 'on', 'ir', 'ex', 'az', 'er', 'eth', 'ys', 'ix']
34
  }
35
 
36
+ @st.cache_data(ttl=2)
37
  def load_all_players(timestamp):
38
  players = {}
39
  if os.path.exists('players'):
 
48
  continue
49
  return {'players': players, 'last_update': time.time()}
50
 
51
+ def create_sync_mechanism():
52
+ sync_js = """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  <script>
54
+ function updateGameState() {
55
+ const timestamp = Date.now();
56
+ window.parent.document.querySelector('.stApp').classList.add('refreshing');
57
+ setTimeout(() => window.location.reload(), 100);
58
+ }
59
+
60
+ function displayCharacterSheet(playerData) {
61
+ const sidebar = window.parent.document.querySelector('[data-testid="stSidebar"]');
62
+ if (sidebar && playerData) {
63
+ const statsDiv = document.createElement('div');
64
+ statsDiv.innerHTML = `
65
+ <div style="padding: 10px; margin: 5px; border: 1px solid #ccc; border-radius: 5px;">
66
+ <h3>${playerData.name}</h3>
67
+ <p>Score: ${playerData.stats.score}</p>
68
+ <p>HP: ${playerData.stats.HP}/${playerData.stats.MAX_HP}</p>
69
+ <p>STR: ${playerData.stats.STR}</p>
70
+ <p>DEX: ${playerData.stats.DEX}</p>
71
+ <p>CON: ${playerData.stats.CON}</p>
72
+ <p>INT: ${playerData.stats.INT}</p>
73
+ <p>WIS: ${playerData.stats.WIS}</p>
74
+ <p>CHA: ${playerData.stats.CHA}</p>
75
+ </div>
76
+ `;
77
  }
78
+ }
79
+
80
+ function startSync() {
81
+ // Update game state every 10 seconds
82
+ setInterval(updateGameState, 10000);
83
+
84
+ // Handle visibility changes
85
  document.addEventListener('visibilitychange', function() {
86
+ if (!document.hidden) {
87
+ updateGameState();
 
 
88
  }
89
  });
90
+
91
+ // Handle focus changes
92
+ window.addEventListener('focus', updateGameState);
93
  }
94
+
95
  if (document.readyState === 'complete') {
96
+ startSync();
97
  } else {
98
+ window.addEventListener('load', startSync);
99
  }
100
  </script>
101
  """
102
+ st.components.v1.html(sync_js, height=0)
103
+
104
+ def show_character_sheet(player_data):
105
+ st.sidebar.markdown("### Character Sheet")
106
+ st.sidebar.markdown(f"""
107
+ **Name:** {player_data['name']}
108
+
109
+ **Stats:**
110
+ - HP: {player_data['stats']['HP']}/{player_data['stats']['MAX_HP']}
111
+ - STR: {player_data['stats']['STR']}
112
+ - DEX: {player_data['stats']['DEX']}
113
+ - CON: {player_data['stats']['CON']}
114
+ - INT: {player_data['stats']['INT']}
115
+ - WIS: {player_data['stats']['WIS']}
116
+ - CHA: {player_data['stats']['CHA']}
117
+
118
+ **Score:** {player_data['stats']['score']}
119
+ """)
120
+
121
+ [Previous functions remain the same: generate_fantasy_name, load_game_state, save_game_state, calculate_distance, update_position, etc.]
122
 
123
  def main():
124
+ create_sync_mechanism()
125
  update_nearby_players()
126
+
127
  st.sidebar.title("Player Info")
128
 
129
+ current_time = time.time()
130
+ all_players = load_all_players(current_time)['players']
131
+
132
  if st.session_state.player_name is None:
133
  default_name = generate_fantasy_name()
134
  player_name = st.sidebar.text_input("Enter your name or use generated name:", value=default_name)
 
150
  save_player_state()
151
  st.rerun()
152
  else:
153
+ show_character_sheet({'name': st.session_state.player_name, 'stats': st.session_state.character_stats})
154
+
155
+ st.sidebar.markdown("### Other Players")
156
+ for player_name, player_data in all_players.items():
157
+ if player_name != st.session_state.player_name:
158
+ show_character_sheet(player_data)
159
 
160
  st.sidebar.markdown("### Movement Controls")
161
  move_cols = st.sidebar.columns(3)